From 3f67bc3566bc9454edb7669b6320444748239151 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Sun, 21 Jul 2024 09:56:24 +0800 Subject: [PATCH 01/41] New translations shards.mdx (Korean) --- .../current/develop/blockchain/shards.mdx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/develop/blockchain/shards.mdx b/i18n/ko/docusaurus-plugin-content-docs/current/develop/blockchain/shards.mdx index c30c633d4a..96fd3c5432 100644 --- a/i18n/ko/docusaurus-plugin-content-docs/current/develop/blockchain/shards.mdx +++ b/i18n/ko/docusaurus-plugin-content-docs/current/develop/blockchain/shards.mdx @@ -1,9 +1,5 @@ # 샤드 -:::warning -페이지가 개발 중입니다. -::: - 샤딩은 [데이터베이스 설계](https://en.wikipedia.org/wiki/Shard_(database_architecture))에서 기원한 성숙한 개념입니다. 이는 하나의 논리적 데이터 세트를 여러 데이터베이스에 나누어 분산시키는 것으로, 이 데이터베이스들은 서로 독립적이며 여러 서버에 배포될 수 있습니다. 간단히 말해, 샤딩은 수평적 확장성을 가능하게 합니다 - 데이터를 독립적인 여러 조각으로 나누어 병렬로 처리할 수 있게 하는 것입니다. 이는 데이터에서 [빅 데이터](https://en.wikipedia.org/wiki/Big_data)로의 전환에서 중요한 개념입니다. 데이터 세트가 전통적인 방법으로 처리하기에는 너무 커질 때, 더 작게 분할하지 않으면 확장할 다른 방법이 없습니다. From 5d78d9b2a42d26b08b0eb60c136c78e1b2ade835 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 22 Jul 2024 14:16:27 +0800 Subject: [PATCH 02/41] New translations how-it-works.md (Korean) --- .../localization-program/how-it-works.md | 152 ++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/how-it-works.md diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/how-it-works.md b/i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/how-it-works.md new file mode 100644 index 0000000000..bfa7a87b82 --- /dev/null +++ b/i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/how-it-works.md @@ -0,0 +1,152 @@ +# 작동 방식 + +![작동 방식](/img/localizationProgramGuideline/localization-program.png) + +**ownSquare Labs 현지화 프로그램**은 몇 가지 주요 요소로 구성됩니다. 이 장에서는 프로그램의 작동 방식을 개괄적으로 설명하여, 그 작동 원리와 효과적인 사용 방법을 이해할 수 있도록 도와줍니다. + +이 시스템 내에서는 여러 애플리케이션을 통합하여 하나의 통합된 프로그램으로 원활하게 작동하도록 합니다: + +- **GitHub**: 문서를 호스팅하고, 업스트림 리포지토리에서 문서를 동기화하고, 특정 브랜치에 번역을 동기화합니다. +- **Crowdin**: 번역, 교정, 언어 기본 설정 등 번역 프로세스를 관리합니다. +- **AI 시스템**: 번역자들을 지원하기 위해 고급 AI를 활용하여 원활한 워크플로우를 보장합니다. +- **맞춤형 용어집**: 번역자들을 안내하고 AI가 프로젝트의 맥락에 맞는 정확한 번역을 생성하도록 합니다. 사용자들은 필요에 따라 자신들의 용어집을 업로드할 수도 있습니다. + +:::info +이 가이드는 전체 과정을 자세히 다루지는 않지만, TownSquare Labs 현지화 프로그램의 독특한 주요 요소들을 강조할 것입니다. 프로그램을 더 자세히 탐색해 보세요. +::: + +## 문서 및 번역을 위한 GitHub 동기화 + +우리 리포지토리는 문서와 번역 관리를 위해 여러 브랜치를 활용합니다. 각 특수 브랜치의 목적과 기능에 대한 자세한 설명은 다음과 같습니다: + +### 브랜치 개요 + +#### 1. `dev` + +`dev` 브랜치는 동기화 작업을 처리하기 위해 GitHub Actions를 실행합니다. 워크플로우 설정은 [**`.github/workflows`**](https://github.com/TownSquareXYZ/ton-docs/tree/dev/.github/workflows) 디렉터리에서 찾을 수 있습니다: + +- **`sync-fork.yml`**: 이 워크플로우는 업스트림 리포지토리로부터 문서를 동기화합니다. 매일 00:00에 실행됩니다. +- **`sync-translations.yml`**: 이 워크플로우는 업데이트된 번역을 해당 언어 브랜치로 동기화하여 해당 언어 웹사이트에서 미리 볼 수 있도록 합니다. + +#### 2. '현지화' + +이 브랜치는 `dev` 브랜치에서 실행되는 GitHub Actions를 통해 업스트림 리포지토리와 동기화를 유지합니다. 또한 원래 리포지토리에 제안하고자 하는 특정 코드를 업데이트하는 데 사용됩니다. + +#### 3. `l10n_localization` + +이 브랜치는 `localization` 브랜치의 모든 변경 사항과 Crowdin의 번역을 포함합니다. 이 브랜치의 모든 수정 사항은 업스트림 리포지토리에 커밋됩니다. + +#### 4. `[lang]_localization` + +이 브랜치들은 `ko_localization` (한국어) 및 `ja_localization` (일본어)와 같이 특정 언어 미리보기를 위해 지정됩니다. 이를 통해 우리는 웹사이트를 다양한 언어로 미리 볼 수 있습니다. + +이 브랜치들을 유지하고 GitHub Actions를 사용함으로써, 우리는 문서와 번역 업데이트의 동기화를 효율적으로 관리하여 다국어 콘텐츠가 항상 최신 상태를 유지하도록 합니다. + +## Crowdin의 새 프로젝트를 설정하는 방법 + +1. [**Crowdin 계정**](https://accounts.crowdin.com/login) 에 로그인하세요. + +2. 메뉴에서 `새 프로젝트 만들기`를 클릭하세요. + ![새 프로젝트 만들기](/img/localizationProgramGuideline/howItWorked/create-new-project.png) + +3. 프로젝트 이름과 대상 언어를 설정하세요. 언어는 나중에 설정에서 변경할 수 있습니다. + ![프로젝트 설정 만들기](/img/localizationProgramGuideline/howItWorked/create-project-setting.png) + +4. 방금 만든 프로젝트로 이동하여, 통합 탭을 선택하고 `통합 추가` 버튼을 클릭한 다음, `GitHub`를 검색하여 설치하세요. + ![GitHub 통합 설치](/img/localizationProgramGuideline/howItWorked/install-github-integration.png) + +5. Crowdin에서 GitHub 통합을 구성하기 전에, 불필요한 파일 업로드를 방지하기 위해 Crowdin에 업로드할 파일을 지정하세요: + + 1. **GitHub 리포지토리 루트**에 **crowdin.yml** 파일을 기본 설정으로 만드세요: + + ```yml + project_id: + preserve_hierarchy: 1 + files: + - source: + translation: + ``` + + 2. 올바른 구성 값을 가져옵니다: + - **project_id**: Crowdin 프로젝트에서 도구 탭으로 이동하여 API를 선택하고, **project_id**를 찾으세요. + ![API 도구 선택](/img/localizationProgramGuideline/howItWorked/select-api-tool.png) + ![project\_id](/img/localizationProgramGuideline/howItWorked/projectId.png) + - **preserve_hierarchy**: Crowdin 서버에서 GitHub 디렉토리 구조를 유지합니다. + - **source**와 **translation**: Crowdin에 업로드할 파일 경로와 번역된 파일이 출력될 경로를 지정합니다. + + 예시는 [**공식 설정 파일**](https://github.com/TownSquareXYZ/ton-docs/blob/localization/crowdin.yml)을 참고하세요.\ + 자세한 내용은 [**Crowdin 구성 파일 문서**](https://developer.crowdin.com/configuration-file/)에서 확인할 수 있습니다. + +6. Crowdin을 구성하여 GitHub 리포지토리에 연결합니다: + 1. `리포지토리 추가`를 클릭하고 `소스 및 번역 파일 모드`를 선택합니다. + ![통합 모드 선택](/img/localizationProgramGuideline/howItWorked/select-integration-mode.png) + 2. GitHub 계정을 연결하고 번역할 리포지토리를 검색하세요. + ![리포지토리 검색](/img/localizationProgramGuideline/howItWorked/search-repo.png) + 3. 왼쪽에서 브랜치를 선택하면 Crowdin이 번역을 게시할 새 브랜치가 생성됩니다. + ![브랜치 설정](/img/localizationProgramGuideline/howItWorked/setting-branch.png) + 4. GitHub 브랜치로 번역을 업데이트할 빈도를 선택하세요. 다른 설정은 기본 설정을 유지한 후 저장을 클릭하여 통합을 활성화하세요. + ![빈도 설정 후 저장](/img/localizationProgramGuideline/howItWorked/frequency-save.png) + +자세한 내용은 [**GitHub 연동 문서**](https://support.crowdin.com/github-integration/)를 참조하세요. + +7. 마지막으로, 필요할 때마다 `지금 동기화` 버튼을 클릭하여 리포지토리와 번역을 동기화할 수 있습니다. + +## 용어집 + +### 용어집이란 무엇인가요? + +때로는 AI 번역기가 번역해서는 안 되는 특정 용어를 인식하지 못할 수 있습니다. 예를 들어, 프로그래밍 언어를 나타내는 "Rust"는 번역하지 않아야 합니다. 이러한 실수를 방지하기 위해 번역 지침으로 용어집을 사용합니다. + +**용어집**은 프로젝트별 용어를 한 곳에 생성, 저장 및 관리하여 용어가 올바르고 일관되게 번역되도록 합니다. + +참고용으로 [**ton-i18n-glossary**](https://github.com/TownSquareXYZ/ton-i18n-glossary)를 확인할 수 있습니다. +![ton-i18n-glossary](/img/localizationProgramGuideline/howItWorked/ton-i18n-glossary.png) + +### 새 언어에 대한 용어집을 설정하는 방법은 무엇인가요? + +대부분의 번역 플랫폼은 용어집을 지원합니다. Crowdin에서는 용어집을 설정한 후, 각 용어가 편집기에서 밑줄이 그어진 단어로 나타납니다. 용어 위에 마우스를 올리면 번역, 품사, 정의(제공된 경우)를 볼 수 있습니다. +![github-glossary](/img/localizationProgramGuideline/howItWorked/github-glossary.png) +![crowdin-glossary](/img/localizationProgramGuideline/howItWorked/crowdin-glossary.png) + +DeepL에서는 용어집을 업로드하면 AI 번역 중 자동으로 사용됩니다. + +우리는 업데이트를 자동으로 업로드하는 [**용어집 프로그램**](https://github.com/TownSquareXYZ/ton-i18n-glossary)을 만들었습니다. + +용어집에 용어를 추가하려면: + +1. 영어 용어가 이미 용어집에 있는 경우, 해당 언어의 번역을 입력하고 업로드합니다. +2. 새 용어집을 업로드하려면, 프로젝트를 클론하고 다음을 실행합니다: + + - `npm i` + - `npm run generate -- ` + +새 용어를 추가하려면 1단계를 반복합니다. + +**간단하고 효율적이지 않나요?** + +## AI 번역 Copilot을 활용하는 방법은 무엇인가요? + +AI 번역 코파일럿은 여러 가지 이점으로 언어 장벽을 허물어줍니다: + +- **향상된 일관성**: AI 번역은 최신 정보를 기반으로 하여 가장 정확하고 최신의 번역을 제공합니다. +- **속도와 효율성**: AI 번역은 실시간으로 대량의 콘텐츠를 즉시 처리합니다. +- **강력한 확장성**: AI 시스템은 지속적으로 학습하고 개선되어 번역 품질이 시간이 지남에 따라 향상됩니다. 제공된 용어집을 통해 AI 번역은 다양한 저장소의 특정 요구에 맞춰 조정될 수 있습니다. + +Crowdin에서 AI 번역을 사용하려면(저희 프로젝트에서는 DeepL 사용): + +1. Crowdin 메뉴에서 기계 번역을 선택하고 DeepL 라인에서 편집을 클릭하세요. + ![select-deepl](/img/localizationProgramGuideline/howItWorked/select-deepl.png) +2. DeepL 지원을 활성화하고 DeepL 번역기 API 키를 입력하세요. + > [DeepL 번역기 API 키 받기 방법](https://www.deepl.com/pro-api?cta=header-pro-api) + +![config-crowdin-deepl](/img/localizationProgramGuideline/howItWorked/config-crowdin-deepl.png) + +3. 우리의 DeepL 설정은 맞춤형 용어집을 사용합니다. 용어집 업로드에 대한 자세한 내용은 [**ton-i18n-glossary**](https://github.com/TownSquareXYZ/ton-i18n-glossary)를 확인하세요. + +4. 리포지토리에서 사전 번역을 클릭하고 기계 번역을 통해 선택하세요. + ![pre-translation](/img/localizationProgramGuideline/howItWorked/pre-translation.png) + +5. DeepL을 번역 엔진으로 선택하고, 대상 언어를 선택한 다음 번역할 파일을 선택하세요. + ![pre-translate-config](/img/localizationProgramGuideline/howItWorked/pre-translate-config.png) + +끝났습니다! 이제 사전 번역이 완료될 때까지 잠시 휴식을 취하면 됩니다. From 2228d8aabf150d3a2e00e47fc9a74559913623b0 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:59:45 +0800 Subject: [PATCH 03/41] New translations overview.md (Korean) --- .../localization-program/overview.md | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md b/i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md new file mode 100644 index 0000000000..1cf9362d71 --- /dev/null +++ b/i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md @@ -0,0 +1,39 @@ +# 현지화 프로그램 + +번역 프로그램은 TON 관련 다양한 문서를 여러 언어로 번역하여 전 세계 수십억 명의 비영어권 사용자에게 웹사이트 접근성을 높이는 협업 노력입니다. + +## 시스템 설계 철학 + +![how it works](/img/localizationProgramGuideline/localization-program.png) + +현지화 프로그램은 **TON**의 가장 가까운 파트너 중 하나인 [**TownSquare Labs**](https://github.com/TownSquareXYZ)에 의해 **시작**되고 **적극적으로 유지 관리**됩니다. + +우리는 다국어 커뮤니티 협업을 위한 개방형 인프라를 구축하여 **TON을 더 나은 단계로 발전**시키는 것을 목표로 하고 있으며, 이를 위해 다음을 포함합니다: + +1. **다국어 커뮤니티에 적합** + 이 프로그램은 여러 언어를 지원하여 다양한 언어적 배경을 가진 사용자가 접근하기 쉽고 포괄적입니다. + +2. **개발, 통합 및 배포 자동화** + 자동화 도구를 활용하여 개발, 통합 및 배포 과정을 간소화하고 수작업을 줄이며 모든 현지화 작업에서 효율성과 일관성을 높입니다. + +3. **개발자, 번역가 및 검증자의 역할 분리** + 우리의 접근 방식은 개발자, 번역가 및 검증자의 책임을 분리하여 각 역할이 자신의 특정 작업에 집중할 수 있도록 합니다. 이를 통해 높은 품질의 번역과 원활한 협업이 보장되며, 업무 중복이나 충돌을 방지합니다. + +4. **커뮤니티 기여 인센티브** + 현지화 과정에 기여하는 커뮤니티 구성원에게 인센티브를 제공합니다. 이를 통해 적극적인 참여를 유도하고 프로그램을 개선하는 데 도움을 준 사람들을 보상하여 소속감과 커뮤니티 정신을 함양합니다. + +5. **고급 AI 시스템 통합** + 고급 AI 시스템은 지능형 제안 제공 및 반복 작업 자동화를 통해 번역 정확도와 효율성을 높여 적은 노력으로 높은 품질의 결과를 보장합니다. + +이 프로젝트는 특정 언어 사용자만을 위한 것이 아니라, **전 세계 개발자 생태계를 위한 서비스 제공**을 목표로 합니다. + +## 감사의 글 + +번역 프로그램의 핵심 구성원인 수천 명의 커뮤니티 멤버들에게 깊은 감사를 드립니다. 우리는 번역가들을 인정하고 그들의 경력 경로를 지원하고자 합니다. 가까운 미래에 리더보드와 번역 프로그램의 모든 기여자의 목록을 작성하여 최고의 번역가들을 인정할 것입니다. + +## 가이드 및 자료 + +번역 프로그램에 기여하거나 참여를 고려하고 있다면, 아래의 번역 가이드를 확인하세요: + +- [**번역 스타일 가이드**](/contribute/localization-program/translation-style-guide) – 번역가를 위한 지침 및 팁. +- [**Crowdin 온라인 편집기 가이드**](https://support.crowdin.com/online-editor/) – Crowdin 온라인 편집기와 일부 고급 기능 사용에 대한 심층 가이드. From 35171977b8c979283756008e8806c457e5c5c7aa Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:59:47 +0800 Subject: [PATCH 04/41] New translations how-to-contribute.md (Korean) --- .../localization-program/how-to-contribute.md | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/how-to-contribute.md diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/how-to-contribute.md b/i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/how-to-contribute.md new file mode 100644 index 0000000000..c8ae69c481 --- /dev/null +++ b/i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/how-to-contribute.md @@ -0,0 +1,124 @@ +# 기여 방법 + +**TON을 가장 성공적인 블록체인으로 만드는** 우리의 목표를 이루기 위해, TON 문서가 전 세계 사람들에게 이해될 수 있도록 하는 것이 중요합니다. 현지화가 핵심이며, 이 노력에 당신이 함께 해주신다면 **정말 기쁠 것**입니다. + +## 사전 준비 사항 + +**TownSquare Labs Localization Program**은 누구에게나 열려 있습니다! 기여를 시작하기 전에 다음 단계를 따라주세요: + +1. [**Crowdin**](https://crowdin.com) 계정에 로그인하거나 가입하세요. +2. 기여하고 싶은 언어를 선택하세요. +3. [**Crowdin 사용 방법**](/contribute/localization-program/how-to-contribute) 가이드와 [**번역 스타일 가이드**](/contribute/localization-program/translation-style-guide)를 읽고 팁과 모범 사례를 익히세요. +4. 기계 번역을 사용하여 작업을 보조하지만, 단독으로 의존하지 마세요. +5. 모든 번역 결과는 교정이 완료된 후 1시간 내에 웹사이트에서 미리 볼 수 있습니다. + +## 역할 + +시스템에서 맡을 수 있는 **역할**은 다음과 같습니다: + +- **언어 코디네이터** – 할당된 언어 내 프로젝트 기능을 관리합니다. +- **개발자** – 파일 업로드, 번역 가능한 텍스트 편집, 통합 연결 및 API 사용을 담당합니다. +- **교정자** – 문자열을 번역하고 승인합니다. +- **번역가** (내부 또는 커뮤니티) – 문자열을 번역하고 다른 사람이 추가한 번역에 투표합니다. + +우리의 현지화 프로젝트는 [Crowdin](https://crowdin.com/project/ton-docs)에서 호스팅됩니다. + +:::info +Before you start contributing, **read the guidelines below** to ensure standardization and quality, making the review process much faster. + +## 나란히 보기 모드 + +모든 작업은 Crowdin Editor의 **나란히 보기** 모드에서 수행됩니다. 이를 활성화하려면 작업할 파일을 클릭하세요. 페이지 오른쪽 상단의 **편집기 보기** 버튼을 클릭하고 더 명확한 편집기 보기를 위해 **나란히 보기** 모드를 선택하세요. +![나란히 보기 모드](/img/localizationProgramGuideline/side-by-side.png) +::: + +### 언어 코디네이터 + +- **문자열 번역 및 승인** +- **프로젝트 콘텐츠 사전 번역** +- **프로젝트 멤버 및 가입 요청 관리** + ![멤버 관리](/img/localizationProgramGuideline/manage-members.png) +- **프로젝트 보고서 생성** + ![보고서 생성](/img/localizationProgramGuideline/generate-reports.png) +- **작업 생성** + ![작업 생성](/img/localizationProgramGuideline/create-tasks.png) + +### 개발자 + +- **파일 업로드** +- **번역 가능한 텍스트 편집** +- **통합 연결** (예: GitHub 통합 추가) + ![GitHub 통합 설치](/img/localizationProgramGuideline/howItWorked/install-github-integration.png) +- **[Crowdin API](https://developer.crowdin.com/api/v2/) 사용** + +### 교정자 + +**교정자**로서, **파란색 진행 막대**가 있는 파일에서 작업하게 됩니다. +![교정 단계1](/img/localizationProgramGuideline/proofread-step1.png) +파일을 클릭하여 편집 인터페이스로 들어가세요. + +#### 기여 시작 + +1. [**나란히 보기 모드**](#side-by-side-mode)에 있는지 확인하세요. **승인되지 않음** 번역으로 필터링하여 교정이 필요한 문자열을 확인하세요. + ![교정 필터](/img/localizationProgramGuideline/proofread-filter.png) + +2. 다음 규칙을 따르세요: + - **파란색 큐브 아이콘**이 있는 문자열을 선택하세요. 각 번역을 확인하세요: + - **올바르면**, ☑️ 버튼을 클릭하세요. + - **잘못되면**, 다음 줄로 이동하세요. + +![교정 승인됨](/img/localizationProgramGuideline/proofread-approved.png) + +:::info +You can also review approved lines: + +1. **승인됨**으로 필터링하세요. + +2. 승인된 줄에 문제가 있으면, ☑️ 버튼을 클릭하여 교정이 필요하도록 되돌리세요. + ::: + +3. 다음 파일로 이동하려면 상단의 파일 이름을 클릭하고, 팝업 창에서 새 파일을 선택하여 교정을 계속하세요. + ![다음으로 이동](/img/localizationProgramGuideline/redirect-to-next.png) + +#### 작업 미리보기 + +모든 승인된 콘텐츠는 1시간 내에 미리보기 웹사이트에 배포됩니다. 최신 PR의 **미리보기** 링크는 [**우리의 레포지토리**](https://github.com/TownSquareXYZ/ton-docs/pulls)에서 확인하세요. +![미리보기 링크](/img/localizationProgramGuideline/preview-link.png) + +### 번역가 + +**번역가**로서, 당신의 목표는 번역이 원문과 가깝고 표현이 풍부하여 이해하기 쉽게 만드는 것입니다. **파란색 진행 막대**를 100%로 만드는 것이 당신의 임무입니다. + +#### 번역 시작 + +성공적인 번역 과정을 위해 다음 단계를 따르세요: + +1. 번역이 100%에 도달하지 않은 파일을 선택하세요. + ![번역가 선택](/img/localizationProgramGuideline/translator-select.png) + +2. [**나란히 보기 모드**](#side-by-side-mode)에 있는지 확인하세요. **번역되지 않음** 문자열로 필터링하세요. + ![번역가 필터](/img/localizationProgramGuideline/translator-filter.png) + +3. 작업 공간은 네 부분으로 구성됩니다: + - **왼쪽 상단:** 소스 문자열을 기반으로 번역을 입력하세요. + - **왼쪽 하단:** 번역된 파일을 미리보기 합니다. 원본 형식을 유지하세요. + - **오른쪽 하단:** Crowdin의 번역 제안. 클릭하여 사용할 수 있지만, 특히 링크의 정확성을 확인하세요. + +4. 상단의 **저장** 버튼을 클릭하여 번역을 저장하세요. + ![번역가 저장](/img/localizationProgramGuideline/translator-save.png) + +5. 다음 파일로 이동하려면 상단의 파일 이름을 클릭하고 팝업 창에서 새 파일을 선택하세요. + ![다음으로 이동](/img/localizationProgramGuideline/redirect-to-next.png) + +## 새 언어 지원 추가 방법 + +현재, Crowdin에는 원하는 모든 언어가 있습니다. 커뮤니티 매니저인 경우, 다음 단계를 따르세요: + +1. [TownSquareXYZ/ton-docs](https://github.com/TownSquareXYZ/ton-docs)에 `[lang]_localization` (예: 한국어의 경우 `ko_localization`)이라는 새 브랜치를 추가하세요. +2. 이 저장소의 Vercel 소유자에게 연락하여 메뉴에 새 언어를 추가하도록 요청하세요. +3. dev 브랜치에 PR 요청을 생성하세요. **dev로 병합하지 마세요**; 이는 미리보기 용도입니다. + +이 단계가 완료되면 PR 요청에서 언어의 미리보기를 볼 수 있습니다. +![ko 미리보기](/img/localizationProgramGuideline/ko_preview.png) + +언어가 TON 문서에 준비되면, 문제를 생성하고, 우리가 프로덕션 환경에 언어를 설정하도록 요청하세요. From a6772fabca3e6ef5de012a87d25fefbd103c8453 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:59:51 +0800 Subject: [PATCH 05/41] New translations translation-style-guide.md (Korean) --- .../translation-style-guide.md | 198 ++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/translation-style-guide.md diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/translation-style-guide.md b/i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/translation-style-guide.md new file mode 100644 index 0000000000..732b5918f8 --- /dev/null +++ b/i18n/ko/docusaurus-plugin-content-docs/current/contribute/localization-program/translation-style-guide.md @@ -0,0 +1,198 @@ +# 번역 스타일 가이드 + +이 번역 스타일 가이드는 웹사이트 로컬라이제이션을 돕기 위한 가장 중요한 지침, 지시사항, 팁을 포함하고 있습니다. + +이 문서는 일반적인 가이드이며 특정 언어에 국한되지 않습니다. + +## 메시지의 핵심 포착 + +TON 문서를 번역할 때, 문자 그대로의 번역을 피하십시오. + +번역이 메시지의 핵심을 포착하는 것이 중요합니다. 이는 특정 문구를 재구성하거나 내용의 단어 대 단어 번역 대신 설명적인 번역을 사용하는 것을 의미할 수 있습니다. + +각 언어는 서로 다른 문법 규칙, 관습 및 단어 순서를 가지고 있습니다. 번역할 때는 대상 언어의 문장 구조에 유의하고, 영어 소스를 문자 그대로 번역하는 것을 피하십시오. 이는 문장 구조와 가독성을 떨어뜨릴 수 있습니다. + +원문을 단어 대 단어로 번역하는 대신 전체 문장을 읽고 대상 언어의 관습에 맞게 조정하는 것이 좋습니다. + +## 격식 vs. 비격식 + +우리는 방문자 모두에게 항상 정중하고 적절한 격식적인 대화 방식을 사용합니다. + +격식적인 대화 방식을 사용하면 비공식적이거나 공격적으로 들리지 않으며 방문자의 나이와 성별에 관계없이 사용할 수 있습니다. + +대부분의 인도유럽어 및 아프라시아어는 남성과 여성을 구별하는 성별에 따른 2인칭 대명사를 사용합니다. 사용자에게 말할 때나 소유 대명사를 사용할 때 방문자의 성별을 가정하지 않을 수 있습니다. 격식적인 대화 방식은 일반적으로 적용 가능하며 일관성 있습니다. + +## 간단하고 명확한 어휘와 의미 + +우리의 목표는 웹사이트의 내용을 가능한 한 많은 사람들이 이해할 수 있도록 하는 것입니다. + +대부분의 경우, 짧고 간단한 단어를 사용하여 쉽게 이해할 수 있습니다. 동일한 의미를 가진 여러 가지 번역 가능한 단어가 있는 경우, 가장 짧고 의미를 명확하게 반영하는 단어를 사용하는 것이 가장 좋습니다. + +## 문자 체계 + +모든 콘텐츠는 대상 언어에 맞는 올바른 문자 체계를 사용하여 번역되어야 하며, 라틴 문자를 사용한 단어를 포함해서는 안 됩니다. + +번역할 때는 번역이 일관되고 라틴 문자를 포함하지 않도록 해야 합니다. + +**위 내용은 고유 명사는 번역하지 않는 것이 원칙인 언어에는 적용되지 않습니다.** + +## 페이지 메타데이터 번역 + +일부 페이지에는 'title', 'lang', 'description', 'sidebar' 등과 같은 메타데이터가 포함되어 있습니다. + +새 페이지를 Crowdin에 업로드할 때 번역자가 번역해서는 안 되는 내용을 숨기기 때문에 Crowdin에서 번역자가 볼 수 있는 모든 메타데이터는 번역해야 합니다. + +'source text'가 'en'인 문자열을 번역할 때 특히 주의해야 합니다. 이는 페이지가 제공되는 언어를 나타내며 [ISO 언어 코드](https://www.andiamo.co.uk/resources/iso-language-codes/)로 번역해야 합니다. 이러한 문자열은 대상 언어의 고유 문자 대신 라틴 문자를 사용하여 번역해야 합니다. + +어떤 언어 코드를 사용해야 할지 확신이 서지 않으면, Crowdin에서 번역 메모리를 확인하거나 Crowdin 온라인 편집기의 페이지 URL에서 해당 언어 코드를 찾을 수 있습니다. + +가장 많이 사용되는 언어의 언어 코드 예시: + +- 영어 - en +- 중국어 간체 - zh-CN +- 러시아어 - ru +- 한국어 - ko +- 폴란드어 - pl +- 우크라이나어 - uk + +## 외부 기사 제목 + +일부 문자열에는 외부 기사 제목이 포함되어 있습니다. 대부분의 개발자 문서 페이지에는 추가 읽기 자료를 위한 외부 기사 링크가 포함되어 있습니다. 기사 제목이 포함된 문자열은 일관된 사용자 경험을 위해 기사 언어에 관계없이 번역되어야 합니다. + +## Crowdin 경고 + +Crowdin에는 번역가가 실수를 할 때 경고하는 내장 기능이 있습니다. 태그를 포함하지 않거나, 번역해서는 안 되는 요소를 번역하거나, 여러 개의 연속적인 공백을 추가하거나, 종결 구두점을 잊는 경우 Crowdin은 저장하기 전에 자동으로 경고합니다. 이러한 경고가 표시되면 제안된 번역을 다시 확인하십시오. + +:::warning +이러한 경고를 무시하지 마십시오. 보통 무언가가 잘못되었거나 번역에서 소스 텍스트의 중요한 부분이 누락된 것을 의미합니다. +::: + +## 단축형 vs. 전체형/약어 + +웹사이트에는 dapps, NFT, DAO, DeFi 등 많은 약어가 사용됩니다. 이러한 약어는 영어로 널리 사용되며 대부분의 웹사이트 방문자가 익숙합니다. + +이러한 약어는 다른 언어로 정립된 번역이 없는 경우가 많으므로 이러한 용어와 유사한 용어에 접근하는 가장 좋은 방법은 전체 형태의 설명적인 번역을 제공하고 영어 약어를 괄호 안에 추가하는 것입니다. + +이러한 약어를 번역하지 마십시오. 대부분의 사람들이 익숙하지 않으며, 현지화된 버전은 대부분의 방문자에게 의미가 없을 것입니다. + +dapps 번역 예시: + +- Decentralized applications (dapps) → 번역된 전체형 (영어 약어 괄호 안에) + +## 정립된 번역이 없는 용어 + +일부 용어는 다른 언어로 정립된 번역이 없으며, 원래 영어 용어로 널리 알려져 있습니다. 이러한 용어는 주로 새로운 개념을 포함하며, 예를 들어 proof-of-work, proof-of-stake, Beacon Chain, staking 등이 있습니다. + +이러한 용어를 번역하면 부자연스러울 수 있지만, 영어 버전은 다른 언어에서도 일반적으로 사용되므로 번역하는 것이 좋습니다. + +번역할 때 창의적으로 설명적인 번역을 사용하거나 단순히 문자 그대로 번역해도 좋습니다. + +대부분의 용어를 영어로 남기기보다는 번역해야 하는 이유는 새로운 용어가 더 널리 퍼질 것이기 때문입니다. 더 많은 사람들이 TON 및 관련 기술을 사용하기 시작하면서, 더 많은 사람들이 쉽게 이해할 수 있는 용어를 다양한 언어로 제공해야 합니다. + +## 버튼 및 CTA + +웹사이트에는 여러 버튼이 있으며, 다른 콘텐츠와는 다르게 번역되어야 합니다. + +버튼 텍스트는 대부분의 문자열과 연결된 컨텍스트 스크린샷을 보거나 편집기에서 컨텍스트를 확인하여 식별할 수 있습니다. 여기에는 'button'이라는 구문이 포함됩니다. + +버튼 번역은 형식 불일치를 방지하기 위해 가능한 한 짧게 해야 합니다. 또한, 버튼 번역은 명령형, 즉 명령이나 요청을 제시해야 합니다. + +## 포용성을 위한 번역 + +TON 문서 방문자는 전 세계에서 다양한 배경을 가지고 있습니다. 웹사이트의 언어는 따라서 중립적이고 모두를 환영하며 배타적이지 않아야 합니다. + +중요한 측면 중 하나는 성 중립성입니다. 이는 공식적인 대화 방식을 사용하고 번역에서 성별에 특정한 단어를 피함으로써 쉽게 달성할 수 있습니다. + +또 다른 형태의 포용성은 특정 국가, 인종 또는 지역에 국한되지 않고 글로벌 관객을 대상으로 번역하는 것입니다. + +마지막으로, 언어는 모든 연령대와 청중에게 적합해야 합니다. + +## 언어별 번역 + +번역할 때는 소스를 복사하는 대신, 해당 언어에서 사용되는 문법 규칙, 관습 및 형식을 따르는 것이 중요합니다. 소스 텍스트는 영어 문법 규칙과 관습을 따르며, 이는 많은 다른 언어에 적용되지 않습니다. + +자신의 언어에 대한 규칙을 알고 이에 따라 번역해야 합니다. 도움이 필요하면 저희에게 연락 주시면 해당 언어에서 이러한 요소가 어떻게 사용되어야 하는지에 대한 리소스를 찾는 데 도움을 드리겠습니다. + +특히 주의해야 할 몇 가지 예시: + +### 구두점, 형식 + +#### 대문자 사용 + +- 다른 언어에서는 대문자 사용에 큰 차이가 있습니다. +- 영어에서는 제목 및 이름, 월 및 요일, 언어 이름, 휴일 등을 모두 대문자로 쓰는 것이 일반적입니다. 그러나 많은 다른 언어에서는 이러한 대문자 사용이 문법적으로 틀립니다. +- 일부 언어는 영어에서 대문자로 쓰지 않는 개인 대명사, 명사 및 특정 형용사를 대문자로 쓰는 규칙이 있습니다. + +#### 공백 + +- 철자 규칙은 각 언어의 공백 사용을 정의합니다. 공백은 어디에나 사용되기 때문에 이러한 규칙은 가장 두드러지며, 공백은 가장 오역된 요소 중 하나입니다. +- 영어와 다른 언어 간의 공백 사용의 일반적인 차이점: + - 단위와 통화 앞의 공백 (예: USD, EUR, kB, MB) + - 온도 기호 앞의 공백 (예: °C, ℉) + - 일부 구두점, 특히 줄임표 (…) 앞의 공백 + - 슬래시 (/) 전후의 공백 + +#### 목록 + +- 각 언어에는 다양한 목록 작성 규칙이 있으며, 이는 영어와 크게 다를 수 있습니다. +- 일부 언어에서는 각 새로운 줄의 첫 단어를 대문자로 써야 하고, 다른 언어에서는 소문자로 시작해야 합니다. 많은 언어는 각 줄의 길이에 따라 목록에서 대문자 사용에 대한 다른 규칙을 가지고 있습니다. +- 동일한 규칙이 항목의 끝 구두점에도 적용됩니다. 목록의 끝 구두점은 언어에 따라 마침표 (.), 쉼표 (,) 또는 세미콜론 (;)이 될 수 있습니다. + +#### 인용 부호 + +- 언어는 다양한 인용 부호를 사용합니다. 소스에서 영어 인용 부호를 복사하는 것은 종종 잘못된 것입니다. +- 가장 일반적인 인용 부호 유형: + - „예문“ + - ‚예문’ + - »예문« + - “예문” + - ‘예문’ + - «예문» + +#### 하이픈과 대시 + +- 영어에서는 하이픈 (-)을 사용하여 단어를 연결하거나 단어의 다른 부분을 연결하며, 대시 (–)는 범위 또는 일시 중지를 나타내는 데 사용됩니다. +- 많은 언어는 하이픈과 대시 사용에 대한 다른 규칙을 가지고 있습니다. + +### 형식 + +#### 숫자 + +- 각 언어의 숫자 작성에서 주요 차이점은 소수점 및 천 단위 구분 기호입니다. 천 단위의 경우, 이는 마침표, 쉼표 또는 공백이 될 수 있습니다. 비슷하게, 일부 언어는 소수점으로 마침표를, 다른 언어는 소수점으로 쉼표를 사용합니다. + - 큰 숫자의 예시: + - 영어 – **1,000.50** + - 스페인어 – **1.000,50** + - 프랑스어 – **1 000,50** +- 숫자 번역 시 중요한 고려 사항은 퍼센트 기호입니다. 이는 다양한 방식으로 작성될 수 있습니다: **100%**, **100 %** 또는 **%100**. +- 마지막으로, 음수는 언어에 따라 다르게 표시될 수 있습니다: -100, 100-, (100) 또는 [100]. + +#### 날짜 + +- 날짜를 번역할 때는 날짜 형식, 구분 기호, 대문자 사용 및 선행 0과 같은 여러 가지 고려 사항이 있습니다. 전체 길이 날짜와 숫자 날짜 간에도 차이가 있습니다. + - 다양한 날짜 형식 예시: + - 영국 영어 (dd/mm/yyyy) – 2022년 1월 1일 + - 미국 영어 (mm/dd/yyyy) – 2022년 1월 1일 + - 중국어 (yyyy-mm-dd) – 2022 年 1 月 1 日 + - 프랑스어 (dd/mm/yyyy) – 1er janvier 2022 + - 이탈리아어 (dd/mm/yyyy) – 1º gennaio 2022 + - 독일어 (dd/mm/yyyy) – 1. Januar 2022 + +#### 통화 + +- 통화를 번역하는 것은 형식, 관습 및 변환의 차이로 인해 어려울 수 있습니다. 일반적으로 통화는 소스와 동일하게 유지하십시오. 독자를 위해 괄호 안에 현지 통화와 변환을 추가할 수 있습니다. +- 다양한 언어에서 통화를 작성하는 주요 차이점은 기호 위치, 소수점과 소수점의 사용, 공백 및 약어 대 기호입니다. + - 기호 위치: $100 또는 100$ + - 소수점 대 소수점: 100,50$ 또는 100.50$ + - 공백: 100$ 또는 100 $ + - 약어 대 기호: 100 $ 또는 100 USD + +#### 단위 + +- 일반적으로, 단위는 소스와 동일하게 유지하십시오. 귀하의 국가가 다른 시스템을 사용하는 경우, 독자를 위해 괄호 안에 변환을 추가할 수 있습니다. +- 단위의 현지화 외에도 언어가 이러한 단위에 접근하는 방식의 차이점에 유의해야 합니다. 주요 차이점은 언어에 따라 숫자와 단위 사이의 공백입니다. 예시로는 100kB 대 100 kB 또는 50ºF 대 50 ºF가 있습니다. + +## 결론 + +번역할 때 서두르지 마십시오. 천천히 하며 즐기십시오! + +번역 프로그램에 참여해 주셔서 감사합니다. TON 커뮤니티는 글로벌하며, 여러분이 그 일원이 되어 기쁩니다! From 98d8281816041490d7e4e13f9c88c4c5feff1a91 Mon Sep 17 00:00:00 2001 From: sansx Date: Wed, 31 Jul 2024 01:54:27 +0800 Subject: [PATCH 06/41] add translations --- .../localization-program/overview.md | 39 + .../develop/dapps/asset-processing/README.md | 587 ++++++++ .../develop/dapps/asset-processing/jettons.md | 1205 +++++++++++++++++ .../dapps/asset-processing/overview.md | 62 + .../develop/dapps/ton-connect/overview.mdx | 113 ++ .../current/develop/fift/overview.mdx | 57 + .../current/develop/func/overview.mdx | 157 +++ .../current/develop/overview.mdx | 207 +++ .../smart-contracts/testing/overview.mdx | 141 ++ .../current/learn/academy/academy-overview.md | 16 + .../current/learn/introduction.mdx | 81 ++ .../current/learn/networking/overview.md | 19 + .../current/learn/overviews/addresses.md | 220 +++ .../current/learn/overviews/cells.md | 52 + .../current/learn/overviews/ton-blockchain.md | 72 + .../learn/tvm-instructions/tvm-overview.mdx | 133 ++ .../current/participate/README.md | 38 + .../participate/crosschain/overview.md | 57 + .../current/participate/web3/overview.mdx | 17 + .../current/contribute/README.md | 50 + .../localization-program/overview.md | 39 + .../develop/dapps/asset-processing/README.md | 587 ++++++++ .../develop/dapps/asset-processing/jettons.md | 1205 +++++++++++++++++ .../dapps/asset-processing/overview.md | 62 + .../develop/dapps/ton-connect/overview.mdx | 113 ++ .../current/develop/fift/overview.mdx | 57 + .../current/develop/overview.mdx | 207 +++ .../smart-contracts/testing/overview.mdx | 141 ++ .../current/learn/academy/academy-overview.md | 16 + .../current/learn/introduction.mdx | 81 ++ .../current/learn/networking/overview.md | 19 + .../current/learn/overviews/addresses.md | 220 +++ .../current/learn/overviews/cells.md | 52 + .../current/learn/overviews/ton-blockchain.md | 72 + .../learn/tvm-instructions/tvm-overview.mdx | 133 ++ .../current/participate/README.md | 38 + .../participate/crosschain/overview.md | 57 + .../current/participate/web3/overview.mdx | 17 + .../localization-program/overview.md | 39 + .../develop/dapps/asset-processing/README.md | 587 ++++++++ .../develop/dapps/asset-processing/jettons.md | 1205 +++++++++++++++++ .../dapps/asset-processing/overview.md | 62 + .../develop/dapps/ton-connect/overview.mdx | 113 ++ .../current/develop/fift/overview.mdx | 57 + .../current/develop/func/overview.mdx | 157 +++ .../current/develop/overview.mdx | 207 +++ .../smart-contracts/testing/overview.mdx | 141 ++ .../current/learn/academy/academy-overview.md | 16 + .../current/learn/introduction.mdx | 81 ++ .../current/learn/networking/overview.md | 19 + .../current/learn/overviews/addresses.md | 220 +++ .../current/learn/overviews/cells.md | 52 + .../current/learn/overviews/ton-blockchain.md | 72 + .../learn/tvm-instructions/tvm-overview.mdx | 133 ++ .../current/participate/README.md | 38 + .../participate/crosschain/overview.md | 57 + .../current/participate/web3/overview.mdx | 17 + 57 files changed, 9712 insertions(+) create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/README.md create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/develop/fift/overview.mdx create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/develop/func/overview.mdx create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/develop/overview.mdx create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/develop/smart-contracts/testing/overview.mdx create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/learn/academy/academy-overview.md create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/learn/introduction.mdx create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/learn/networking/overview.md create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/learn/overviews/addresses.md create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/learn/overviews/cells.md create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/learn/overviews/ton-blockchain.md create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/learn/tvm-instructions/tvm-overview.mdx create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/participate/README.md create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/participate/crosschain/overview.md create mode 100644 i18n/pl/docusaurus-plugin-content-docs/current/participate/web3/overview.mdx create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/contribute/README.md create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/README.md create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/develop/fift/overview.mdx create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/develop/overview.mdx create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/develop/smart-contracts/testing/overview.mdx create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/learn/academy/academy-overview.md create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/learn/introduction.mdx create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/learn/networking/overview.md create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/learn/overviews/addresses.md create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/learn/overviews/cells.md create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/learn/overviews/ton-blockchain.md create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/learn/tvm-instructions/tvm-overview.mdx create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/participate/README.md create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/participate/crosschain/overview.md create mode 100644 i18n/ru/docusaurus-plugin-content-docs/current/participate/web3/overview.mdx create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/README.md create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/develop/fift/overview.mdx create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/develop/func/overview.mdx create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/develop/overview.mdx create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/develop/smart-contracts/testing/overview.mdx create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/learn/academy/academy-overview.md create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/learn/introduction.mdx create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/learn/networking/overview.md create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/learn/overviews/addresses.md create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/learn/overviews/cells.md create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/learn/overviews/ton-blockchain.md create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/learn/tvm-instructions/tvm-overview.mdx create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/participate/README.md create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/participate/crosschain/overview.md create mode 100644 i18n/uk/docusaurus-plugin-content-docs/current/participate/web3/overview.mdx diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md b/i18n/pl/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md new file mode 100644 index 0000000000..d6d5f64219 --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md @@ -0,0 +1,39 @@ +# Program lokalizacji + +Program tłumaczeń to wspólny wysiłek mający na celu przetłumaczenie różnych dokumentów związanych z TON na wiele języków, dzięki czemu strona jest bardziej dostępna dla miliardów osób nie mówiących po angielsku na całym świecie. + +## Filozofia projektowania systemu + +![jak to działa](/img/localizationProgramGuideline/localization-program.png) + +Program lokalizacji jest **uruchamiany** i **aktywnie utrzymywany** przez [**TownSquare Labs**](https://github.com/TownSquareXYZ), jednego z najbliższych partnerów **TON**. + +Jesteśmy zaangażowani w tworzenie otwartej infrastruktury dla wielojęzycznej współpracy społeczności, aby **awansować TON do lepszej fazy**, która obejmuje: + +1. **Odpowiedni dla wielojęzycznych społeczności**\ + Program obsługuje wiele języków, zapewniając integrację i łatwy dostęp dla użytkowników z różnych środowisk językowych. + +2. **Automatyzacja rozwoju, integracji i wdrażania**\ + Wykorzystując narzędzia do automatyzacji, program usprawnia procesy rozwoju, integracji i wdrażania, zmniejszając wysiłki manualne oraz zwiększając wydajność i spójność wszystkich działań lokalizacyjnych. + +3. **Rozdzielenie ról programisty, tłumacza i weryfikatora**\ + Nasze podejście rozdziela obowiązki programistów, tłumaczy i weryfikatorów, pozwalając każdej roli skupić się na swoich konkretnych zadaniach. Zapewnia to wysoką jakość tłumaczeń i płynną współpracę bez nakładania się lub konfliktu obowiązków. + +4. **Zachęta dla społeczności**\ + Zapewniamy zachęty dla członków społeczności, którzy przyczyniają się do procesu lokalizacji. Zachęca to do aktywnego uczestnictwa i nagradza tych, którzy pomagają ulepszać program, wspierając poczucie własności i ducha społeczności. + +5. **Integracja zaawansowanych systemów AI**\ + Zaawansowane systemy AI zwiększają dokładność i wydajność tłumaczenia poprzez dostarczanie inteligentnych sugestii i automatyzację powtarzalnych zadań, zapewniając wysokiej jakości wyniki przy mniejszym wysiłku. + +Ten projekt nie jest przeznaczony tylko dla osób posługujących się jednym językiem; naszym celem jest **służyć globalnemu ekosystemowi programistów**. + +## Podziękowania + +Jesteśmy bardzo wdzięczni tysiącom członków społeczności, którzy są kluczową częścią Programu Tłumaczeń. Chcemy docenić naszych tłumaczy i wspierać ich na ścieżce kariery. W niedalekiej przyszłości wyróżnimy naszych najlepszych tłumaczy, tworząc rankingi i listę wszystkich osób, które przyczyniły się do rozwoju Programu Tłumaczeń. + +## Przewodniki i zasoby + +Jeśli uczestniczą Państwo w Programie Tłumaczeń lub rozważają zaangażowanie się w niego, prosimy zapoznać się z poniższymi przewodnikami po tłumaczeniach: + +- [**Translation Style Guide**](/contribute/localization-program/translation-style-guide) - Instrukcje i wskazówki dla tłumaczy. +- [**Crowdin Online Editor Guide**](https://support.crowdin.com/online-editor/) - Szczegółowy przewodnik po korzystaniu z edytora Crowdin online i niektórych zaawansowanych funkcji Crowdin. diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/README.md b/i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/README.md new file mode 100644 index 0000000000..a8e832ce87 --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/README.md @@ -0,0 +1,587 @@ +import Button from '@site/src/components/button' +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Przetwarzanie płatności + +Ta strona **wyjaśnia, jak przetwarzać** (wysyłać i akceptować) "aktywa cyfrowe" na blockchainie TON. +Opisuje **głównie** jak pracować z `monetami TON`, ale **część teoretyczna** jest **ważna**, nawet jeśli chcą Państwo przetwarzać tylko `jettony`. + +## Inteligentny kontrakt portfela + +Inteligentne kontrakty Wallet to kontrakty w sieci TON, których zadaniem jest umożliwienie podmiotom spoza łańcucha bloków interakcji z podmiotami łańcucha bloków. Ogólnie rzecz biorąc, rozwiązują one trzy wyzwania: + +- uwierzytelnia właściciela: Odmawia przetwarzania i uiszczania opłat za wnioski osób niebędących właścicielami. +- Ochrona przed powtórzeniami: Zabrania powtarzalnego wykonywania jednego żądania, na przykład wysyłania aktywów do innego inteligentnego kontraktu. +- inicjuje dowolną interakcję z innymi inteligentnymi kontraktami. + +Standardowym rozwiązaniem dla pierwszego wyzwania jest kryptografia klucza publicznego: `wallet` przechowuje klucz publiczny i sprawdza, czy przychodząca wiadomość z żądaniem jest podpisana odpowiednim kluczem prywatnym, który jest znany tylko właścicielowi. + +Rozwiązanie trzeciego wyzwania jest również powszechne; ogólnie rzecz biorąc, żądanie zawiera w pełni uformowaną wewnętrzną wiadomość, którą `wallet` wysyła do sieci. Jednak w przypadku ochrony przed powtórkami istnieje kilka różnych podejść. + +### Portfele oparte na sekwencji + +Portfele oparte na Seqno stosują najprostsze podejście do sekwencjonowania wiadomości. Każda wiadomość ma specjalną liczbę całkowitą `seqno`, która musi pokrywać się z licznikiem przechowywanym w inteligentnym kontrakcie `wallet`. `wallet` aktualizuje swój licznik przy każdym żądaniu, zapewniając w ten sposób, że jedno żądanie nie zostanie przetworzone dwukrotnie. Istnieje kilka wersji `wallet`, które różnią się publicznie dostępnymi metodami: możliwość ograniczenia żądań według czasu wygaśnięcia oraz możliwość posiadania wielu portfeli z tym samym kluczem publicznym. Jednak nieodłącznym wymogiem tego podejścia jest wysyłanie żądań jedno po drugim, ponieważ każda luka w sekwencji `seqno` spowoduje niemożność przetworzenia wszystkich kolejnych żądań. + +### Portfele o dużym obciążeniu + +Ten typ `wallet` stosuje podejście oparte na przechowywaniu identyfikatora niewygasłych przetworzonych żądań w pamięci smart-contract. W tym podejściu każde żądanie jest sprawdzane pod kątem bycia duplikatem już przetworzonego żądania i, jeśli zostanie wykryta powtórka, jest odrzucane. Ze względu na wygaśnięcie, kontrakt może nie przechowywać wszystkich żądań na zawsze, ale usunie te, które nie mogą zostać przetworzone ze względu na limit wygaśnięcia. Żądania do tego "portfela" mogą być wysyłane równolegle bez zakłócania siebie nawzajem; jednak takie podejście wymaga bardziej zaawansowanego monitorowania przetwarzania żądań. + +### Wdrożenie portfela + +Aby wdrożyć portfel za pośrednictwem TonLib, należy: + +1. Proszę wygenerować parę kluczy prywatny/publiczny za pomocą funkcji [createNewKey](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L244) lub jej funkcji opakowujących (przykład w [tonlib-go](https://github.com/mercuryoio/tonlib-go/tree/master/v2#create-new-private-key)). Proszę zauważyć, że klucz prywatny jest generowany lokalnie i nie opuszcza komputera hosta. +2. Formularz [InitialAccountWallet](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L62) struktury odpowiadającej jednemu z włączonych `wallets`. Obecnie dostępne są `wallet.v3`, `wallet.v4`, `wallet.highload.v1`, `wallet.highload.v2`. +3. Proszę obliczyć adres nowego inteligentnego kontraktu `wallet` za pomocą metody [getAccountAddress](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L283). Zalecamy użycie domyślnej wersji `0`, a także wdrożenie portfeli w łańcuchu bazowym `workchain=0` w celu obniżenia opłat za przetwarzanie i przechowywanie. +4. Proszę wysłać Toncoin na obliczony adres. Proszę zauważyć, że należy wysłać je w trybie `non-bounce`, ponieważ ten adres nie ma jeszcze kodu, a zatem nie może przetwarzać przychodzących wiadomości. Flaga `non-bounce` wskazuje, że nawet jeśli przetwarzanie nie powiedzie się, pieniądze nie powinny zostać zwrócone z wiadomością bounce. Nie zalecamy używania flagi `non-bounce` w innych transakcjach, szczególnie w przypadku dużych kwot, ponieważ mechanizm bounce zapewnia pewien stopień ochrony przed błędami. +5. Proszę utworzyć żądaną [akcję](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L154), na przykład `actionNoop` tylko do wdrożenia. Następnie proszę użyć [createQuery](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L292) i [sendQuery](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L300), aby zainicjować interakcję z blockchainem. +6. Proszę sprawdzić umowę w ciągu kilku sekund za pomocą metody [getAccountState](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L288). + +:::tip +Proszę przeczytać więcej w [Wallet Tutorial] (/develop/smart-contracts/tutorials/wallet#-deploying-a-wallet). +::: + +### Proszę sprawdzić ważność adresu portfela + +Większość zestawów SDK wymusza weryfikację adresu (większość weryfikuje go podczas tworzenia portfela lub procesu przygotowywania transakcji), więc zazwyczaj nie wymaga to od użytkownika żadnych dodatkowych skomplikowanych kroków. + + + + + +```js + const TonWeb = require("tonweb") + TonWeb.utils.Address.isValid('...') +``` + + + + +```python +package main + +import ( + "fmt" + "github.com/xssnick/tonutils-go/address" +) + +if _, err := address.ParseAddr("EQCD39VS5j...HUn4bpAOg8xqB2N"); err != nil { + return errors.New("invalid address") +} +``` + + + + +```javascript +try { + Address.of("..."); + } catch (e) { + // not valid address +} +``` + + + + +```javascript + try { + AddrStd("...") + } catch(e: IllegalArgumentException) { + // not valid address + } +``` + + + + +:::tip +Pełny opis adresu na stronie [Smart Contract Addresses](/learn/overviews/addresses). +::: + +## Praca z transferami + +### Proszę sprawdzić transakcje kontraktu + +Transakcje kontraktu można uzyskać za pomocą [getTransactions](https://toncenter.com/api/v2/#/accounts/get_transactions_getTransactions_get). Metoda ta pozwala uzyskać 10 transakcji od pewnego `last_transaction_id` i wcześniejszych. Aby przetworzyć wszystkie przychodzące transakcje, należy wykonać następujące kroki: + +1. Najnowszy `last_transaction_id` można uzyskać za pomocą [getAddressInformation](https://toncenter.com/api/v2/#/accounts/get_address_information_getAddressInformation_get). +2. Lista 10 transakcji powinna zostać załadowana za pomocą metody `getTransactions`. +3. Przetwarzanie transakcji z niepustym źródłem w wiadomości przychodzącej i miejscem docelowym równym adresowi konta. +4. Należy wczytać kolejne 10 transakcji i powtarzać kroki 2,3,4,5 aż do przetworzenia wszystkich przychodzących transakcji. + +### Proszę pobrać transakcje przychodzące/wychodzące + +Możliwe jest śledzenie przepływu wiadomości podczas przetwarzania transakcji. Ponieważ przepływ wiadomości jest DAG, wystarczy pobrać bieżącą transakcję za pomocą metody [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get) i znaleźć transakcję przychodzącą przez `out_msg` za pomocą [tryLocateResultTx](https://testnet.toncenter.com/api/v2/#/transactions/get_try_locate_result_tx_tryLocateResultTx_get) lub transakcje wychodzące przez `in_msg` za pomocą [tryLocateSourceTx](https://testnet.toncenter.com/api/v2/#/transactions/get_try_locate_source_tx_tryLocateSourceTx_get). + + + + +```ts +import { TonClient, Transaction } from '@ton/ton'; +import { getHttpEndpoint } from '@orbs-network/ton-access'; +import { CommonMessageInfoInternal } from '@ton/core'; + +async function findIncomingTransaction(client: TonClient, transaction: Transaction): Promise { + const inMessage = transaction.inMessage?.info; + if (inMessage?.type !== 'internal') return null; + return client.tryLocateSourceTx(inMessage.src, inMessage.dest, inMessage.createdLt.toString()); +} + +async function findOutgoingTransactions(client: TonClient, transaction: Transaction): Promise { + const outMessagesInfos = transaction.outMessages.values() + .map(message => message.info) + .filter((info): info is CommonMessageInfoInternal => info.type === 'internal'); + + return Promise.all( + outMessagesInfos.map((info) => client.tryLocateResultTx(info.src, info.dest, info.createdLt.toString())), + ); +} + +async function traverseIncomingTransactions(client: TonClient, transaction: Transaction): Promise { + const inTx = await findIncomingTransaction(client, transaction); + // now you can traverse this transaction graph backwards + if (!inTx) return; + await traverseIncomingTransactions(client, inTx); +} + +async function traverseOutgoingTransactions(client: TonClient, transaction: Transaction): Promise { + const outTxs = await findOutgoingTransactions(client, transaction); + // do smth with out txs + for (const out of outTxs) { + await traverseOutgoingTransactions(client, out); + } +} + +async function main() { + const endpoint = await getHttpEndpoint({ network: 'testnet' }); + const client = new TonClient({ + endpoint, + apiKey: '[API-KEY]', + }); + + const transaction: Transaction = ...; // Obtain first transaction to start traversing + await traverseIncomingTransactions(client, transaction); + await traverseOutgoingTransactions(client, transaction); +} + +main(); +``` + + + + +### Proszę wysyłać płatności + +1. Usługa powinna wdrożyć "portfel" i utrzymywać go w stanie finansowania, aby zapobiec zniszczeniu kontraktu z powodu opłat za przechowywanie. Proszę zauważyć, że opłaty za przechowywanie są zazwyczaj niższe niż 1 Toncoin rocznie. +2. Usługa powinna otrzymać od użytkownika `destination_address` i opcjonalnie `comment`. Proszę zauważyć, że w międzyczasie zalecamy zakazanie niedokończonych płatności wychodzących z tym samym zestawem (`destination_address`, `value`, `comment`) lub odpowiednie zaplanowanie tych płatności; w ten sposób następna płatność zostanie zainicjowana dopiero po potwierdzeniu poprzedniej. +3. Formularz [msg.dataText](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L103) z `komentarzem` jako tekstem. +4. Formularz [msg.message](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L113), który zawiera `destination_address`, pusty `public_key`, `amount` i `msg.dataText`. +5. Formularz [Action](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L154) zawierający zestaw wiadomości wychodzących. +6. Do wysyłania płatności wychodzących proszę używać zapytań [createQuery](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L292) i [sendQuery](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L300). +7. Usługa powinna regularnie sprawdzać metodę [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get) dla kontraktu `wallet`. Dopasowanie potwierdzonych transakcji do wychodzących płatności według (`destination_address`, `value`, `comment`) pozwala oznaczyć płatności jako zakończone; wykryć i pokazać użytkownikowi odpowiedni hash transakcji i lt (czas logiczny). +8. Żądania do `v3` portfeli `high-load` mają domyślnie czas wygaśnięcia równy 60 sekund. Po tym czasie nieprzetworzone żądania mogą być bezpiecznie ponownie wysłane do sieci (proszę zobaczyć kroki 3-6). + +### Proszę pobrać identyfikator transakcji + +Może być niejasne, że aby uzyskać więcej informacji na temat transakcji, użytkownik musi przeskanować blockchain za pomocą funkcji [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get). +Niemożliwe jest pobranie identyfikatora transakcji natychmiast po wysłaniu wiadomości, ponieważ transakcja musi najpierw zostać potwierdzona przez sieć blockchain. +Aby zrozumieć wymagany potok, proszę uważnie przeczytać [Wyślij płatności] (https://docs.ton.org/develop/dapps/asset-processing/#send-payments), zwłaszcza punkt 7. + +## Podejście oparte na fakturach + +Aby akceptować płatności na podstawie załączonych komentarzy, usługa powinna + +1. Proszę wdrożyć kontrakt `wallet`. +2. Proszę wygenerować unikalną `fakturę` dla każdego użytkownika. Wystarczy ciąg znaków reprezentujący uuid32. +3. Użytkownicy powinni zostać poinstruowani, aby wysłać Toncoin do umowy "portfela" usługi z załączoną "fakturą" jako komentarzem. +4. Usługa powinna regularnie sprawdzać metodę [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get) dla kontraktu `wallet`. +5. W przypadku nowych transakcji, przychodząca wiadomość powinna zostać wyodrębniona, `komentarz` dopasowany do bazy danych, a **wartość przychodzącej wiadomości** zdeponowana na koncie użytkownika. + +Aby obliczyć **wartość przychodzącej wiadomości**, którą wiadomość wnosi do umowy, należy przeanalizować transakcję. Dzieje się tak, gdy wiadomość trafia do kontraktu. Transakcję można uzyskać za pomocą [getTransactions](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L268). W przypadku przychodzącej transakcji portfela prawidłowe dane składają się z jednej wiadomości przychodzącej i zero wiadomości wychodzących. W przeciwnym razie albo wiadomość zewnętrzna zostanie wysłana do portfela, w którym to przypadku właściciel wyda Toncoin, albo portfel nie zostanie wdrożony, a transakcja przychodząca zostanie odrzucona. + +W każdym razie, ogólnie rzecz biorąc, kwota, którą wiadomość wnosi do kontraktu może być obliczona jako wartość wiadomości przychodzącej minus suma wartości wiadomości wychodzących minus opłata: `value_{in_msg} - SUM(value_{out_msg}) - fee`. Technicznie, reprezentacja transakcji zawiera trzy różne pola z `fee` w nazwie: `fee`, `storage_fee` i `other_fee`, czyli całkowitą opłatę, część opłaty związaną z kosztami przechowywania i część opłaty związaną z przetwarzaniem transakcji. Tylko pierwsza z nich powinna być używana. + +### Faktury z TON Connect + +Najlepiej nadaje się do aplikacji dApps, które muszą podpisywać wiele płatności/transakcji w ramach sesji lub muszą utrzymywać połączenie z portfelem przez pewien czas. + +- ✅ Istnieje stały kanał komunikacji z portfelem, informacje o adresie użytkownika + +- Użytkownicy muszą zeskanować kod QR tylko raz. + +- ✅ Możliwe jest sprawdzenie, czy użytkownik potwierdził transakcję w portfelu, śledzenie transakcji przez zwrócony BOC + +- Gotowe zestawy SDK i UI są dostępne dla różnych platform. + +- Jeśli wystarczy wysłać tylko jedną płatność, użytkownik musi wykonać dwie czynności: połączyć portfel i potwierdzić transakcję. + +- Integracja jest bardziej złożona niż link ton:// + +```mdx-code-block + +``` + +### Faktury z linkiem ton:// + +:::warning +Ton link jest przestarzały, proszę go nie używać +::: + +Jeśli potrzebują Państwo łatwej integracji dla prostego przepływu użytkowników, odpowiednie jest użycie łącza ton://. +Najlepiej nadaje się do jednorazowych płatności i faktur. + +```bash +ton://transfer/? + [nft=&] + [fee-amount=&] + [forward-amount=] +``` + +- Łatwa integracja + +- Nie ma potrzeby podłączania portfela + +- Użytkownicy muszą zeskanować nowy kod QR dla każdej płatności. + +- Nie jest możliwe śledzenie, czy użytkownik podpisał transakcję, czy nie. + +- Brak informacji o adresie użytkownika + +- Obejścia są potrzebne na platformach, na których takie linki nie są klikalne (np. wiadomości od botów dla klientów Telegram na komputery stacjonarne). + +[Więcej informacji na temat ton linków tutaj](https://github.com/tonkeeper/wallet-api#payment-urls) + +## Odkrywcy + +Eksplorator blockchain to https://tonscan.org. + +Aby wygenerować link do transakcji w eksploratorze, usługa musi uzyskać lt (czas logiczny), hash transakcji i adres konta (adres konta, dla którego lt i txhash zostały pobrane za pomocą metody [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get)). https://tonscan.org i https://explorer.toncoin.org/ mogą następnie wyświetlać stronę dla tego tx w następującym formacie: + +`https://tonviewer.com/transaction/{txhash as base64url}` + +`https://tonscan.org/tx/{lt as int}:{txhash as base64url}:{account address}` + +`https://explorer.toncoin.org/transaction?account={account address}<={lt as int}&hash={txhash as base64url}` + +## Najlepsze praktyki + +### Tworzenie portfela + + + + +- **toncenter:** + - [Utworzenie portfela + pobranie adresu portfela](https://github.com/toncenter/examples/blob/main/common.js) + +- **ton-community/ton:** + - [Utworzenie portfela + uzyskanie salda](https://github.com/ton-community/ton#usage) + + + + + +- **xssnick/tonutils-go:**. + - [Utworzenie portfela + uzyskanie salda](https://github.com/xssnick/tonutils-go?tab=readme-ov-file#wallet) + + + + + +- **psylopunk/pythonlib:** + - [Utworzenie portfela + pobranie adresu portfela](https://github.com/psylopunk/pytonlib/blob/main/examples/generate_wallet.py) +- **yungwine/pytoniq:** + +```py +import asyncio + +from pytoniq.contract.wallets.wallet import WalletV4R2 +from pytoniq.liteclient.balancer import LiteBalancer + + +async def main(): + provider = LiteBalancer.from_mainnet_config(2) + await provider.start_up() + + mnemonics, wallet = await WalletV4R2.create(provider) + print(f"{wallet.address=} and {mnemonics=}") + + await provider.close_all() + + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + + +### Depozyty toncoinów (Zdobądź toncoiny) + + + + +- **toncenter:** + - [Przetwórz depozyt Toncoins](https://github.com/toncenter/examples/blob/main/deposits.js) + - [Przetwarzaj wpłaty Toncoins w wielu portfelach] (https://github.com/toncenter/examples/blob/main/deposits-multi-wallets.js) + + + + + +- **xssnick/tonutils-go:**. + +
+Depozyty czekowe + +```go +package main + +import ( + "context" + "encoding/base64" + "log" + + "github.com/xssnick/tonutils-go/address" + "github.com/xssnick/tonutils-go/liteclient" + "github.com/xssnick/tonutils-go/ton" +) + +const ( + num = 10 +) + +func main() { + client := liteclient.NewConnectionPool() + err := client.AddConnectionsFromConfigUrl(context.Background(), "https://ton.org/global.config.json") + if err != nil { + panic(err) + } + + api := ton.NewAPIClient(client, ton.ProofCheckPolicyFast).WithRetry() + + accountAddr := address.MustParseAddr("0QA__NJI1SLHyIaG7lQ6OFpAe9kp85fwPr66YwZwFc0p5wIu") + + // we need fresh block info to run get methods + b, err := api.CurrentMasterchainInfo(context.Background()) + if err != nil { + log.Fatal(err) + } + + // we use WaitForBlock to make sure block is ready, + // it is optional but escapes us from liteserver block not ready errors + res, err := api.WaitForBlock(b.SeqNo).GetAccount(context.Background(), b, accountAddr) + if err != nil { + log.Fatal(err) + } + + lastTransactionId := res.LastTxHash + lastTransactionLT := res.LastTxLT + + headSeen := false + + for { + trxs, err := api.ListTransactions(context.Background(), accountAddr, num, lastTransactionLT, lastTransactionId) + if err != nil { + log.Fatal(err) + } + + for i, tx := range trxs { + // should include only first time lastTransactionLT + if !headSeen { + headSeen = true + } else if i == 0 { + continue + } + + if tx.IO.In == nil || tx.IO.In.Msg.SenderAddr().IsAddrNone() { + // external message should be omitted + continue + } + + if tx.IO.Out != nil { + // no outgoing messages - this is incoming Toncoins + continue + } + + // process trx + log.Printf("found in transaction hash %s", base64.StdEncoding.EncodeToString(tx.Hash)) + } + + if len(trxs) == 0 || (headSeen && len(trxs) == 1) { + break + } + + lastTransactionId = trxs[0].Hash + lastTransactionLT = trxs[0].LT + } +} +``` + +
+
+ + + +- **yungwine/pytoniq:** + +Depozyty czekowe + +```python +import asyncio + +from pytoniq_core import Transaction + +from pytoniq import LiteClient, Address + +MY_ADDRESS = Address("kf8zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM_BP") + + +async def main(): + client = LiteClient.from_mainnet_config(ls_i=0, trust_level=2) + + await client.connect() + + last_block = await client.get_trusted_last_mc_block() + + _account, shard_account = await client.raw_get_account_state(MY_ADDRESS, last_block) + assert shard_account + + last_trans_lt, last_trans_hash = ( + shard_account.last_trans_lt, + shard_account.last_trans_hash, + ) + + while True: + print(f"Waiting for{last_block=}") + + transactions = await client.get_transactions( + MY_ADDRESS, 1024, last_trans_lt, last_trans_hash + ) + toncoin_deposits = [tx for tx in transactions if filter_toncoin_deposit(tx)] + print(f"Got {len(transactions)=} with {len(toncoin_deposits)=}") + + for deposit_tx in toncoin_deposits: + # Process toncoin deposit transaction + print(deposit_tx.cell.hash.hex()) + + last_trans_lt = transactions[0].lt + last_trans_hash = transactions[0].cell.hash + + +def filter_toncoin_deposit(tx: Transaction): + if tx.out_msgs: + return False + + if tx.in_msg: + return False + + return True + + +if __name__ == "__main__": + asyncio.run(main()) +``` + + +
+ +### Wypłaty toncoinów (proszę wysłać toncoiny) + + + + +- **toncenter:** + - [Wypłacanie toncoinów z portfela partiami](https://github.com/toncenter/examples/blob/main/withdrawals-highload-batch.js) + - [Wypłata toncoinów z portfela](https://github.com/toncenter/examples/blob/main/withdrawals-highload.js) + +- **ton-community/ton:** + - [Wypłata toncoinów z portfela](https://github.com/ton-community/ton#usage) + + + + + +- **xssnick/tonutils-go:**. + - [Wypłata toncoinów z portfela](https://github.com/xssnick/tonutils-go?tab=readme-ov-file#wallet) + + + + + +- **psylopunk/pythonlib:** + - [Wypłata toncoinów z portfela](https://github.com/psylopunk/pytonlib/blob/main/examples/transactions.py) + +- **yungwine/pytoniq:** + +```python +import asyncio + +from pytoniq_core import Address +from pytoniq.contract.wallets.wallet import WalletV4R2 +from pytoniq.liteclient.balancer import LiteBalancer + + +MY_MNEMONICS = "one two tree ..." +DESTINATION_WALLET = Address("Destination wallet address") + + +async def main(): + provider = LiteBalancer.from_mainnet_config() + await provider.start_up() + + wallet = await WalletV4R2.from_mnemonic(provider, MY_MNEMONICS) + + await wallet.transfer(DESTINATION_WALLET, 5) + + await provider.close_all() + + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + + +### Proszę pobrać transakcje kontraktu + + + + +- **ton-community/ton:** + - [Klient z metodą getTransaction](https://github.com/ton-community/ton/blob/master/src/client/TonClient.ts) + + + + + +- **xssnick/tonutils-go:**. + - [Proszę pobrać transakcje](https://github.com/xssnick/tonutils-go?tab=readme-ov-file#account-info-and-transactions) + + + + + +- **psylopunk/pythonlib:** + - [Proszę pobrać transakcje](https://github.com/psylopunk/pytonlib/blob/main/examples/transactions.py) +- **yungwine/pytoniq:** + - [Proszę pobrać transakcje](https://github.com/yungwine/pytoniq/blob/master/examples/transactions.py) + + + + + +## SDK + +Listę zestawów SDK dla różnych języków (JS, Python, Golang, C#, Rust itp.) można znaleźć [tutaj] (/develop/dapps/apis/sdk). diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md b/i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md new file mode 100644 index 0000000000..a19d50dcf6 --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md @@ -0,0 +1,1205 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import Button from '@site/src/components/button'; + +# Przetwarzanie TON Jetton + +:::info +Dla jasnego zrozumienia, czytelnik powinien być zaznajomiony z podstawowymi zasadami przetwarzania aktywów opisanymi w [sekcji przetwarzania płatności](/develop/dapps/asset-processing/) naszej dokumentacji. +::: + +Jettony to tokeny na TON Blockchain - można je traktować podobnie do tokenów ERC-20 na Ethereum. + +W tej analizie zagłębiamy się w formalne standardy wyszczególniające jetton [zachowanie](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md) i [metadane](https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md). +Mniej formalny przegląd architektury jetton skoncentrowany na shardingu można znaleźć w naszym wpisie na blogu +[anatomy of jettons](https://blog.ton.org/how-to-shard-your-ton-smart-contract-and-why-studying-the-anatomy-of-tons-jettons). + +Należy również pamiętać, że istnieją dwa podejścia do pracy z wypłatami jetton: + +- [Memo Deposits](https://github.com/toncenter/examples/blob/main/deposits-jettons.js) - Pozwala to na utrzymanie jednego portfela depozytowego, a użytkownicy dodają notatkę w celu identyfikacji przez system. Oznacza to, że nie trzeba skanować całego łańcucha bloków, ale jest to nieco mniej łatwe dla użytkowników. +- [Depozyty bez notatek](https://github.com/gobicycle/bicycle) - To rozwiązanie również istnieje, ale jest trudniejsze do zintegrowania. Możemy jednak w tym pomóc, jeśli wolą Państwo wybrać tę drogę. Proszę powiadomić nas przed podjęciem decyzji o wdrożeniu tego podejścia. + +## Architektura Jetton + +Standardowe tokeny w TON są wdrażane przy użyciu zestawu inteligentnych kontraktów, w tym: + +- Inteligentny kontrakt [Jetton master](https://github.com/ton-blockchain/token-contract/blob/main/ft/jetton-minter.fc) +- [portfel Jetton](https://github.com/ton-blockchain/token-contract/blob/main/ft/jetton-wallet.fc) inteligentne kontrakty + +

+
+ contracts scheme +
+

+ +## Główny inteligentny kontrakt Jetton + +Główny inteligentny kontrakt jetton przechowuje ogólne informacje o jetton (w tym całkowitą podaż, link do metadanych lub same metadane). + +:::warning Proszę uważać na oszustwo Jetton + +Jettony z `symbolem`==`TON` lub te, które zawierają powiadomienia systemowe, takie jak: +`ERROR`, `SYSTEM` i inne. Proszę upewnić się, że jettony są wyświetlane w interfejsie w taki sposób, że nie mogą +być mieszane z transferami TON, powiadomieniami systemowymi itp. Czasami nawet `symbol`, `name` i `image` +będą tworzone tak, by wyglądały niemal identycznie do oryginału z nadzieją na wprowadzenie użytkowników w błąd. + +Aby wyeliminować możliwość oszustwa dla użytkowników TON, proszę sprawdzić **oryginalny adres jetton** (umowa główna Jetton) dla określonych typów jetton lub **śledzić oficjalne media społecznościowe projektu** lub stronę internetową, aby znaleźć **prawidłowe informacje**. Proszę sprawdzić aktywa, aby wyeliminować możliwość oszustwa za pomocą [Tonkeeper ton-assets list](https://github.com/tonkeeper/ton-assets). +::: + +### Pobieranie danych Jetton + +Aby pobrać bardziej szczegółowe dane Jetton, proszę użyć metody *get* kontraktu `get_jetton_data()`. + +Metoda ta zwraca następujące dane: + +| Nazwa | Typ | Opis | +| -------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `total_supply` | `int` | całkowita liczba wydanych jettonów mierzona w niepodzielnych jednostkach. | +| `mintable` | `int` | określa, czy nowe jettony mogą zostać wybite, czy nie. Wartość ta wynosi -1 (można wybijać) lub 0 (nie można wybijać). | +| `admin_address` | `slice` | | +| `jetton_content` | `cell` | dane zgodnie z [TEP-64](https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md), proszę sprawdzić [jetton metadata parsing page](/develop/dapps/asset-processing/metadata), aby dowiedzieć się więcej. | +| `jetton_wallet_code` | `cell` | | + +Można go wywołać za pomocą [Toncenter API](https://toncenter.com/api/v3/#/default/get_jetton_masters_api_v3_jetton_masters_get) lub jednego z [SDK](https://docs.ton.org/develop/dapps/apis/sdk). + + + + +> Proszę uruchomić metodę `jetton/masters` z [Toncenter API](https://toncenter.com/api/v3/#/default/get_jetton_masters_api_v3_jetton_masters_get). + + + + +```js +import TonWeb from "tonweb"; +const tonweb = new TonWeb(); +const jettonMinter = new TonWeb.token.jetton.JettonMinter(tonweb.provider, {address: ""}); +const data = await jettonMinter.getJettonData(); +console.log('Total supply:', data.totalSupply.toString()); +console.log('URI to off-chain metadata:', data.jettonContentUri); +``` + + + + +### Górnik Jetton + +Jak wspomniano wcześniej, jettony mogą być `mintable` lub `non-mintable`. + +Jeśli nie można ich wybić, logika staje się prosta - nie ma możliwości wybicia dodatkowych tokenów. Aby wybić jettony po raz pierwszy, proszę zapoznać się ze stroną [Mint your first jetton](/develop/dapps/tutorials/jetton-minter). + +Jeśli jettony mogą być bite, istnieje specjalna funkcja w [kontrakcie mintera](https://github.com/ton-blockchain/minter-contract/blob/main/contracts/jetton-minter.fc) do bicia dodatkowych jettonów. Funkcja ta może zostać wywołana poprzez wysłanie `wewnętrznej wiadomości` z określonym kodem operacyjnym z adresu administratora. + +Jeśli administrator jetton chce ograniczyć tworzenie jetton, może to zrobić na trzy sposoby: + +1. Jeśli nie mogą lub nie chcą Państwo zaktualizować kodu umowy, administrator musi przenieść własność z obecnego administratora na adres zerowy. Spowoduje to, że kontrakt pozostanie bez ważnego administratora, co uniemożliwi komukolwiek wybijanie jettonów. Zapobiegnie to jednak również jakimkolwiek zmianom w metadanych jettona. +2. Jeśli mają Państwo dostęp do kodu źródłowego i mogą go zmienić, można utworzyć metodę w kontrakcie, która ustawia flagę przerywającą proces wybijania po jej wywołaniu i dodać instrukcję sprawdzającą tę flagę w funkcji mint. +3. Jeśli można zaktualizować kod umowy, można dodać ograniczenia, aktualizując kod już wdrożonej umowy. + +## Inteligentny kontrakt portfela Jetton + +Kontrakty `portfela jettona` są używane do **wysyłania**, **odbierania** i **spalania** jettonów. Każdy kontrakt *portfela jettona* przechowuje informacje o saldzie portfela dla określonych użytkowników. +W określonych przypadkach, portfele jettona są używane dla indywidualnych posiadaczy jettona dla każdego typu jettona. + +"Portfeli jetton" **nie należy mylić z portfelami** przeznaczonymi do interakcji z blockchainem i przechowywania +tylko aktywów Toncoin (np. portfele v3R2, portfele highload i inne), +które są odpowiedzialne za obsługę i zarządzanie **tylko określonym typem jetton**. + +### Wdrożenie portfela Jetton + +Podczas `przekazywania jettonów` między portfelami, transakcje (wiadomości) wymagają pewnej ilości TON +jako zapłaty za **opłaty gazowe** sieci i wykonanie działań zgodnie z kodem kontraktu portfela Jetton. +Oznacza to, że **odbiorca nie musi wdrażać portfela jetton przed otrzymaniem jettonów**. +Portfel Jetton odbiorcy zostanie wdrożony automatycznie, o ile nadawca posiada wystarczającą ilość TON +w portfelu, aby uiścić wymagane opłaty za gaz. + +### Pobieranie adresów portfela Jetton dla danego użytkownika + +Aby pobrać `adres portfela Jetton` przy użyciu `adresu właściciela` (adres portfela TON), +`kontrakt główny Jetton` udostępnia metodę get `get_wallet_address(slice owner_address)`. + + + + +> Proszę uruchomić `get_wallet_address(slice owner_address)` poprzez metodę `/runGetMethod` z [Toncenter API](https://toncenter.com/api/v3/#/default/run_get_method_api_v3_runGetMethod_post). + + + + +```js +import TonWeb from "tonweb"; +const tonweb = new TonWeb(); +const jettonMinter = new TonWeb.token.jetton.JettonMinter(tonweb.provider, {address: ""}); +const address = await jettonMinter.getJettonWalletAddress(new TonWeb.utils.Address("")); +// It is important to always check that wallet indeed is attributed to desired Jetton Master: +const jettonWallet = new TonWeb.token.jetton.JettonWallet(tonweb.provider, { + address: jettonWalletAddress +}); +const jettonData = await jettonWallet.getData(); +if (jettonData.jettonMinterAddress.toString(false) !== new TonWeb.utils.Address(info.address).toString(false)) { + throw new Error('jetton minter address from jetton wallet doesnt match config'); +} + +console.log('Jetton wallet address:', address.toString(true, true, true)); +``` + + + + +### Pobieranie danych dla określonego portfela Jetton + +Aby pobrać saldo konta portfela, informacje identyfikacyjne właściciela i inne informacje związane z konkretnym kontraktem portfela jetton, należy użyć metody `get_wallet_data()` w kontrakcie portfela jetton. + +Metoda ta zwraca następujące dane: + +| Nazwa | Typ | +| -------------------- | --------- | +| `balance` | int | +| `właściciel` | plasterek | +| `jetton` | plasterek | +| `jetton_wallet_code` | komórka | + + + + +> Proszę użyć metody `/jetton/wallets` get z [Toncenter API](https://toncenter.com/api/v3/#/default/get_jetton_wallets_api_v3_jetton_wallets_get), aby pobrać wcześniej zdekodowane dane portfela jetton. + + + + + +```js +import TonWeb from "tonweb"; +const tonweb = new TonWeb(); +const walletAddress = "EQBYc3DSi36qur7-DLDYd-AmRRb4-zk6VkzX0etv5Pa-Bq4Y"; +const jettonWallet = new TonWeb.token.jetton.JettonWallet(tonweb.provider,{address: walletAddress}); +const data = await jettonWallet.getData(); +console.log('Jetton balance:', data.balance.toString()); +console.log('Jetton owner address:', data.ownerAddress.toString(true, true, true)); +// It is important to always check that Jetton Master indeed recognize wallet +const jettonMinter = new TonWeb.token.jetton.JettonMinter(tonweb.provider, {address: data.jettonMinterAddress.toString(false)}); +const expectedJettonWalletAddress = await jettonMinter.getJettonWalletAddress(data.ownerAddress.toString(false)); +if (expectedJettonWalletAddress.toString(false) !== new TonWeb.utils.Address(walletAddress).toString(false)) { + throw new Error('jetton minter does not recognize the wallet'); +} + +console.log('Jetton master address:', data.jettonMinterAddress.toString(true, true, true)); +``` + + + + +## Przegląd komunikacji portfeli Jetton + +Komunikacja między portfelami Jetton a portfelami TON odbywa się poprzez następującą sekwencję komunikacji: + +![](/img/docs/asset-processing/jetton_transfer.svg) + +#### Wiadomość 0 + +`Nadawca -> portfel jetton nadawcy`. Wiadomość *Transfer* zawiera następujące dane: + +| Nazwa | Typ | Opis | +| ---------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `query_id` | uint64 | Umożliwia aplikacjom powiązanie ze sobą trzech typów wiadomości `Transfer`, `Powiadomienie o transferze` i `Excesses`. Aby proces ten został przeprowadzony poprawnie, zaleca się **zawsze używać unikalnego identyfikatora zapytania**. | +| `kwota` | monety | Całkowita kwota `ton monety`, która zostanie wysłana wraz z wiadomością. | +| `przeznaczenie` | adres | Adres nowego właściciela jettons | +| `response_destination` | adres | Adres portfela używany do zwracania pozostałych ton monet z wiadomością o przekroczeniu limitu. | +| `custom_payload` | może komórka | Rozmiar zawsze wynosi >= 1 bit. Dane niestandardowe (które są używane przez nadawcę lub odbiorcę portfela jetton dla wewnętrznej logiki). | +| `forward_ton_amount` | monety | Musi być > 0, jeśli chcesz wysłać `powiadomienie o transferze` z `przekazanym ładunkiem`. Jest to **część wartości `amount`** i **musi być mniejsza niż `amount`**. | +| `forward_payload` | może komórka | Rozmiar zawsze wynosi >= 1 bit. Jeśli pierwsze 32 bity = 0x0, jest to zwykła wiadomość. | + +#### Wiadomość 2 + +`portfel jetton odbiorcy płatności -> odbiorca płatności`. Wiadomość z powiadomieniem o przelewie. **Wysyłana tylko jeśli** `forward_ton_amount` **nie wynosi zero**. Zawiera następujące dane: + +| Nazwa | Typ | +| ----------------- | ------- | +| `query_id` | uint64 | +| `kwota` | monety | +| `nadawca` | adres | +| `forward_payload` | komórka | + +Tutaj `adres nadawcy` jest adresem `portfela Jetton` Alice. + +#### Wiadomość 2'' + +`payee's jetton wallet -> Sender`. Treść wiadomości. **Wysyłane tylko wtedy, gdy po uiszczeniu opłat pozostały jakiekolwiek monety tonowe**. Zawiera następujące dane: + +| Nazwa | Typ | +| ---------- | ------ | +| `query_id` | uint64 | + +:::tip Jettons standard +Szczegółowy opis pól kontraktu portfela jetton można znaleźć w opisie interfejsu [TEP-74](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md) `Jetton standard`. +::: + +## Proszę wysłać Jettons z komentarzami + +Ten przelew wymaga kilku ton monet na **opłaty** i, opcjonalnie, **wiadomości o przelewie** (proszę sprawdzić pole kwoty przelewu). + +Aby wysłać **komentarz** należy skonfigurować `forward payload`. Proszę ustawić **pierwsze 32 bity na 0x0** i dołączyć **swój tekst**. + +`forward payload` jest wysyłany w wewnętrznej wiadomości `transfer notification`. Zostanie on wygenerowany tylko wtedy, gdy `forward amount` > 0. + +Wreszcie, aby pobrać wiadomość `Excess`, należy ustawić `miejsce docelowe odpowiedzi`. + +:::tip +Proszę sprawdzić [best practices](/develop/dapps/asset-processing/jettons#best-practices) dla przykładu *"send jettons with comments"*. +::: + +## Przetwarzanie poza łańcuchem Jetton + +:::info Potwierdzenie transakcji +Transakcje TON są nieodwracalne po jednym potwierdzeniu. Aby uzyskać najlepsze wrażenia użytkownika, zaleca się unikanie czekania na dodatkowe bloki po sfinalizowaniu transakcji na blockchainie TON. Więcej informacji znajdą Państwo w dokumencie [Catchain.pdf] (https://docs.ton.org/catchain.pdf#page=3). +::: + +Istnieją dwa sposoby akceptacji Jettonów: + +- w ramach \*\* scentralizowanego gorącego portfela\*\*. +- przy użyciu portfela z **oddzielnym adresem** dla **każdego indywidualnego użytkownika**. + +Ze względów bezpieczeństwa zaleca się posiadanie **oddzielnych gorących portfeli** dla **oddzielnych Jettonów** (wiele portfeli dla każdego typu aktywów). + +Podczas przetwarzania środków zaleca się również zapewnienie zimnego portfela do przechowywania nadwyżek środków, które nie uczestniczą w automatycznych procesach wpłat i wypłat. + +### Dodawanie nowych Jettonów do przetwarzania zasobów i wstępnej weryfikacji + +1. Proszę znaleźć poprawny adres [smart contract] (/develop/dapps/asset-processing/jettons#jetton-master-smart-contract). +2. Proszę pobrać [metadane](/develop/dapps/asset-processing/jettons#retrieving-jetton-data). +3. Proszę sprawdzić, czy nie ma [scam](/develop/dapps/asset-processing/jettons#jetton-master-smart-contract). + +### Identyfikacja nieznanego urządzenia Jetton podczas odbierania komunikatu powiadomienia o transferze + +Jeśli w Państwa portfelu zostanie odebrana wiadomość z powiadomieniem o transferze dotycząca nieznanego Jettona, oznacza to, że Państwa portfel +został utworzony w celu przechowywania konkretnego Jettona. + +Adres nadawcy wewnętrznej wiadomości zawierającej treść `Transfer notification` jest adresem nowego portfela Jetton. +Nie należy go mylić z polem `sender` w powiadomieniu `Transfer notification` [body] (/develop/dapps/asset-processing/jettons#jetton-wallets-communication-overview). + +1. Proszę pobrać adres główny Jetton dla nowego portfela Jetton poprzez [getting wallet data](/develop/dapps/asset-processing/jettons#retrieving-data-for-a-specific-jetton-wallet). +2. Proszę pobrać adres portfela Jetton dla swojego adresu portfela (jako właściciela) za pomocą głównego kontraktu Jetton: [Jak pobrać adres portfela Jetton dla danego użytkownika] (#retrieving-jetton-wallet-addresses-for-a-given-user) +3. Proszę porównać adres zwrócony przez główny kontrakt i rzeczywisty adres tokena portfela. + Jeśli się zgadzają, to idealnie. Jeśli nie, to prawdopodobnie otrzymali Państwo fałszywy token. +4. Pobieranie metadanych Jetton: [Jak otrzymać metadane Jetton](#retrieving-jetton-data). +5. Proszę sprawdzić pola `symbol` i `name` pod kątem oznak oszustwa. W razie potrzeby proszę ostrzec użytkownika. [Dodawanie nowych Jettons do przetwarzania i wstępnej weryfikacji](#adding-new-jettons-for-asset-processing-and-initial-verification). + +### Przyjmowanie Jettonów od użytkowników za pośrednictwem scentralizowanego portfela + +:::info +Aby zapobiec wąskiemu gardłu w transakcjach przychodzących do jednego portfela, sugeruje się przyjmowanie depozytów w wielu portfelach i zwiększanie liczby tych portfeli w razie potrzeby. +::: + +W tym scenariuszu usługa płatności tworzy unikalny identyfikator notatki dla każdego nadawcy, ujawniając +adres scentralizowanego portfela i wysyłane kwoty. Nadawca wysyła tokeny +na podany scentralizowany adres z obowiązkową notatką w komentarzu. + +**Zalety tej metody:** ta metoda jest bardzo prosta, ponieważ nie ma żadnych dodatkowych opłat przy przyjmowaniu tokenów i są one pobierane bezpośrednio do gorącego portfela. + +**Wady tej metody:** ta metoda wymaga od wszystkich użytkowników dołączenia komentarza do przelewu, co może prowadzić do większej liczby błędów wpłat (zapomniane notatki, nieprawidłowe notatki itp.), co oznacza większe obciążenie personelu pomocniczego. + +Przykłady Tonweb: + +1. [Przyjmowanie wpłat Jetton do indywidualnego portfela HOT z komentarzami (notatka)](https://github.com/toncenter/examples/blob/main/deposits-jettons.js) +2. [Przykład wypłat Jettons](https://github.com/toncenter/examples/blob/main/withdrawals-jettons.js) + +#### Przygotowania + +1. [Proszę przygotować listę zaakceptowanych Jettonów](/develop/dapps/asset-processing/jettons#adding-new-jettons-for-asset-processing-and-initial-verification) (adresy główne Jettonów). +2. Proszę wdrożyć gorący portfel (używając v3R2, jeśli nie oczekuje się wypłat Jetton; highload v3 - jeśli oczekuje się wypłat Jetton). [Wdrożenie portfela](/develop/dapps/asset-processing/#wallet-deployment). +3. Proszę wykonać testowy transfer Jetton przy użyciu adresu gorącego portfela, aby zainicjować portfel. + +#### Przetwarzanie przychodzących Jettonów + +1. Proszę załadować listę zaakceptowanych Jettonów. +2. [Odzyskaj adres portfela Jetton](#retrieving-jetton-wallet-addresses-for-a-given-user) dla wdrożonego gorącego portfela. +3. Proszę pobrać adres główny Jetton dla każdego portfela Jetton za pomocą [getting wallet data] (/develop/dapps/asset-processing/jettons#retrieving-data-for-a-specific-jetton-wallet). +4. Proszę porównać adresy umów głównych Jetton z kroku 1. i kroku 3 (bezpośrednio powyżej). + Jeśli adresy nie są zgodne, należy zgłosić błąd weryfikacji adresu Jetton. +5. Pobiera listę ostatnich nieprzetworzonych transakcji przy użyciu konta hot wallet i + iteruje ją (sortując każdą transakcję po kolei). Proszę zobaczyć: [Sprawdzanie transakcji kontraktu](https://docs.ton.org/develop/dapps/asset-processing/#checking-contracts-transactions). +6. Proszę sprawdzić wiadomość wejściową (in_msg) pod kątem transakcji i pobrać adres źródłowy z wiadomości wejściowej. [Przykład Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-jettons-single-wallet.js#L84) +7. Jeśli adres źródłowy jest zgodny z adresem w portfelu Jetton, należy kontynuować przetwarzanie transakcji. + Jeśli nie, proszę pominąć przetwarzanie transakcji i sprawdzić następną transakcję. +8. Proszę upewnić się, że treść wiadomości nie jest pusta i że pierwsze 32 bity wiadomości pasują do kodu op `transfer notification` `0x7362d09c`. + [Przykład Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-jettons-single-wallet.js#L91) + Jeśli treść wiadomości jest pusta lub kod op jest nieprawidłowy - proszę pominąć transakcję. +9. Proszę odczytać pozostałe dane wiadomości, w tym `query_id`, `amount`, `sender`, `forward_payload`. + [Układy wiadomości w kontraktach Jetton](#jetton-contract-message-layouts), [Przykład Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-jettons-single-wallet.js#L105) +10. Proszę spróbować pobrać komentarze tekstowe z danych `forward_payload`. Pierwsze 32 bity muszą odpowiadać + kodowi op komentarza tekstowego `0x00000000`, a pozostałe - tekstowi zakodowanemu w UTF-8. + [Przykład Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-jettons-single-wallet.js#L110) +11. Jeśli dane `forward_payload` są puste lub kod operacji jest nieprawidłowy - proszę pominąć transakcję. +12. Proszę porównać otrzymany komentarz z zapisanymi notatkami. Jeśli istnieje zgodność (identyfikacja użytkownika jest zawsze możliwa) - proszę wpłacić przelew. +13. Proszę zacząć od kroku 5 i powtarzać ten proces, aż przejdą Państwo przez całą listę transakcji. + +### Przyjmowanie Jettonów z adresów depozytowych użytkowników + +Aby akceptować Jettony z adresów depozytowych użytkowników, konieczne jest, aby usługa płatności utworzyła swój +indywidualny adres (depozyt) dla każdego uczestnika wysyłającego środki. Świadczenie usługi w tym przypadku obejmuje +wykonanie kilku równoległych procesów, w tym tworzenie nowych depozytów, skanowanie bloków w poszukiwaniu transakcji, +wypłacanie środków z depozytów do gorącego portfela i tak dalej. + +Ponieważ gorący portfel może korzystać z jednego portfela Jetton dla każdego typu Jetton, konieczne jest utworzenie wielu portfeli +w celu zainicjowania wpłat. Aby utworzyć dużą liczbę portfeli, ale jednocześnie zarządzać nimi za pomocą +jednej frazy seed (lub klucza prywatnego), konieczne jest określenie innego `subwallet_id` podczas tworzenia portfela. +W TON funkcjonalność wymagana do utworzenia subportfela jest obsługiwana przez portfele w wersji v3 i wyższych. + +#### Tworzenie subportfela w Tonweb + +```js +const WalletClass = tonweb.wallet.all['v3R2']; +const wallet = new WalletClass(tonweb.provider, { + publicKey: keyPair.publicKey, + wc: 0, + walletId: , +}); +``` + +#### Przygotowanie + +1. [Proszę przygotować listę zaakceptowanych Jettonów](#adding-new-jettons-for-asset-processing-and-initial-verification). +2. Proszę wdrożyć gorący portfel (używając v3R2, jeśli nie oczekuje się wypłat Jetton; highload v3 - jeśli oczekuje się wypłat Jetton). [Wdrożenie portfela](/develop/dapps/asset-processing/#wallet-deployment). + +#### Tworzenie depozytów + +1. Akceptuje żądanie utworzenia nowego depozytu dla użytkownika. +2. Proszę wygenerować nowy adres subwallet (v3R2) na podstawie seedu hot wallet. [Tworzenie subportfela w Tonweb](#creating-a-subwallet-in-tonweb) +3. Adres odbiorczy może być podany użytkownikowi jako adres używany do wpłat Jetton (jest to adres + właściciela portfela Jetton depozytu). Inicjalizacja portfela nie jest wymagana, można to zrobić + podczas wypłacania Jettonów z depozytu. +4. Aby uzyskać ten adres, konieczne jest obliczenie adresu portfela Jetton za pośrednictwem głównego kontraktu Jetton. + [Jak pobrać adres portfela Jetton dla danego użytkownika] (#retrieving-jetton-wallet-addresses-for-a-given-user). +5. Proszę dodać adres portfela Jetton do puli adresów w celu monitorowania transakcji i zapisać adres subportfela. + +#### Przetwarzanie transakcji + +:::info Potwierdzenie transakcji +Transakcje TON są nieodwracalne po jednym potwierdzeniu. Aby uzyskać najlepsze wrażenia użytkownika, zaleca się unikanie czekania na dodatkowe bloki po sfinalizowaniu transakcji na blockchainie TON. Więcej informacji znajdą Państwo w dokumencie [Catchain.pdf] (https://docs.ton.org/catchain.pdf#page=3). +::: + +Nie zawsze jest możliwe określenie dokładnej ilości Jettonów otrzymanych z wiadomości, ponieważ portfele Jetton +mogą nie wysyłać wiadomości `powiadomienia o transferze`, `nadwyżkach` i `przelewach wewnętrznych`. Nie są one ustandaryzowane. Oznacza to, że +nie ma gwarancji, że wiadomość `internal transfer` może zostać zdekodowana. + +W związku z tym, aby określić kwotę otrzymaną w portfelu, należy zażądać sald za pomocą metody get. +Aby pobrać kluczowe dane podczas żądania sald, bloki są używane zgodnie ze stanem konta dla określonego bloku w łańcuchu. +[Przygotowanie do akceptacji bloku przy użyciu Tonweb](https://github.com/toncenter/tonweb/blob/master/src/test-block-subscribe.js). + +Proces ten przebiega w następujący sposób: + +1. Przygotowanie do akceptacji bloków (poprzez przygotowanie systemu do akceptacji nowych bloków). +2. Pobiera nowy blok i zapisuje poprzedni identyfikator bloku. +3. Odbieranie transakcji z bloków. +4. Proszę filtrować transakcje używane tylko z adresami z puli portfela Jetton. +5. Dekodowanie wiadomości za pomocą treści `transfer notification` w celu otrzymania bardziej szczegółowych danych, w tym adresu + `nadawcy`, `kwoty` Jetton i komentarza. (Proszę zobaczyć: [Przetwarzanie przychodzących Jettonów](#processing-incoming-jettons)) +6. Jeśli istnieje co najmniej jedna transakcja z niedekodowalnymi komunikatami out (treść komunikatu nie zawiera kodów op dla + `powiadomienia o przelewie` i kodów op dla `przetargów`) lub bez komunikatów out obecnych na koncie + , wówczas saldo Jetton musi zostać zażądane przy użyciu metody get dla bieżącego bloku, podczas gdy poprzedni blok + jest używany do obliczenia różnicy sald. Teraz całkowite zmiany depozytu salda są ujawniane dzięki + transakcjom przeprowadzanym w bloku. +7. Jako identyfikator niezidentyfikowanego transferu Jettons (bez "powiadomienia o transferze") można użyć danych transakcji + , jeśli istnieje jedna taka transakcja lub dane bloku (jeśli kilka jest obecnych w bloku). +8. Teraz należy sprawdzić, czy saldo depozytu jest prawidłowe. Jeśli saldo depozytu jest wystarczające do zainicjowania transferu między gorącym portfelem a istniejącym portfelem Jetton, należy wypłacić Jettony, aby upewnić się, że saldo portfela zmniejszyło się. +9. Uruchomić ponownie od kroku 2 i powtórzyć cały proces. + +#### Wypłaty dokonane z depozytów + +Przelewy nie powinny być wykonywane z depozytu do gorącego portfela przy każdym uzupełnieniu depozytu, +ponieważ za operację przelewu pobierana jest prowizja w TON (płacona w opłatach za gaz sieciowy). +Ważne jest, aby określić pewną minimalną ilość Jettonów, które są wymagane, aby przelew +był opłacalny (a tym samym depozyt). + +Domyślnie właściciele portfeli depozytowych Jetton nie są inicjowani. Dzieje się tak, ponieważ nie ma z góry określonego +wymogu uiszczania opłat za przechowywanie. Portfele depozytowe Jetton mogą być wdrażane podczas wysyłania wiadomości z ciałem +`transfer`, które następnie można natychmiast zniszczyć. Aby to zrobić, inżynier musi użyć specjalnego mechanizmu +do wysyłania wiadomości: [128 + 32](/develop/smart-contracts/messages#message-modes). + +1. Pobieranie listy depozytów oznaczonych do wypłaty do gorącego portfela +2. Pobieranie zapisanych adresów właścicieli dla każdego depozytu +3. Wiadomości są następnie wysyłane na każdy adres właściciela (poprzez połączenie kilku takich wiadomości w partię) z portfela o wysokim obciążeniu + z dołączoną kwotą TON Jetton. Jest ona określana przez dodanie opłat za inicjalizację portfela v3R2* opłat za wysłanie wiadomości z treścią `transfer` + arbitralnej kwoty TON związanej z `forward_ton_amount` + (jeśli to konieczne). Załączona kwota TON jest określana przez dodanie opłat za inicjalizację portfela v3R2 (wartość) + + opłat za wysłanie wiadomości z treścią `transfer` (wartość) + dowolna kwota TON + dla `forward_ton_amount` (wartość) (jeśli to konieczne). +4. Gdy saldo na adresie stanie się niezerowe, status konta ulegnie zmianie. Proszę poczekać kilka sekund i sprawdzić status + konta, wkrótce zmieni się on ze stanu `nonexists` na `uninit`. +5. Dla każdego adresu właściciela (ze statusem `uninit`) konieczne jest wysłanie zewnętrznej wiadomości z portfelem v3R2 + init i ciałem z wiadomością `transfer` do wpłaty do portfela Jetton = 128 + 32. Dla `transfer`, + użytkownik musi określić adres gorącego portfela jako `destination` i `response destination`. + Można dodać komentarz tekstowy, aby ułatwić identyfikację transferu. +6. Możliwe jest zweryfikowanie dostawy Jetton za pomocą adresu depozytowego na adres gorącego portfela przez + , biorąc pod uwagę [przetwarzanie informacji o przychodzących Jettonach] (#processing-incoming-jettons). + +### Wypłaty Jetton + +:::info Ważne + +Poniżej znajdą Państwo przewodnik krok po kroku, jak przetwarzać wypłaty jetton. +::: + +Aby wypłacić Jettony, portfel wysyła wiadomości z treścią `transfer` do odpowiedniego portfela Jetton. +Portfel Jetton wysyła następnie Jettony do odbiorcy. W dobrej wierze ważne jest, aby dołączyć TON +jako `forward_ton_amount` (i opcjonalny komentarz do `forward_payload`), aby wywołać `powiadomienie o transferze`. +Proszę zobaczyć: [Układy wiadomości w kontraktach Jetton](#jetton-contract-message-layouts). + +#### Przygotowanie + +1. Proszę przygotować listę Jettonów do wypłaty: [Dodawanie nowych Jettonów do przetwarzania i wstępnej weryfikacji](#adding-new-jettons-for-asset-processing-and-initial-verification) +2. Rozpoczęto wdrażanie gorącego portfela. Zalecana jest wersja Highload v3. [Wdrożenie portfela](/develop/dapps/asset-processing/#wallet-deployment) +3. Proszę wykonać przelew Jetton przy użyciu adresu gorącego portfela, aby zainicjować portfel Jetton i uzupełnić jego saldo. + +#### Przetwarzanie wypłat + +1. Proszę załadować listę przetworzonych Jettonów +2. Pobieranie adresów portfela Jetton dla wdrożonego gorącego portfela: [Jak pobrać adresy portfela Jetton dla danego użytkownika] (#retrieving-jetton-wallet-addresses-for-a-given-user) +3. Proszę pobrać adresy główne Jetton dla każdego portfela Jetton: [Jak pobrać dane dla portfeli Jetton](#retrieving-data-for-a-specific-jetton-wallet). + Wymagany jest parametr `jetton` (który jest w rzeczywistości adresem głównego kontraktu Jetton). +4. Proszę porównać adresy z umów głównych Jetton z kroku 1. i kroku 3. Jeśli adresy nie są zgodne, należy zgłosić błąd weryfikacji adresu Jetton. +5. Otrzymywane są żądania wypłaty, które faktycznie wskazują rodzaj Jetton, kwotę przelewu i adres portfela odbiorcy. +6. Proszę sprawdzić saldo portfela Jetton, aby upewnić się, że na koncie znajduje się wystarczająca ilość środków do dokonania wypłaty. +7. Proszę wygenerować [wiadomość](/develop/dapps/asset-processing/jettons#message-0). +8. W przypadku korzystania z portfela o wysokim obciążeniu zaleca się zbieranie partii wiadomości i wysyłanie jednej partii na raz w celu optymalizacji opłat. +9. Proszę zapisać czas wygaśnięcia dla wychodzących wiadomości zewnętrznych (jest to czas do pomyślnego przetworzenia wiadomości przez portfel + , po jego upływie portfel nie będzie już akceptował wiadomości). +10. Wysłać pojedynczą wiadomość lub więcej niż jedną wiadomość (wiadomości wsadowe). +11. Pobiera listę ostatnich nieprzetworzonych transakcji na koncie hot wallet i iteruje ją. + Więcej informacji można znaleźć tutaj: [Sprawdzanie transakcji kontraktu](/develop/dapps/asset-processing/#checking-contracts-transactions), + [Przykład Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-single-wallet.js#L43) lub + proszę użyć metody Toncenter API `/getTransactions`. +12. Proszę sprawdzić wiadomości wychodzące na koncie. +13. Jeśli istnieje wiadomość z kodem operacyjnym `transfer`, należy ją zdekodować, aby pobrać wartość `query_id`. + Odzyskane `query_id` należy oznaczyć jako pomyślnie wysłane. +14. Jeśli czas potrzebny na przetworzenie bieżącej zeskanowanej transakcji jest dłuższy niż + czasu wygaśnięcia, a wiadomość wychodząca z podanym `query_id` + nie zostanie znaleziona, wówczas żądanie powinno (jest to opcjonalne) zostać oznaczone jako wygasłe i powinno zostać bezpiecznie wysłane ponownie. +15. Proszę sprawdzić przychodzące wiadomości na koncie. +16. Jeśli istnieje wiadomość, która używa kodu operacyjnego `excesses`, wiadomość powinna zostać zdekodowana, a wartość `query_id` + powinna zostać pobrana. Znaleziony `query_id` musi zostać oznaczony jako pomyślnie dostarczony. +17. Proszę przejść do kroku 5. Wygasłe żądania, które nie zostały pomyślnie wysłane, powinny zostać przesunięte z powrotem na listę wypłat. + +## Przetwarzanie w łańcuchu Jetton + +Ogólnie rzecz biorąc, aby zaakceptować i przetworzyć jettony, program obsługi wiadomości odpowiedzialny za wewnętrzne wiadomości używa kodu operacyjnego `op=0x7362d09c`. + +:::info Potwierdzenie transakcji +Transakcje TON są nieodwracalne po jednym potwierdzeniu. Aby uzyskać najlepsze wrażenia użytkownika, zaleca się unikanie czekania na dodatkowe bloki po sfinalizowaniu transakcji na blockchainie TON. Więcej informacji znajdą Państwo w dokumencie [Catchain.pdf] (https://docs.ton.org/catchain.pdf#page=3). +::: + +### Zalecenia dotyczące przetwarzania w łańcuchu + +Poniżej znajduje się "lista zaleceń", które należy wziąć pod uwagę podczas **przetwarzania jettonów w łańcuchu**: + +1. Proszę **identyfikować przychodzące jettony** używając ich typu portfela, a nie ich głównego kontraktu Jetton. Innymi słowy, Państwa kontrakt powinien wchodzić w interakcje (odbierać i wysyłać wiadomości) z konkretnym portfelem Jetton (a nie z jakimś nieznanym portfelem korzystającym z konkretnego głównego kontraktu Jetton). +2. Podczas łączenia portfela Jetton Wallet i Jetton Master, proszę **sprawdzić**, czy to **połączenie jest dwukierunkowe**, gdzie portfel rozpoznaje kontrakt główny i odwrotnie. Na przykład, jeśli Państwa system kontraktów otrzyma powiadomienie z portfela jetton (który uważa MySuperJetton za swój kontrakt główny), jego informacje o transferze muszą zostać wyświetlone użytkownikowi, przed wyświetleniem `symbolu`, `nazwy` i `obrazu` + kontraktu MySuperJetton, proszę sprawdzić, czy portfel MySuperJetton używa właściwego systemu kontraktów. Z kolei jeśli Państwa system kontraktowy z jakiegoś powodu musi wysyłać jettony przy użyciu kontraktów głównych MySuperJetton lub MySuperJetton, proszę sprawdzić, czy portfel X jest portfelem używającym tych samych parametrów kontraktu. + Dodatkowo, przed wysłaniem żądania `transfer` do X, proszę upewnić się, że rozpoznaje on MySuperJetton jako swój master. +3. **Prawdziwa moc** zdecentralizowanych finansów (DeFi) opiera się na możliwości układania protokołów jeden na drugim, jak klocki lego. Na przykład, powiedzmy, że jetton A jest zamieniany na jetton B, który z kolei jest następnie wykorzystywany jako dźwignia finansowa w ramach protokołu pożyczkowego (gdy użytkownik dostarcza płynność), który jest następnie wykorzystywany do zakupu NFT .... i tak dalej. W związku z tym proszę rozważyć, w jaki sposób umowa może służyć nie tylko użytkownikom poza łańcuchem, ale także podmiotom w łańcuchu, dołączając tokenizowaną wartość do powiadomienia o transferze, dodając niestandardowy ładunek, który można wysłać wraz z powiadomieniem o transferze. +4. \*\*Proszę pamiętać, że nie wszystkie umowy są zgodne z tymi samymi standardami. Niestety, niektóre jettony mogą być wrogie (wykorzystujące wektory ataku) i tworzone wyłącznie w celu atakowania niczego niepodejrzewających użytkowników. Ze względów bezpieczeństwa, jeśli dany protokół składa się z wielu kontraktów, proszę nie tworzyć dużej liczby portfeli jettton tego samego typu. W szczególności proszę nie wysyłać jetttonów wewnątrz protokołu pomiędzy kontraktem depozytowym, kontraktem skarbca lub kontraktem konta użytkownika itp. Atakujący mogą celowo zakłócać logikę kontraktu poprzez fałszowanie powiadomień o transferze, kwot jettona lub parametrów ładunku. Proszę zredukować potencjał ataku poprzez używanie tylko jednego portfela w systemie na jettona (dla wszystkich wpłat i wypłat). +5. Często dobrym pomysłem jest również **tworzenie subkontraktów** dla każdego zindywidualizowanego jettona, aby zmniejszyć ryzyko spoofingu adresów (na przykład, gdy wiadomość transferowa jest wysyłana do jettona B przy użyciu kontraktu przeznaczonego dla jettona A). +6. Zdecydowanie zaleca się \*\*pracę z niepodzielnymi jednostkami jetton na poziomie kontraktu. Logika związana z ułamkami dziesiętnymi jest zwykle używana do ulepszania interfejsu użytkownika aplikacji i nie jest związana z numerycznym przechowywaniem rekordów w łańcuchu. + +Aby dowiedzieć się **więcej** na temat [Secure Smart Contract Programming in FunC by CertiK](https://blog.ton.org/secure-smart-contract-programming-in-func), prosimy zapoznać się z tym zasobem. Zaleca się, aby programiści **obsługiwali wszystkie wyjątki inteligentnych kontraktów**, aby nigdy nie zostały one pominięte podczas tworzenia aplikacji. + +## Zalecenia dotyczące przetwarzania portfela Jetton + +Ogólnie rzecz biorąc, wszystkie procedury weryfikacji stosowane do przetwarzania Jetton poza łańcuchem są odpowiednie również dla portfeli. W przypadku przetwarzania portfela Jetton nasze najważniejsze zalecenia są następujące: + +1. Kiedy portfel otrzymuje powiadomienie o przelewie z nieznanego portfela jetton, bardzo ważne jest, aby zaufać portfelowi jetton i jego adresowi głównemu, ponieważ może to być złośliwa podróbka. Aby się zabezpieczyć, należy sprawdzić Jetton Master (główny kontrakt) przy użyciu podanego adresu, aby upewnić się, że procesy weryfikacji rozpoznają portfel jetton jako legalny. Po zaufaniu portfelowi i zweryfikowaniu go jako legalnego, można zezwolić mu na dostęp do sald kont i innych danych w portfelu. Jeśli Jetton Master nie rozpoznaje tego portfela, zaleca się, aby w ogóle nie inicjować ani nie ujawniać przelewów jetton i wyświetlać tylko przychodzące przelewy TON (Toncoin dołączone do powiadomień o przelewach). +2. W praktyce, jeśli użytkownik chce wejść w interakcję z Jetton, a nie z portfelem Jetton. Innymi słowy, użytkownicy wysyłają wTON/oUSDT/jUSDT, jUSDC, jDAI zamiast `EQAjN...`/`EQBLE...` + itd. Często oznacza to, że gdy użytkownik inicjuje transfer jetton, portfel pyta odpowiedniego mastera jetton, który portfel jetton (należący do użytkownika) powinien zainicjować żądanie transferu. Ważne jest, aby **nigdy nie ufać ślepo** tym danym od Mastera (głównego kontraktu). Przed wysłaniem żądania transferu do portfela jetton, proszę zawsze upewnić się, że portfel jetton rzeczywiście należy do Jetton Master, do którego rzekomo należy. +3. **Proszę pamiętać**, że wrodzy Mistrzowie Jetton/portfele Jetton **mogą z czasem zmienić** swoje portfele/Mistrzów. Dlatego konieczne jest, aby użytkownicy dołożyli należytej staranności i sprawdzili legalność wszystkich portfeli, z którymi wchodzą w interakcję przed każdym użyciem. +4. **Zawsze proszę upewnić się**, że wyświetlają Państwo jettony w swoim interfejsie w sposób, który **nie będzie mieszał się z transferami TON**, powiadomieniami systemowymi itp. Nawet parametry `symbol`, `name` i `image` + mogą zostać spreparowane w celu wprowadzenia użytkowników w błąd, pozostawiając poszkodowanych jako potencjalne ofiary oszustwa. Było kilka przypadków, w których złośliwe jettony były używane do podszywania się pod przelewy TON, błędy powiadomień, zarobki nagród lub ogłoszenia o zamrożeniu aktywów. +5. **Zawsze proszę zwracać uwagę na potencjalnych złośliwych aktorów**, którzy tworzą fałszywe jettony, zawsze dobrym pomysłem jest zapewnienie użytkownikom funkcji potrzebnych do wyeliminowania niechcianych jettonów w ich głównym interfejsie użytkownika. + +Autorami są [kosrk](https://github.com/kosrk), [krigga](https://github.com/krigga), [EmelyanenkoK](https://github.com/EmelyanenkoK/) i [tolya-yanot](https://github.com/tolya-yanot/). + +## Najlepsze praktyki + +Jeśli chcą Państwo przetestować gotowe przykłady, proszę sprawdzić [SDKs](/develop/dapps/asset-processing/jettons#sdks) i spróbować je uruchomić. Poniżej znajdują się fragmenty kodu, które pomogą Państwu zrozumieć przetwarzanie jettona poprzez przykłady kodu. + +### Proszę wysłać Jettons z komentarzem + + + + +
+ +Kod źródłowy + + +```js +// first 4 bytes are tag of text comment +const comment = new Uint8Array([... new Uint8Array(4), ... new TextEncoder().encode('text comment')]); + +await wallet.methods.transfer({ + secretKey: keyPair.secretKey, + toAddress: JETTON_WALLET_ADDRESS, // address of Jetton wallet of Jetton sender + amount: TonWeb.utils.toNano('0.05'), // total amount of TONs attached to the transfer message + seqno: seqno, + payload: await jettonWallet.createTransferBody({ + jettonAmount: TonWeb.utils.toNano('500'), // Jetton amount (in basic indivisible units) + toAddress: new TonWeb.utils.Address(WALLET2_ADDRESS), // recepient user's wallet address (not Jetton wallet) + forwardAmount: TonWeb.utils.toNano('0.01'), // some amount of TONs to invoke Transfer notification message + forwardPayload: comment, // text comment for Transfer notification message + responseAddress: walletAddress // return the TONs after deducting commissions back to the sender's wallet address + }), + sendMode: 3, +}).send() +``` + +
+ +
+ + +
+ +Kod źródłowy + + +```go +client := liteclient.NewConnectionPool() + +// connect to testnet lite server +err := client.AddConnectionsFromConfigUrl(context.Background(), "https://ton.org/global.config.json") +if err != nil { + panic(err) +} + +ctx := client.StickyContext(context.Background()) + +// initialize ton api lite connection wrapper +api := ton.NewAPIClient(client) + +// seed words of account, you can generate them with any wallet or using wallet.NewSeed() method +words := strings.Split("birth pattern then forest walnut then phrase walnut fan pumpkin pattern then cluster blossom verify then forest velvet pond fiction pattern collect then then", " ") + +w, err := wallet.FromSeed(api, words, wallet.V3R2) +if err != nil { + log.Fatalln("FromSeed err:", err.Error()) + return +} + +token := jetton.NewJettonMasterClient(api, address.MustParseAddr("EQD0vdSA_NedR9uvbgN9EikRX-suesDxGeFg69XQMavfLqIw")) + +// find our jetton wallet +tokenWallet, err := token.GetJettonWallet(ctx, w.WalletAddress()) +if err != nil { + log.Fatal(err) +} + +amountTokens := tlb.MustFromDecimal("0.1", 9) + +comment, err := wallet.CreateCommentCell("Hello from tonutils-go!") +if err != nil { + log.Fatal(err) +} + +// address of receiver's wallet (not token wallet, just usual) +to := address.MustParseAddr("EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N") +transferPayload, err := tokenWallet.BuildTransferPayload(to, amountTokens, tlb.ZeroCoins, comment) +if err != nil { + log.Fatal(err) +} + +// your TON balance must be > 0.05 to send +msg := wallet.SimpleMessage(tokenWallet.Address(), tlb.MustFromTON("0.05"), transferPayload) + +log.Println("sending transaction...") +tx, _, err := w.SendWaitTransaction(ctx, msg) +if err != nil { + panic(err) +} +log.Println("transaction confirmed, hash:", base64.StdEncoding.EncodeToString(tx.Hash)) +``` + +
+ +
+ + +
+ +Kod źródłowy + + +```py +my_wallet = Wallet(provider=client, mnemonics=my_wallet_mnemonics, version='v4r2') + +# for TonCenterClient and LsClient +await my_wallet.transfer_jetton(destination_address='address', jetton_master_address=jetton.address, jettons_amount=1000, fee=0.15) + +# for all clients +await my_wallet.transfer_jetton_by_jetton_wallet(destination_address='address', jetton_wallet='your jetton wallet address', jettons_amount=1000, fee=0.1) +``` + +
+ +
+ + + +
+ +Kod źródłowy + + +```py +from pytoniq import LiteBalancer, WalletV4R2, begin_cell +import asyncio + +mnemonics = ["your", "mnemonics", "here"] + +async def main(): + provider = LiteBalancer.from_mainnet_config(1) + await provider.start_up() + + wallet = await WalletV4R2.from_mnemonic(provider=provider, mnemonics=mnemonics) + USER_ADDRESS = wallet.address + JETTON_MASTER_ADDRESS = "EQBlqsm144Dq6SjbPI4jjZvA1hqTIP3CvHovbIfW_t-SCALE" + DESTINATION_ADDRESS = "EQAsl59qOy9C2XL5452lGbHU9bI3l4lhRaopeNZ82NRK8nlA" + + USER_JETTON_WALLET = (await provider.run_get_method(address=JETTON_MASTER_ADDRESS, + method="get_wallet_address", + stack=[begin_cell().store_address(USER_ADDRESS).end_cell().begin_parse()]))[0].load_address() + forward_payload = (begin_cell() + .store_uint(0, 32) # TextComment op-code + .store_snake_string("Comment") + .end_cell()) + transfer_cell = (begin_cell() + .store_uint(0xf8a7ea5, 32) # Jetton Transfer op-code + .store_uint(0, 64) # query_id + .store_coins(1 * 10**9) # Jetton amount to transfer in nanojetton + .store_address(DESTINATION_ADDRESS) # Destination address + .store_address(USER_ADDRESS) # Response address + .store_bit(0) # Custom payload is None + .store_coins(1) # Ton forward amount in nanoton + .store_bit(1) # Store forward_payload as a reference + .store_ref(forward_payload) # Forward payload + .end_cell()) + + await wallet.transfer(destination=USER_JETTON_WALLET, amount=int(0.05*1e9), body=transfer_cell) + await provider.close_all() + +asyncio.run(main()) +``` + +
+ +
+
+ +### Proszę zaakceptować Jetton Transfer z parsowaniem komentarzy + + + + +
+ +Kod źródłowy + + +```ts +import { + Address, + TonClient, + Cell, + beginCell, + storeMessage, + JettonMaster, + OpenedContract, + JettonWallet, + Transaction +} from '@ton/ton'; + + +export async function retry(fn: () => Promise, options: { retries: number, delay: number }): Promise { + let lastError: Error | undefined; + for (let i = 0; i < options.retries; i++) { + try { + return await fn(); + } catch (e) { + if (e instanceof Error) { + lastError = e; + } + await new Promise(resolve => setTimeout(resolve, options.delay)); + } + } + throw lastError; +} + +export async function tryProcessJetton(orderId: string) : Promise { + + const client = new TonClient({ + endpoint: 'https://toncenter.com/api/v2/jsonRPC', + apiKey: 'TONCENTER-API-KEY', // https://t.me/tonapibot + }); + + interface JettonInfo { + address: string; + decimals: number; + } + + interface Jettons { + jettonMinter : OpenedContract, + jettonWalletAddress: Address, + jettonWallet: OpenedContract + } + + const MY_WALLET_ADDRESS = 'INSERT-YOUR-HOT-WALLET-ADDRESS'; // your HOT wallet + + const JETTONS_INFO : Record = { + 'jUSDC': { + address: 'EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728', // + decimals: 6 + }, + 'jUSDT': { + address: 'EQBynBO23ywHy_CgarY9NK9FTz0yDsG82PtcbSTQgGoXwiuA', + decimals: 6 + }, + } + const jettons: Record = {}; + + const prepare = async () => { + for (const name in JETTONS_INFO) { + const info = JETTONS_INFO[name]; + const jettonMaster = client.open(JettonMaster.create(Address.parse(info.address))); + const userAddress = Address.parse(MY_WALLET_ADDRESS); + + const jettonUserAddress = await jettonMaster.getWalletAddress(userAddress); + + console.log('My jetton wallet for ' + name + ' is ' + jettonUserAddress.toString()); + + const jettonWallet = client.open(JettonWallet.create(jettonUserAddress)); + + //const jettonData = await jettonWallet; + const jettonData = await client.runMethod(jettonUserAddress, "get_wallet_data") + + jettonData.stack.pop(); //skip balance + jettonData.stack.pop(); //skip owneer address + const adminAddress = jettonData.stack.readAddress(); + + + if (adminAddress.toString() !== (Address.parse(info.address)).toString()) { + throw new Error('jetton minter address from jetton wallet doesnt match config'); + } + + jettons[name] = { + jettonMinter: jettonMaster, + jettonWalletAddress: jettonUserAddress, + jettonWallet: jettonWallet + }; + } + } + + const jettonWalletAddressToJettonName = (jettonWalletAddress : Address) => { + const jettonWalletAddressString = jettonWalletAddress.toString(); + for (const name in jettons) { + const jetton = jettons[name]; + + if (jetton.jettonWallet.address.toString() === jettonWalletAddressString) { + return name; + } + } + return null; + } + + // Subscribe + const Subscription = async ():Promise =>{ + + const client = new TonClient({ + endpoint: 'https://toncenter.com/api/v2/jsonRPC', + apiKey: 'TONCENTER-API-KEY', // https://t.me/tonapibot + }); + + const myAddress = Address.parse('INSERT-YOUR-HOT-WALLET'); // Address of receiver TON wallet + const transactions = await client.getTransactions(myAddress, { + limit: 5, + }); + return transactions; + } + + return retry(async () => { + + await prepare(); + const Transactions = await Subscription(); + + for (const tx of Transactions) { + + const sourceAddress = tx.inMessage?.info.src; + if (!sourceAddress) { + // external message - not related to jettons + continue; + } + + if (!(sourceAddress instanceof Address)) { + continue; + } + + const in_msg = tx.inMessage; + + if (in_msg?.info.type !== 'internal') { + // external message - not related to jettons + continue; + } + + // jetton master contract address check + const jettonName = jettonWalletAddressToJettonName(sourceAddress); + if (!jettonName) { + // unknown or fake jetton transfer + continue; + } + + if (tx.inMessage === undefined || tx.inMessage?.body.hash().equals(new Cell().hash())) { + // no in_msg or in_msg body + continue; + } + + const msgBody = tx.inMessage; + const sender = tx.inMessage?.info.src; + const originalBody = tx.inMessage?.body.beginParse(); + let body = originalBody?.clone(); + const op = body?.loadUint(32); + if (!(op == 0x7362d09c)) { + continue; // op != transfer_notification + } + + console.log('op code check passed', tx.hash().toString('hex')); + + const queryId = body?.loadUint(64); + const amount = body?.loadCoins(); + const from = body?.loadAddress(); + const maybeRef = body?.loadBit(); + const payload = maybeRef ? body?.loadRef().beginParse() : body; + const payloadOp = payload?.loadUint(32); + if (!(payloadOp == 0)) { + console.log('no text comment in transfer_notification'); + continue; + } + + const comment = payload?.loadStringTail(); + if (!(comment == orderId)) { + continue; + } + + console.log('Got ' + jettonName + ' jetton deposit ' + amount?.toString() + ' units with text comment "' + comment + '"'); + const txHash = tx.hash().toString('hex'); + return (txHash); + } + throw new Error('Transaction not found'); + }, {retries: 30, delay: 1000}); +} +``` + +
+ +
+ + +
+ +Kod źródłowy + + +```go +import ( + "context" + "fmt" + "log" + + "github.com/xssnick/tonutils-go/address" + "github.com/xssnick/tonutils-go/liteclient" + "github.com/xssnick/tonutils-go/tlb" + "github.com/xssnick/tonutils-go/ton" + "github.com/xssnick/tonutils-go/ton/jetton" + "github.com/xssnick/tonutils-go/tvm/cell" +) + +const ( + MainnetConfig = "https://ton.org/global.config.json" + TestnetConfig = "https://ton.org/global.config.json" + MyWalletAddress = "INSERT-YOUR-HOT-WALLET-ADDRESS" +) + +type JettonInfo struct { + address string + decimals int +} + +type Jettons struct { + jettonMinter *jetton.Client + jettonWalletAddress string + jettonWallet *jetton.WalletClient +} + +func prepare(api ton.APIClientWrapped, jettonsInfo map[string]JettonInfo) (map[string]Jettons, error) { + userAddress := address.MustParseAddr(MyWalletAddress) + block, err := api.CurrentMasterchainInfo(context.Background()) + if err != nil { + return nil, err + } + + jettons := make(map[string]Jettons) + + for name, info := range jettonsInfo { + jettonMaster := jetton.NewJettonMasterClient(api, address.MustParseAddr(info.address)) + jettonWallet, err := jettonMaster.GetJettonWallet(context.Background(), userAddress) + if err != nil { + return nil, err + } + + jettonUserAddress := jettonWallet.Address() + + jettonData, err := api.RunGetMethod(context.Background(), block, jettonUserAddress, "get_wallet_data") + if err != nil { + return nil, err + } + + slice := jettonData.MustCell(0).BeginParse() + slice.MustLoadCoins() // skip balance + slice.MustLoadAddr() // skip owneer address + adminAddress := slice.MustLoadAddr() + + if adminAddress.String() != info.address { + return nil, fmt.Errorf("jetton minter address from jetton wallet doesnt match config") + } + + jettons[name] = Jettons{ + jettonMinter: jettonMaster, + jettonWalletAddress: jettonUserAddress.String(), + jettonWallet: jettonWallet, + } + } + + return jettons, nil +} + +func jettonWalletAddressToJettonName(jettons map[string]Jettons, jettonWalletAddress string) string { + for name, info := range jettons { + if info.jettonWallet.Address().String() == jettonWalletAddress { + return name + } + } + return "" +} + +func GetTransferTransactions(orderId string, foundTransfer chan<- *tlb.Transaction) { + jettonsInfo := map[string]JettonInfo{ + "jUSDC": {address: "EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728", decimals: 6}, + "jUSDT": {address: "EQBynBO23ywHy_CgarY9NK9FTz0yDsG82PtcbSTQgGoXwiuA", decimals: 6}, + } + + client := liteclient.NewConnectionPool() + + cfg, err := liteclient.GetConfigFromUrl(context.Background(), MainnetConfig) + if err != nil { + log.Fatalln("get config err: ", err.Error()) + } + + // connect to lite servers + err = client.AddConnectionsFromConfig(context.Background(), cfg) + if err != nil { + log.Fatalln("connection err: ", err.Error()) + } + + // initialize ton api lite connection wrapper + api := ton.NewAPIClient(client, ton.ProofCheckPolicySecure).WithRetry() + master, err := api.CurrentMasterchainInfo(context.Background()) + if err != nil { + log.Fatalln("get masterchain info err: ", err.Error()) + } + + // address on which we are accepting payments + treasuryAddress := address.MustParseAddr("EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N") + + acc, err := api.GetAccount(context.Background(), master, treasuryAddress) + if err != nil { + log.Fatalln("get masterchain info err: ", err.Error()) + } + + jettons, err := prepare(api, jettonsInfo) + if err != nil { + log.Fatalln("can't prepare jettons data: ", err.Error()) + } + + lastProcessedLT := acc.LastTxLT + + transactions := make(chan *tlb.Transaction) + + go api.SubscribeOnTransactions(context.Background(), treasuryAddress, lastProcessedLT, transactions) + + log.Println("waiting for transfers...") + + // listen for new transactions from channel + for tx := range transactions { + if tx.IO.In == nil || tx.IO.In.MsgType != tlb.MsgTypeInternal { + // external message - not related to jettons + continue + } + + msg := tx.IO.In.Msg + sourceAddress := msg.SenderAddr() + + // jetton master contract address check + jettonName := jettonWalletAddressToJettonName(jettons, sourceAddress.String()) + if len(jettonName) == 0 { + // unknown or fake jetton transfer + continue + } + + if msg.Payload() == nil || msg.Payload() == cell.BeginCell().EndCell() { + // no in_msg body + continue + } + + msgBodySlice := msg.Payload().BeginParse() + + op := msgBodySlice.MustLoadUInt(32) + if op != 0x7362d09c { + continue // op != transfer_notification + } + + // just skip bits + msgBodySlice.MustLoadUInt(64) + amount := msgBodySlice.MustLoadCoins() + msgBodySlice.MustLoadAddr() + + payload := msgBodySlice.MustLoadMaybeRef() + payloadOp := payload.MustLoadUInt(32) + if payloadOp == 0 { + log.Println("no text comment in transfer_notification") + continue + } + + comment := payload.MustLoadStringSnake() + if comment != orderId { + continue + } + + // process transaction + log.Printf("Got %s jetton deposit %d units with text comment %s\n", jettonName, amount, comment) + foundTransfer <- tx + } +} +``` + +
+
+ + + +
+ +Kod źródłowy + + +```py +import asyncio + +from pytoniq import LiteBalancer, begin_cell + +MY_WALLET_ADDRESS = "EQAsl59qOy9C2XL5452lGbHU9bI3l4lhRaopeNZ82NRK8nlA" + + +async def parse_transactions(provider: LiteBalancer, transactions): + for transaction in transactions: + if not transaction.in_msg.is_internal: + continue + if transaction.in_msg.info.dest.to_str(1, 1, 1) != MY_WALLET_ADDRESS: + continue + + sender = transaction.in_msg.info.src.to_str(1, 1, 1) + value = transaction.in_msg.info.value_coins + if value != 0: + value = value / 1e9 + + if len(transaction.in_msg.body.bits) < 32: + print(f"TON transfer from {sender} with value {value} TON") + continue + + body_slice = transaction.in_msg.body.begin_parse() + op_code = body_slice.load_uint(32) + if op_code != 0x7362D09C: + continue + + body_slice.load_bits(64) # skip query_id + jetton_amount = body_slice.load_coins() / 1e9 + jetton_sender = body_slice.load_address().to_str(1, 1, 1) + if body_slice.load_bit(): + forward_payload = body_slice.load_ref().begin_parse() + else: + forward_payload = body_slice + + jetton_master = ( + await provider.run_get_method( + address=sender, method="get_wallet_data", stack=[] + ) + )[2].load_address() + jetton_wallet = ( + ( + await provider.run_get_method( + address=jetton_master, + method="get_wallet_address", + stack=[ + begin_cell() + .store_address(MY_WALLET_ADDRESS) + .end_cell() + .begin_parse() + ], + ) + )[0] + .load_address() + .to_str(1, 1, 1) + ) + + if jetton_wallet != sender: + print("FAKE Jetton Transfer") + continue + + if len(forward_payload.bits) < 32: + print( + f"Jetton transfer from {jetton_sender} with value {jetton_amount} Jetton" + ) + else: + forward_payload_op_code = forward_payload.load_uint(32) + if forward_payload_op_code == 0: + print( + f"Jetton transfer from {jetton_sender} with value {jetton_amount} Jetton and comment: {forward_payload.load_snake_string()}" + ) + else: + print( + f"Jetton transfer from {jetton_sender} with value {jetton_amount} Jetton and unknown payload: {forward_payload} " + ) + + print(f"Transaction hash: {transaction.cell.hash.hex()}") + print(f"Transaction lt: {transaction.lt}") + + +async def main(): + provider = LiteBalancer.from_mainnet_config(1) + await provider.start_up() + transactions = await provider.get_transactions(address=MY_WALLET_ADDRESS, count=5) + await parse_transactions(provider, transactions) + await provider.close_all() + + +if __name__ == "__main__": + asyncio.run(main()) +``` + +
+
+
+ +## SDK + +Listę SDK dla różnych języków (js, python, golang, C#, Rust itp.) można znaleźć [tutaj](/develop/dapps/apis/sdk). + +## Proszę zobaczyć również + +- [Przetwarzanie płatności](/develop/dapps/asset-processing/) +- [Przetwarzanie NFT na TON](/develop/dapps/asset-processing/nfts) +- [Parsowanie metadanych na TON](/develop/dapps/asset-processing/metadata) diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md b/i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md new file mode 100644 index 0000000000..8d21593c15 --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md @@ -0,0 +1,62 @@ +import Button from '@site/src/components/button' +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Przegląd przetwarzania zasobów + +Tutaj znajdą Państwo **krótki przegląd** [jak działają przelewy TON](/develop/dapps/asset-processing/overview#overview-on-messages-and-transactions), jakie [typy aktywów](/develop/dapps/asset-processing/overview#digital-asset-types-on-ton) można znaleźć w TON (i o czym będą Państwo czytać [next](/develop/dapps/asset-processing/overview#read-next)) oraz jak [wchodzić w interakcję z ton](/develop/dapps/asset-processing/overview#interaction-with-ton-blockchain) przy użyciu języka programowania, zalecamy zapoznanie się ze wszystkimi informacjami, które znajdą Państwo poniżej, przed przejściem do następnych stron. + +## Przegląd wiadomości i transakcji + +Ucieleśniając w pełni asynchroniczne podejście, TON Blockchain obejmuje kilka koncepcji, które są niespotykane w tradycyjnych blockchainach. W szczególności, każda interakcja dowolnego aktora z blockchainem składa się z grafu asynchronicznie przesyłanych [wiadomości] (/develop/smart-contracts/guidelines/message-delivery-guarantees) pomiędzy inteligentnymi kontraktami i/lub światem zewnętrznym. Każda transakcja składa się z jednej wiadomości przychodzącej i do 512 wiadomości wychodzących. + +Istnieją 3 rodzaje wiadomości, które są w pełni opisane [tutaj](/develop/smart-contracts/messages#types-of-messages). Krótko mówiąc: + +- [wiadomość zewnętrzna](/develop/smart-contracts/guidelines/external-messages): + - "Zewnętrzna wiadomość" (czasami nazywana po prostu "zewnętrzną wiadomością") to wiadomość, która jest wysyłana z *zewnątrz* blockchaina do inteligentnego kontraktu *wewnątrz* blockchaina. + - `external out message` (zwykle nazywana `logs message`) jest wysyłana z *blockchain entity* do *świata zewnętrznego*. +- [wiadomość wewnętrzna] (/develop/smart-contracts/guidelines/internal-messages) jest wysyłana z jednego podmiotu *blockchain* do *innego*, może zawierać pewną ilość zasobów cyfrowych i dowolną porcję danych. + +Wspólna ścieżka każdej interakcji rozpoczyna się od zewnętrznej wiadomości wysłanej do inteligentnego kontraktu `wallet`, który uwierzytelnia nadawcę wiadomości za pomocą kryptografii klucza publicznego, przejmuje opłatę i wysyła wewnętrzne wiadomości blockchain. Kolejka wiadomości tworzy kierunkowy graf acykliczny lub drzewo. + +Na przykład: + +![](/img/docs/asset-processing/alicemsgDAG.svg) + +- Alice`użyje np. [Tonkeeper](https://tonkeeper.com/), aby wysłać`zewnętrzną wiadomość\` do swojego portfela. +- `external message` to wiadomość wejściowa dla kontraktu `wallet A v4` z pustym źródłem (wiadomość znikąd, taka jak [Tonkeeper](https://tonkeeper.com/)). +- "Wiadomość wychodząca" to wiadomość wyjściowa dla kontraktu "Portfel A v4" i wiadomość wejściowa dla kontraktu "Portfel B v4" ze źródłem "Portfel A v4" i miejscem docelowym "Portfel B v4". + +W rezultacie istnieją 2 transakcje z zestawem komunikatów wejściowych i wyjściowych. + +Każda akcja, gdy umowa przyjmuje wiadomość jako dane wejściowe (wyzwalane przez nią), przetwarza ją i generuje lub nie generuje wiadomości wychodzących jako dane wyjściowe, zwane `transakcją`. Proszę przeczytać więcej o transakcjach [tutaj](/develop/smart-contracts/guidelines/message-delivery-guarantees#what-is-a-transaction). + +Te "transakcje" mogą obejmować **długi okres czasu**. Technicznie rzecz biorąc, transakcje z kolejkami wiadomości są agregowane w bloki przetwarzane przez walidatory. Asynchroniczny charakter TON Blockchain **nie pozwala przewidzieć hasha i lt (czasu logicznego) transakcji** na etapie wysyłania wiadomości. + +Transakcja zaakceptowana do bloku jest ostateczna i nie może być modyfikowana. + +:::info Potwierdzenie transakcji +Transakcje TON są nieodwracalne po jednym potwierdzeniu. Aby uzyskać najlepsze wrażenia użytkownika, zaleca się unikanie czekania na dodatkowe bloki po sfinalizowaniu transakcji na blockchainie TON. Więcej informacji znajdą Państwo w dokumencie [Catchain.pdf] (https://docs.ton.org/catchain.pdf#page=3). +::: + +Inteligentne kontrakty płacą kilka rodzajów [opłat](/develop/smart-contracts/fees) za transakcje (zwykle z salda przychodzącej wiadomości, zachowanie zależy od [trybu wiadomości](/develop/smart-contracts/messages#message-modes)). Wysokość opłat zależy od konfiguracji łańcucha roboczego z maksymalnymi opłatami na `masterchain` i znacznie niższymi opłatami na `basechain`. + +## Typy zasobów cyfrowych w TON + +TON posiada trzy rodzaje zasobów cyfrowych. + +- Toncoin, główny token sieci. Jest on używany do wszystkich podstawowych operacji na blockchainie, na przykład do uiszczania opłat za gaz lub stakowania w celu walidacji. +- Aktywa kontraktowe, takie jak tokeny i NFT, które są analogiczne do standardów ERC-20/ERC-721 i są zarządzane przez dowolne kontrakty, a zatem mogą wymagać niestandardowych reguł przetwarzania. Więcej informacji na temat ich przetwarzania znajdą Państwo w artykułach [process NFTs](/develop/dapps/asset-processing/nfts) i [process Jettons](/develop/dapps/asset-processing/jettons). +- Natywny token, który jest specjalnym rodzajem aktywów, które można dołączyć do dowolnej wiadomości w sieci. Aktywa te nie są jednak obecnie używane, ponieważ funkcja wydawania nowych tokenów natywnych jest zamknięta. + +## Interakcja z blockchainem TON + +Podstawowe operacje na TON Blockchain mogą być wykonywane za pośrednictwem TonLib. Jest to biblioteka współdzielona, którą można skompilować wraz z węzłem TON i udostępnić interfejsy API do interakcji z blockchainem za pośrednictwem tak zwanych serwerów lite (serwerów dla klientów lite). TonLib stosuje podejście bez zaufania, sprawdzając dowody dla wszystkich przychodzących danych; w związku z tym nie ma potrzeby korzystania z zaufanego dostawcy danych. Metody dostępne dla TonLib są wymienione [w schemacie TL] (https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L234). Mogą być one używane jako biblioteka współdzielona poprzez [wrappers](/develop/dapps/asset-processing/#repositories). + +## Czytaj dalej + +Po przeczytaniu tego artykułu mogą Państwo sprawdzić: + +1. [Przetwarzanie płatności](/develop/dapps/asset-processing/), aby dowiedzieć się, jak pracować z `TON coins`. +2. [Przetwarzanie Jetton](/develop/dapps/asset-processing/jettons), aby dowiedzieć się, jak pracować z `jettons` (czasami nazywanymi `tokens`). +3. [Przetwarzanie NFT](/develop/dapps/asset-processing/nfts), aby dowiedzieć się, jak pracować z `NFT` (czyli specjalnym typem `jetton`). diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx b/i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx new file mode 100644 index 0000000000..752bc83678 --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx @@ -0,0 +1,113 @@ +import Button from '@site/src/components/button' + +# Informacje o TON Connect + +TON Connect to potężny zestaw narzędzi open-source, który służy jako uniwersalny standard autoryzacji aplikacji w ekosystemie [TON](/learn/introduction), umożliwiając użytkownikom bezpieczne i wygodne logowanie się do aplikacji i usług za pomocą portfeli TON zamiast tradycyjnych loginów i haseł. + +![](/img/docs/ton-connect/ton-connect-overview.png?raw=true) + +Proszę użyć jednego z poniższych przepływów do integracji swojej aplikacji: + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Przypadki użycia dla Państwa DApp + +Proszę zapoznać się z tymi rezultatami, które ekosystem TON zapewnia dla doskonałej integracji DApp. + +- **Ruch**. Dodatkowe wizyty użytkowników za pośrednictwem portfeli kryptowalutowych obsługujących TON Connect. +- **Uwierzytelnianie**. Wykorzystaj portfele użytkowników TON jako gotowe konta, eliminując potrzebę dodatkowych kroków uwierzytelniania, a tym samym zwiększając komfort użytkowania. +- **Płatności**. Przetwarzaj transakcje szybko i bezpiecznie za pośrednictwem TON Blockchain za pomocą Toncoin lub owiniętych stabilnych monet (jUSDC / jUSDT). +- **Retencja**. Zwiększenie retencji użytkowników dzięki funkcji zapisywania listy w aplikacji, która pozwala użytkownikom śledzić ostatnio otwierane i ulubione aplikacje. + +## Dla deweloperów portfeli + +Jeśli są Państwo deweloperem portfela, mogą Państwo połączyć swój portfel z TON Connect i umożliwić swoim użytkownikom interakcję z aplikacjami TON w bezpieczny i wygodny sposób, proszę przeczytać jak [zintegrować TON Connect ze swoim portfelem](/develop/dapps/ton-connect/wallet/). + +## Historie sukcesu + +- [GetGems - The Open Network Marketplace](https://getgems.io/) +- [STON.fi - AMM DEX dla TON blockchain](https://ston.fi/) +- [Tonstarter](http://tonstarter.com/) + +
+ Pokaż całą listę + +- [getgems.io](https://getgems.io/) +- [fragment.com](https://fragment.com/) (Ton Connect v.1) +- [ston.fi](https://ston.fi/) +- [ton.diamonds](https://ton.diamonds/) +- [beta.disintar.io](https://beta.disintar.io/) +- [tegro.finance](https://tegro.finance/liquidity) +- [minter.ton.org](https://minter.ton.org/) +- [libermall.com](https://libermall.com/) +- [dedust.io](https://dedust.io/swap) +- [toncap.net](https://toncap.net/) +- [cryptomus.com](https://cryptomus.com/) +- [avanchange.com](https://avanchange.com/) +- [wton.dev](https://wton.dev/) +- [mint.spiroverse.io/shop](https://mint.spiroverse.io/shop) +- [vk.com/vk_nft_hub](https://vk.com/vk_nft_hub) +- [tonverifier.live](https://verifier.ton.org/) +- [stickerface.io/member](https://stickerface.io/member) +- [tonstarter.com](https://tonstarter.com/) +- [cryptogas.shop/ton](https://cryptogas.shop/ton) +- [megaton.fi](https://megaton.fi/) +- [dns.ton.org](https://dns.ton.org/) +- [coinpaymaster.com](https://coinpaymaster.com/) +- [ton.gagarin.world/app/](https://ton.gagarin.world/app) +- [daolama.co](https://daolama.co/) +- [marketplace.playmuse.org](http://marketplace.playmuse.org/) +- [ton.vote](https://ton.vote/) +- [plane.tonfancy.io](https://plane.tonfancy.io/) +- [pi.oberton.io](https://pi.oberton.io/) +- [business.thetonpay.app](https://business.thetonpay.app/) +- [bridge.orbitchain.io](https://bridge.orbitchain.io/) +- [connecton-web-new.vercel.app](https://connecton-web-new.vercel.app/) +- [app.fanz.ee/staking](https://app.fanz.ee/staking) +- [testnet.pton.fi](https://testnet.pton.fi/) +- [tonft.app](https://tonft.app/) +- [cardify.casino](https://cardify.casino/) +- [4riends.org](https://4riends.org/#/) +- [tonflex.fi](https://tonflex.fi/swap) +- [soquest.xyz](https://soquest.xyz/) +- [app.evaa.finance](https://app.evaa.finance/) + +
+ +## Dołącz do ekosystemu TON + +Aby połączyć swoją usługę z ekosystemem TON, należy wdrożyć następujące elementy: + +- **TON Connect**. Proszę włączyć protokół TON Connect do swojej aplikacji. +- **Transakcje**. Tworzenie określonych wiadomości transakcyjnych przy użyciu bibliotek TON. Proszę zagłębić się w proces [wysyłania wiadomości](/develop/dapps/ton-connect/message-builders) z naszym kompleksowym przewodnikiem. +- **Płatności**. Płatności można przetwarzać za pośrednictwem publicznego interfejsu API ([tonapi](https://tonapi.io/)) lub własnego indeksatora, na przykład [gobycicle](http://github.com/gobicycle/bicycle). Proszę dowiedzieć się więcej z naszego obszernego przewodnika na temat [asset processing](/develop/dapps/asset-processing). diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/develop/fift/overview.mdx b/i18n/pl/docusaurus-plugin-content-docs/current/develop/fift/overview.mdx new file mode 100644 index 0000000000..8be16cb2ea --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/develop/fift/overview.mdx @@ -0,0 +1,57 @@ +import Button from '@site/src/components/button' + +# Przegląd + +Fift to oparty na stosie język programowania ogólnego przeznaczenia zoptymalizowany pod kątem tworzenia, debugowania i zarządzania inteligentnymi kontraktami TON Blockchain. +Fift został specjalnie zaprojektowany do interakcji z maszyną wirtualną TON (TON VM lub TVM) i TON Blockchain. + +```fift +{ ."hello " } execute ."world" +hello world ok +``` + +:::info +Zazwyczaj używanie języka Fift nie jest wymagane do programowania inteligentnych kontraktów w TON. Czasami jednak może być konieczne użycie języka Fift w celu rozwiązania nietypowych wyzwań technicznych w ramach zadania. +::: + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +



+ +## Dokumentacja + +- [Fift: A Brief Introduction](https://ton.org/fiftbase.pdf) +- [Maszyna wirtualna TON](/learn/tvm-instructions/tvm-overview) + +## Przykłady + +- [Przykłady inteligentnych umów Fift](/develop/smart-contracts/examples#fift-smart-contracts) + +## Samouczki + +- [Introduction To Fift](https://blog.ton.org/introduction-to-fift) +- [\[YouTube\]His majesty Fift](https://www.youtube.com/watch?v=HVsveTmVowc&list=PLtUBO1QNEKwttRsAs9eacL2oCMOhWaOZs) \[[RU version](https://www.youtube.com/playlist?list=PLyDBPwv9EPsCYG-hR4N5FRTKUkfM8POgh)] by **@MarcoDaTr0p0je** & **@Wikimar**. + +## Źródła + +- [Pięć skryptów dla standardowych inteligentnych kontraktów](https://github.com/ton-blockchain/ton/tree/master/crypto/smartcont) diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/develop/func/overview.mdx b/i18n/pl/docusaurus-plugin-content-docs/current/develop/func/overview.mdx new file mode 100644 index 0000000000..870efded52 --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/develop/func/overview.mdx @@ -0,0 +1,157 @@ +import Button from '@site/src/components/button' + +# Przegląd + +Język wysokiego poziomu FunC jest używany do programowania inteligentnych kontraktów w TON. + +FunC jest specyficznym dla domeny, podobnym do C, statycznie typowanym językiem. +Poniżej znajduje się prosta przykładowa metoda wysyłania pieniędzy napisana w FunC: + +```func +() send_money(slice address, int amount) impure inline { + var msg = begin_cell() + .store_uint(0x10, 6) ;; nobounce + .store_slice(address) + .store_coins(amount) + .end_cell(); + + send_raw_message(msg, 64); +} +``` + +Programy FunC są kompilowane do kodu asemblera Fift, który generuje odpowiedni kod bajtowy dla [TON Virtual Machine] (/learn/tvm-instructions/tvm-overview). + +Ponadto ten kod bajtowy (w rzeczywistości [drzewo komórek] (/learn/overviews/cells), jak każde inne dane w TON Blockchain) może być wykorzystywany do tworzenia inteligentnych kontraktów w łańcuchu bloków lub może być uruchamiany w lokalnej instancji TVM. + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Kompilator + +### Kompilacja z JS + +Najwygodniejszym i najszybszym sposobem na rozpoczęcie tworzenia i kompilowania inteligentnych kontraktów jest użycie frameworka Blueprint. Więcej informacji znajdą Państwo w sekcji [Blueprint](/develop/smart-contracts/sdk/javascript). + +```bash +npm create ton@latest +``` + +### Kompilacja z oryginalnymi plikami binarnymi + +Jeśli chcą Państwo używać natywnego kompilatora TON FunC lokalnie, potrzebne są binaria zainstalowane na Państwa komputerze. Binaria kompilatora FunC dla systemów Windows, MacOS (Intel/M1) i Ubuntu można pobrać ze strony: + +- [Strona konfiguracji środowiska](/develop/smart-contracts/environment/installation) + +:::info +Jednocześnie zawsze można utworzyć pliki binarne ze źródeł, np:\ +[kod źródłowy kompilatora FunC](https://github.com/ton-blockchain/ton/tree/master/crypto/func) (proszę przeczytać [jak skompilować](/develop/howto/compile#func) kompilator FunC ze źródeł). +::: + +## Kurs TON: FunC + +Kurs [TON Blockchain Course] (https://stepik.org/course/176754/) to kompleksowy przewodnik po rozwoju TON Blockchain. + +Moduł 4 w całości obejmuje język FunC i rozwój inteligentnych kontraktów. + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Samouczki + +:::tip wskazówka dla początkujących +Najlepsze miejsce do rozpoczęcia programowania przy użyciu FunC: [WPROWADZENIE](/develop/smart-contracts/) +::: + +Inne materiały zostały z wdzięcznością dostarczone przez ekspertów ze społeczności: + +- [Seria TON Speed Run](https://tonspeedrun.com/) + - [🚩 Wyzwanie 1: Proste wdrożenie NFT](https://github.com/romanovichim/TONQuest1) + - [🚩 Wyzwanie 2: Umowa z Chatbotem](https://github.com/romanovichim/TONQuest2) + - [🚩 Wyzwanie 3: Automat Jetton](https://github.com/romanovichim/TONQuest3) + - [🚩 Wyzwanie 4: Loteria/Rafle](https://github.com/romanovichim/TONQuest4) + - [🚩 Wyzwanie 5: Stworzenie interfejsu użytkownika do interakcji z umową w 5 minut](https://github.com/romanovichim/TONQuest5) + - [🚩 Wyzwanie 6: Analiza sprzedaży NFT na rynku Getgems](https://github.com/romanovichim/TONQuest6) + + + +- [Func & Blueprint](https://www.youtube.com/watch?v=7omBDfSqGfA&list=PLtUBO1QNEKwtO_zSyLj-axPzc9O9rkmYa) by **@MarcoDaTr0p0je**. +- [Naucz się FunC w Y minut](https://learnxinyminutes.com/docs/func/) by **@romanowiczim** +- [TON Hello World: Przewodnik krok po kroku, jak napisać swój pierwszy inteligentny kontrakt](https://ton-community.github.io/tutorials/02-contract/) +- [TON Hello World: Przewodnik krok po kroku dotyczący testowania pierwszego inteligentnego kontraktu](https://ton-community.github.io/tutorials/04-testing/) +- [10 FunC Lessons](https://github.com/romanovichim/TonFunClessons_Eng) by **@romanovichim**, using blueprint +- [10 lekcji FunC (RU)](https://github.com/romanovichim/TonFunClessons_ru) przez **@romanovichim**, używając blueprintu +- [FunC Quiz](https://t.me/toncontests/60) by **Vadim** - Dobry do samodzielnego sprawdzenia. Zajmie to 10-15 minut. Pytania dotyczą głównie FunC z kilkoma ogólnymi pytaniami o TON +- [FunC Quiz (RU)](https://t.me/toncontests/58?comment=14888) by **Vadim** - FunC Quiz po rosyjsku + +## Konkursy + +Udział w [konkursach](https://t.me/toncontests) to świetny sposób na naukę FunC. + +Mogą Państwo również zapoznać się z poprzednimi konkursami w celach edukacyjnych. + +#### Konkursy Dziedzictwo + +| Opis konkursu | Zadania | Rozwiązania | +| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| TSC #5 (grudzień 2023 r.) | [Zadania](https://github.com/ton-community/tsc5) | | +| TSC #4 (wrzesień 2023 r.) | [Zadania](https://github.com/ton-community/tsc4) | [Rozwiązania](/develop/smart-contracts/examples#ton-smart-challenge-4) | +| TSC #3 (grudzień 2022 r.) | [Zadania](https://github.com/ton-blockchain/func-contest3) | [Rozwiązania](https://github.com/nns2009/TON-FunC-contest-3) | +| TSC #2 (lipiec 2022 r.) | [Zadania](https://github.com/ton-blockchain/func-contest2) | [Rozwiązania](https://github.com/ton-blockchain/func-contest2-solutions) | +| TSC #1 (marzec, 2022) | [Zadania](https://github.com/ton-blockchain/func-contest1) | [Rozwiązania](https://github.com/ton-blockchain/func-contest1-solutions) | + +## Przykłady inteligentnych kontraktów + +Standardowe podstawowe inteligentne kontrakty, takie jak portfele, elektorzy (zarządza walidacją w TON), portfele z wieloma podpisami itp. mogą być punktem odniesienia podczas nauki. + +- [Przykłady inteligentnych kontraktów](/develop/smart-contracts/examples) + +## Dziennik zmian + +[Historia aktualizacji funC](/develop/func/changelog). diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/develop/overview.mdx b/i18n/pl/docusaurus-plugin-content-docs/current/develop/overview.mdx new file mode 100644 index 0000000000..bbfeb710c2 --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/develop/overview.mdx @@ -0,0 +1,207 @@ +import Button from '@site/src/components/button' +import Player from '@site/src/components/player' + +# Dokumentacja TON + +Witamy w oficjalnej dokumentacji deweloperskiej TON Blockchain! + +Niniejszy zasób ma na celu dostarczenie Państwu wszystkich niezbędnych informacji potrzebnych do tworzenia, testowania i wdrażania aplikacji na blockchainie TON. + +Jest to wspólna inicjatywa open-source, a wkład jest zawsze mile widziany. Całą dokumentację można edytować za pośrednictwem GitHub, wystarczy [postępować zgodnie z tymi instrukcjami](/contribute). + +- Seria _TON Hello World_ zawiera szczegółowe przewodniki krok po kroku dotyczące portfeli, inteligentnych kontraktów, miniaplikacji oraz testowania i debugowania inteligentnych kontraktów w TON. +- _Get Started with TON_ to przewodnik krok po kroku dotyczący interakcji z TON Blockchain. (dołączony samouczek wideo) + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +### Podstawy blockchain z TON + +Ten kurs wprowadza w podstawy blockchain, ze szczególnym naciskiem na praktyczne umiejętności w ekosystemie TON. Zrozumieją Państwo, jak działa blockchain i jakie są jego różnorodne zastosowania. + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +### Kurs TON + +Z dumą prezentujemy **TON Blockchain Course**, który jest kompleksowym przewodnikiem po TON Blockchain. Kurs jest przeznaczony dla programistów, którzy chcą dowiedzieć się, jak tworzyć inteligentne kontrakty i zdecentralizowane aplikacje na TON Blockchain w angażujący i interaktywny sposób. + +Składa się on z **9 modułów** i obejmuje podstawy TON Blockchain, języka programowania FunC oraz TON Virtual Machine (TVM). + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Moduły rozwoju + +Jeśli są Państwo nowicjuszami w rozwoju TON Blockchain, zaleca się rozpoczęcie od początku i przejście przez te tematy. + +### Podstawowe pojęcia + +- [The Open Network](/learn/introduction) - Ogólny przegląd TON Blockchain. +- [Blockchain of Blockchains](/learn/overviews/ton-blockchain) - praktyczne wyjaśnienie TON Blockchain. +- [Smart Contract Addresses](/learn/overviews/addresses) - Szczegółowe wyjaśnienie adresów. +- [Komórki jako struktura danych](/learn/overviews/cells) - Wysokopoziomowe wyjaśnienie struktur danych. +- [TON Networking](/learn/networking/overview) - Ogólny przegląd protokołów TON peer-to-peer. +- [TON Virtual Machine (TVM)](/learn/tvm-instructions/tvm-overview) - Ogólny przegląd TON Virtual Machine. +- [Transakcje i fazy](/learn/tvm-instructions/tvm-overview#transactions-and-phases) - Szczegółowe wyjaśnienie transakcji i faz. +- [Opłaty transakcyjne](/develop/smart-contracts/fees) - Ogólne wyjaśnienie opłat transakcyjnych. + +### Infrastruktura + +- [Typy węzłów](/participate/nodes/node-types) - Szczegółowe wyjaśnienie typów węzłów. +- [Uruchom pełny węzeł](/participate/run-nodes/full-node) - Szczegółowe wyjaśnienie, jak uruchomić węzeł. +- [TON DNS & Sites](/participate/web3/dns) - Szczegółowe wyjaśnienie TON DNS & Sites. +- [TON Storage](/participate/ton-storage/storage-daemon) - Szczegółowe wyjaśnienie TON Storage. + +### Dodatkowe zasoby + +- [**FAQ**](/develop/howto/faq) - Często zadawane pytania +- [Dokumentacja FunC](/develop/func/overview) +- [Dokumentacja Fift](/develop/fift/overview) + +## Rozwój inteligentnych kontraktów + +Inteligentne kontrakty są elementami składowymi zdecentralizowanych aplikacji (DApps) na TON Blockchain. Jeśli chcą Państwo rozwijać własne dApps, ważne jest, aby zrozumieć, jak działają inteligentne kontrakty. + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +



+ +Poniższe zasoby dostarczają cennych informacji dla rozwoju inteligentnych kontraktów TON: + +- [TON Hello World: Przewodnik krok po kroku, jak napisać swój pierwszy inteligentny kontrakt](https://ton-community.github.io/tutorials/02-contract/) - Przystępne i zwięzłe wyjaśnienie podstaw JS. +- [Jak pracować z inteligentnymi kontraktami portfela](/develop/smart-contracts/tutorials/wallet) - Szczegółowe i staranne wyjaśnienia podstaw inteligentnych kontraktów z wykorzystaniem JS i GO. +- [Nauka inteligentnych kontraktów na przykładach](/develop/smart-contracts/examples) (FunC, Fift) +- [Speed Run TON](/develop/smart-contracts/examples) - 6 interaktywnych wyzwań i samouczków krok po kroku do nauki tworzenia inteligentnych kontraktów. + +## Rozwój aplikacji + +Aplikacje zdecentralizowane (DApps) to aplikacje, które działają w sieci komputerów peer-to-peer, a nie na jednym komputerze (TON Blockchain). Są one podobne do tradycyjnych aplikacji internetowych, ale są zbudowane na szczycie sieci blockchain. Oznacza to, że DApps są zdecentralizowane, co oznacza, że żaden pojedynczy podmiot ich nie kontroluje. + +```mdx-code-block + +``` + +### DeFi Development + +- [TON Connect](/develop/dapps/ton-connect/overview) - integracja i uwierzytelnianie dla DApps. +- [Przetwarzanie płatności poza łańcuchem](/develop/dapps/asset-processing) - przykłady i koncepcje przetwarzania płatności. +- [Przetwarzanie TON Jetton](/develop/dapps/asset-processing/jettons) - przykłady i koncepcje przetwarzania Jettonów. +- [Fungible (FT) / Non-fungible (NFT) tokeny](/develop/dapps/defi/tokens) - inteligentne kontrakty, przykłady, narzędzia + +Proszę postawić pierwsze kroki w rozwoju DApps dzięki kompleksowemu przewodnikowi tworzenia DApps: + +- [TON Hello World: Przewodnik krok po kroku, jak zbudować swojego pierwszego klienta sieciowego](https://ton-community.github.io/tutorials/03-client/) +- [Integracja z botem Telegram za pośrednictwem TON Connect](/develop/dapps/ton-connect/tg-bot-integration) + +### API i SDK + +- [API](/develop/dapps/apis) +- [SDKs](/develop/dapps/apis/sdk) + +## Często zadawane pytania + +Proszę przejść do sekcji [Często zadawane pytania](/develop/howto/faq). diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/develop/smart-contracts/testing/overview.mdx b/i18n/pl/docusaurus-plugin-content-docs/current/develop/smart-contracts/testing/overview.mdx new file mode 100644 index 0000000000..c3aa30fefc --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/develop/smart-contracts/testing/overview.mdx @@ -0,0 +1,141 @@ +# Pisanie testów za pomocą Blueprint + +## Przegląd + +Zestaw narzędzi testowych (zwykle piaskownica) jest już zawarty w TypeScript SDK o nazwie [Blueprint](/develop/smart-contracts/sdk/javascript). Mogą Państwo utworzyć projekt demonstracyjny i uruchomić domyślny test w dwóch krokach: + +1. Proszę utworzyć nowy projekt Blueprint: + +```bash +npm create ton@latest MyProject +``` + +2. Proszę przeprowadzić test: + +```bash +cd MyProject +npx blueprint test +``` + +W rezultacie zobaczą Państwo odpowiednie dane wyjściowe w oknie terminala: + +```bash +% npx blueprint test + +> MyProject@0.0.1 test +> jest + + PASS tests/Main.spec.ts + Main + ✓ should deploy (127 ms) + +Test Suites: 1 passed, 1 total +Tests: 1 passed, 1 total +Snapshots: 0 total +Time: 1.224 s, estimated 2 s +Ran all test suites. +``` + +## Użycie podstawowe + +Testowanie inteligentnych kontraktów pozwala na pokrycie bezpieczeństwa, optymalizację wydatków na gaz i badanie przypadków brzegowych. +Pisanie testów w Blueprint (w oparciu o [Sandbox](https://github.com/ton-org/sandbox)) polega na definiowaniu dowolnych działań z kontraktem i porównywaniu wyników testów z oczekiwanym rezultatem, na przykład: + +```typescript +it('should execute with success', async () => { // description of the test case + const res = await main.sendMessage(sender.getSender(), toNano('0.05')); // performing an action with contract main and saving result in res + + expect(res.transactions).toHaveTransaction({ // configure the expected result with expect() function + from: main.address, // set expected sender for transaction we want to test matcher properties from + success: true // set the desirable result using matcher property success + }); + + printTransactionFees(res.transactions); // print table with details on spent fees +}); +``` + +### Pisanie testów dla złożonych twierdzeń + +Podstawowy proces tworzenia testu wygląda następująco: + +1. Proszę utworzyć konkretny opakowany podmiot `Contract` za pomocą `blockchain.openContract()`. +2. Proszę opisać akcje, które ma wykonać `Contract` i zapisać wynik wykonania w zmiennej `res`. +3. Proszę zweryfikować właściwości za pomocą funkcji `expect()` i matchera `toHaveTransaction()`. + +Matcher `toHaveTransaction` oczekuje obiektu z dowolną kombinacją pól z typu `FlatTransaction` zdefiniowanego z następującymi właściwościami + +| Nazwa | Typ | Opis | +| -------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| z | Adres? | Adres umowy nadawcy wiadomości | +| na | Adres | Adres umowny miejsca docelowego wiadomości (Alternatywna nazwa właściwości `to`). | +| wartość | bigint? | Ilość toncoinów w wiadomości w nanotonach | +| ciało | Komórka | Treść wiadomości zdefiniowana jako komórka | +| op | numer? | Op code to numer identyfikatora operacji (zazwyczaj crc32 z TL-B). Oczekiwany w pierwszych 32 bitach treści wiadomości. | +| sukces | boolean? | Niestandardowa flaga Sandbox, która definiuje wynikowy status określonej transakcji. True - jeśli zarówno faza obliczeniowa, jak i faza działania zakończyły się powodzeniem. W przeciwnym razie - False. | + +Mogą Państwo pominąć pola, które Państwa nie interesują i przekazać funkcje akceptujące typy zwracające wartości logiczne (`true` oznacza dobre), aby sprawdzić np. zakresy liczb, kody operacyjne wiadomości itp. Proszę zauważyć, że jeśli pole jest opcjonalne (jak `from?: Address`), to funkcja musi również akceptować opcjonalny typ. + +:::tip +Pełną listę pól matchera można znaleźć w [dokumentacji Sandbox] (https://github.com/ton-org/sandbox#test-a-transaction-with-matcher). +::: + +### Konkretny zestaw testów + +#### Extract SendMode + +Aby wyodrębnić tryb wysyłania wysłanej wiadomości, można użyć następującego kodu: + +```ts + +const smc = await blockchain.getContract(addr); + +const re = blockchain.executor.runTransaction({ + config: blockchain.configBase64, libs: null, verbosity: 'full', + now: Math. floor (Date.now) / 1000), + lt: BigInt(Date.now()), + randomSeed: null, + ignoreChksig: false, + debugEnabled: true, + shardAccount: beginCell() + .store (storeShardAccount (smc.account)) + .endCell() + .toBoc() + .toString('base64'), + message: beginCell() + .store (storeMessageRelaxed (...)) + .endCell(), +}); + +if (!re.result. success || !re.result.actions) { + throw new Error('fail'); +} +const actions = loadoutList(Cell.fromBase64(re.result.actions).beginParse()); +actions[0].type === 'sendMsg' && actions[0].mode; + +``` + +## Samouczki + +Dowiedz się więcej o testowaniu z najbardziej wartościowych samouczków społeczności na TON: + +- [Lekcja 2: Testowanie FunC dla inteligentnego kontraktu](https://github.com/romanovichim/TonFunClessons_Eng/blob/main/lessons/smartcontract/2lesson/secondlesson.md) +- [TON Hello World część 4: Przewodnik krok po kroku dotyczący testowania pierwszego inteligentnego kontraktu](https://ton-community.github.io/tutorials/04-testing/) +- [TON Smart Contract Pipeline](https://dev.to/roma_i_m/ton-smart-contract-pipeline-write-simple-contract-and-compile-it-4pnh) +- [YouTube]Szósta lekcja FunC & Blueprint. Gaz, opłaty, testy.](https://youtu.be/3XIpKZ6wNcg) + +## Przykłady + +Proszę sprawdzić zestawy testowe używane dla kontraktów TON Ecosystem i uczyć się na przykładach. + +- [liquid-staking-contract sandbox tests](https://github.com/ton-blockchain/liquid-staking-contract/tree/main/tests) +- [governance_tests](https://github.com/Trinketer22/governance_tests/blob/master/config_tests/tests/) +- [JettonWallet.spec.ts](https://github.com/EmelyanenkoK/modern_jetton/blob/master/tests/JettonWallet.spec.ts) +- [governance_tests](https://github.com/Trinketer22/governance_tests/blob/master/elector_tests/tests/complaint-test.fc) +- [MassSender.spec.ts](https://github.com/Gusarich/ton-mass-sender/blob/main/tests/MassSender.spec.ts) +- [TonForwarder.spec.ts](https://github.com/TrueCarry/ton-contract-forwarder/blob/main/src/contracts/ton-forwarder/TonForwarder.spec.ts) +- [Assurer.spec.ts](https://github.com/aSpite/dominant-assurance-contract/blob/main/tests/Assurer.spec.ts) + +## Proszę zobaczyć również + +- [Blueprint](/develop/smart-contracts/sdk/javascript) +- [toncli](/develop/smart-contracts/testing/toncli) diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/learn/academy/academy-overview.md b/i18n/pl/docusaurus-plugin-content-docs/current/learn/academy/academy-overview.md new file mode 100644 index 0000000000..8a42204f46 --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/learn/academy/academy-overview.md @@ -0,0 +1,16 @@ +# Zasoby edukacyjne + +### TON Speedrun + +- [TON Speedrun](https://tonspeedrun.com/) - Specjalistyczna platforma zaprojektowana z myślą o praktycznym podejściu do nauki rozwoju TON. + +### Kursy + +- [Podstawy blockchain z TON](https://stepik.org/course/201294/promo) ([wersja RU](https://stepik.org/course/202221/), [wersja CHN](https://stepik.org/course/200976/)) - + Kurs ten wprowadza w podstawy blockchain, ze szczególnym naciskiem na praktyczne umiejętności w ekosystemie TON. Zrozumieją Państwo, jak działa blockchain i jakie są jego różnorodne zastosowania. + +## Proszę zobaczyć również + +- [Speedrun TON](https://tonspeedrun.com/) +- [TON Hello World](https://tonhelloworld.com/01-wallet/) +- [[YouTube] TON Dev Study PL ](https://www.youtube.com/@TONDevStudy)[[RU]](https://www.youtube.com/results?search_query=tondevstudy) diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/learn/introduction.mdx b/i18n/pl/docusaurus-plugin-content-docs/current/learn/introduction.mdx new file mode 100644 index 0000000000..008ea5d2e1 --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/learn/introduction.mdx @@ -0,0 +1,81 @@ +import Player from '@site/src/components/player' +import Button from '@site/src/components/button' + +# Otwarta sieć + +**The Open Network (TON)** to zdecentralizowana i otwarta platforma internetowa składająca się z kilku komponentów. Należą do nich: TON Blockchain, TON DNS, TON Storage i TON Sites. TON Blockchain jest podstawowym protokołem, który łączy podstawową infrastrukturę TON, tworząc większy ekosystem TON. + +TON koncentruje się na osiągnięciu szerokiej interoperacyjności międzyłańcuchowej, działając jednocześnie w wysoce skalowalnej, bezpiecznej strukturze. TON został zaprojektowany do przetwarzania milionów transakcji na sekundę (TPS), a jego celem jest osiągnięcie setek milionów użytkowników. + +**TON Blockchain** został zaprojektowany jako rozproszony superkomputer lub "superserwer", mający na celu dostarczanie różnorodnych produktów i usług, aby przyczynić się do rozwoju zdecentralizowanej wizji nowego Internetu. + +- Proszę dowiedzieć się, jakie usługi TON zapewnia swoim użytkownikom, przeglądając tę sekcję: [Uczestnictwo w TON](/uczestnictwo/). +- Aby dowiedzieć się więcej o technicznych aspektach TON Blockchain, proszę zapoznać się z [Blockchain of Blockchains] (/learn/overviews/ton-blockchain). +- Proszę dowiedzieć się więcej o rozwoju wszystkich rzeczy związanych z TON, przeglądając tę sekcję: [Pierwsze kroki](/develop/overview). + +## Przegląd z lotu ptaka + +Aby zrozumieć prawdziwą wizję zdecentralizowanego Internetu i tego, w jaki sposób TON przyczynia się do tej nieuchronności, proszę zapoznać się z poniższym filmem: + + + +## Podstawy blockchain z TON + +Ten kurs wprowadza w podstawy blockchain, ze szczególnym naciskiem na praktyczne umiejętności w ekosystemie TON. Zrozumieją Państwo, jak działa blockchain i jego różnorodne zastosowania. Zdobędą Państwo również kluczowe umiejętności związane z TON, w tym konfigurację portfela, handel NFT, tworzenie Jetton i transakcje z monetami TON na zdecentralizowanych giełdach (DEX). Kurs wyposaży Państwa również w krytyczną wiedzę na temat zagrożeń i oszustw związanych z kryptowalutami oraz udzieli praktycznych wskazówek, jak chronić swoje aktywa kryptograficzne. + +- [Podstawy Blockchain z TON](https://stepik.org/course/201294/) ([wersja RU](https://stepik.org/course/202221/), [wersja CHN](https://stepik.org/course/200976/)) + +## Kurs TON Blockchain + +Z dumą prezentujemy **TON Blockchain Course**, który jest kompleksowym przewodnikiem po TON Blockchain. Kurs jest przeznaczony dla programistów, którzy chcą dowiedzieć się, jak tworzyć inteligentne kontrakty i zdecentralizowane aplikacje na TON Blockchain. + +Składa się on z **9 modułów** i obejmuje podstawy TON Blockchain, języka programowania FunC oraz TON Virtual Machine (TVM). + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Nowy w Blockchain? + +Jeśli są Państwo nowicjuszami w dziedzinie blockchain i nie rozumieją, co sprawia, że technologia ta jest tak rewolucyjna - proszę rozważyć zapoznanie się z tymi ważnymi zasobami: + +- [Co to jest Blockchain? Co to jest Smart Contract? Co to jest Gas?](https://blog.ton.org/what_is_blockchain) +- [Jak Blockchain może pomóc Państwu na bezludnej wyspie](https://talkol.medium.com/why-decentralized-consensus-blockchain-is-good-for-business-5ff263468210) +- [YouTube] Crypto Networks and Why They Matter](https://youtu.be/2wxtiNgXBaU) + +## Związek TON z Ethereum + +Dla osób zaznajomionych z rozwojem Ethereum napisaliśmy dwa artykuły wprowadzające, które pomogą Państwu zrozumieć, co wyróżnia TON w tym zakresie: + +- [Sześć unikalnych aspektów TON Blockchain, które zaskoczą deweloperów Solidity](https://blog.ton.org/six-unique-aspects-of-ton-blockchain-that-will-surprise-solidity-developers) +- [Czas wypróbować coś nowego: asynchroniczne inteligentne kontrakty](https://telegra.ph/Its-time-to-try-something-new-Asynchronous-smart-contracts-03-25). +- [Porównanie łańcuchów bloków](https://ton.org/comparison_of_blockchains.pdf) diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/learn/networking/overview.md b/i18n/pl/docusaurus-plugin-content-docs/current/learn/networking/overview.md new file mode 100644 index 0000000000..992d6e3f22 --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/learn/networking/overview.md @@ -0,0 +1,19 @@ +# TON Networking + +Projekt TON wykorzystuje własne protokoły sieciowe peer-to-peer. + +- **TON Blockchain wykorzystuje te protokoły** do propagacji nowych bloków, wysyłania i zbierania kandydatów do transakcji i tak dalej. + + Podczas gdy wymagania sieciowe projektów single-blockchain, takich jak Bitcoin czy Ethereum, można spełnić dość łatwo (zasadniczo trzeba zbudować + sieć nakładkową peer-to-peer, a następnie propagować wszystkie nowe bloki i + kandydatów do transakcji za pośrednictwem protokołu [gossip](https://en.wikipedia.org/wiki/Gossip_protocol)), podczas gdy projekty multi-blockchain, takie + jak TON, są znacznie bardziej wymagające (np. trzeba być w stanie + subskrybować aktualizacje tylko niektórych shardchainów, niekoniecznie wszystkich). + +- \*\*Usługi ekosystemu TON (np. TON Proxy, TON Sites, TON Storage) działają w oparciu o te protokoły. + + Po wprowadzeniu bardziej wyrafinowanych protokołów sieciowych potrzebnych + do obsługi TON Blockchain, okazuje się, że można je łatwo + wykorzystać do celów niekoniecznie związanych z bezpośrednimi wymaganiami samego blockchaina + , zapewniając w ten sposób większe możliwości i elastyczność tworzenia + nowych usług w ekosystemie TON. diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/learn/overviews/addresses.md b/i18n/pl/docusaurus-plugin-content-docs/current/learn/overviews/addresses.md new file mode 100644 index 0000000000..3c8f3c9902 --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/learn/overviews/addresses.md @@ -0,0 +1,220 @@ +# Adresy inteligentnych kontraktów + +Ta sekcja opisuje specyfikę adresów inteligentnych kontraktów na blockchainie TON. Wyjaśnimy również, w jaki sposób aktorzy są synonimami inteligentnych kontraktów na TON. + +## Wszystko jest inteligentnym kontraktem + +W TON inteligentne kontrakty są budowane przy użyciu modelu [Actor model](/learn/overviews/ton-blockchain#single-actor). W rzeczywistości aktorzy w TON są technicznie reprezentowani jako inteligentne kontrakty. Oznacza to, że nawet Państwa portfel jest prostym aktorem (i inteligentnym kontraktem). + +Zazwyczaj aktorzy przetwarzają przychodzące wiadomości, zmieniają swój stan wewnętrzny i w rezultacie generują wiadomości wychodzące. Dlatego też każdy aktor (tj. inteligentny kontrakt) na blockchainie TON musi mieć adres, aby móc odbierać wiadomości od innych aktorów. + +:::info DOŚWIADCZENIE Z EVM +W maszynie wirtualnej Ethereum (EVM) adresy są całkowicie oddzielone od inteligentnych kontraktów. Proszę dowiedzieć się więcej o różnicach, czytając nasz artykuł ["Sześć unikalnych aspektów TON Blockchain, które zaskoczą programistów Solidity"] (https://blog.ton.org/six-unique-aspects-of-ton-blockchain-that-will-surprise-solidity-developers) autorstwa Tal Kol. +::: + +## Adres inteligentnego kontraktu + +Adresy inteligentnych kontraktów działających na TON zazwyczaj składają się z dwóch głównych komponentów: + +- **(workchain_id)**: oznacza identyfikator łańcucha roboczego (32-bitowa liczba całkowita ze znakiem). + +- **(account_id)** oznacza adres konta (64-512 bitów, w zależności od łańcucha roboczego). + +W sekcji przeglądu nieprzetworzonych adresów w tej dokumentacji omówimy, jak prezentują się pary **(workchain_id, account_id)**. + +### Identyfikator łańcucha roboczego i identyfikator konta + +#### Identyfikator łańcucha roboczego + +[Jak widzieliśmy wcześniej](/learn/overviews/ton-blockchain#workchain-blockchain-with-your-own-rules), możliwe jest utworzenie aż `2^32` łańcuchów roboczych działających na TON Blockchain. Zauważyliśmy również, w jaki sposób 32-bitowe prefiksy adresów inteligentnych kontraktów identyfikują i są powiązane z adresami inteligentnych kontraktów w różnych łańcuchach roboczych. Pozwala to inteligentnym kontraktom na wysyłanie i odbieranie wiadomości do i z różnych łańcuchów roboczych na TON Blockchain. + +Obecnie w TON Blockchain działa tylko Masterchain (workchain_id=-1) i okazjonalnie podstawowy workchain (workchain_id=0). + +Oba mają 256-bitowe adresy, dlatego zakładamy, że workchain_id wynosi 0 lub -1, a adres w łańcuchu roboczym ma dokładnie 256 bitów. + +#### Identyfikator konta + +Wszystkie identyfikatory kont w TON wykorzystują 256-bitowe adresy w łańcuchach Masterchain i Basechain (lub podstawowym łańcuchu roboczym). + +W rzeczywistości identyfikator konta **(account_id)** zdefiniowano jako funkcje skrótu dla obiektów inteligentnych kontraktów (w szczególności SHA-256). Każdy inteligentny kontrakt działający na TON Blockchain przechowuje dwa główne komponenty. Należą do nich: + +1. Skompilowany kod_. Logika inteligentnego kontraktu skompilowana w postaci kodu bajtowego. +2. *Stan początkowy*. Wartości kontraktu w momencie jego wdrożenia w łańcuchu. + +Wreszcie, aby dokładnie wyprowadzić adres kontraktu, konieczne jest obliczenie skrótu odpowiadającego parze **(kod początkowy, stan początkowy)** obiektu. W tej chwili nie będziemy zagłębiać się w to, jak działa [TVM](/learn/tvm-instructions/tvm-overview), ale ważne jest, aby zrozumieć, że identyfikatory kont w TON są określane za pomocą tego wzoru: +: +**account_id = hash(kod początkowy, stan początkowy)**. + +Z czasem, w całej tej dokumentacji, zagłębimy się w specyfikacje techniczne i przegląd schematu TVM i TL-B. Teraz, gdy jesteśmy zaznajomieni z generowaniem **account_id** i ich interakcją z adresami inteligentnych kontraktów w TON, wyjaśnijmy adresy Raw i User-Friendly. + +## Adresy państwowe + +Każdy adres może znajdować się w jednym z możliwych stanów: + +- `nonexist` - nie było żadnych zaakceptowanych transakcji na tym adresie, więc nie ma on żadnych danych (lub umowa została usunięta). Możemy powiedzieć, że początkowo wszystkie adresy2256 są w tym stanie. +- `uninit` - adres ma pewne dane, które zawierają saldo i meta informacje. W tym stanie adres nie ma jeszcze żadnego kodu inteligentnego kontraktu/trwałych danych. Adres wchodzi w ten stan, na przykład, gdy nie istniał, a inny adres wysłał do niego tokeny. +- `active` - adres posiada kod inteligentnego kontraktu, trwałe dane i saldo. W tym stanie może wykonać pewną logikę podczas transakcji i zmienić swoje trwałe dane. Adres wchodzi w ten stan, gdy był `uninit` i nadeszła wiadomość z parametrem state_init (proszę zauważyć, że aby móc wdrożyć ten adres, hash z `state_init` i `code` musi być równy adresowi). +- `frozen` - adres nie może wykonywać żadnych operacji, ten stan zawiera tylko dwa skróty poprzedniego stanu (odpowiednio komórki kodu i stanu). Gdy ładunek pamięci adresu przekroczy jego saldo, przechodzi on w ten stan. Aby go odmrozić, można wysłać wewnętrzną wiadomość z `state_init` i `code`, które przechowują hashe opisane wcześniej i trochę Toncoin. Odzyskanie go może być trudne, więc nie należy dopuszczać do takiej sytuacji. Istnieje projekt odblokowania adresu, który można znaleźć [tutaj] (https://unfreezer.ton.org/). + +## Surowe i przyjazne dla użytkownika adresy + +Po przedstawieniu krótkiego przeglądu tego, w jaki sposób adresy inteligentnych kontraktów w TON wykorzystują łańcuchy robocze i identyfikatory kont (w szczególności dla Masterchain i Basechain), ważne jest, aby zrozumieć, że adresy te są wyrażane w dwóch głównych formatach: + +- **Surowe adresy**: Oryginalna pełna reprezentacja adresów inteligentnych kontraktów. +- **Adresy przyjazne dla użytkownika**: Adresy przyjazne dla użytkownika to ulepszony format surowego adresu, który zapewnia lepsze bezpieczeństwo i łatwość użytkowania. + +Poniżej wyjaśnimy więcej na temat różnic między tymi dwoma typami adresów i zagłębimy się w to, dlaczego adresy przyjazne dla użytkownika są używane w TON. + +### Nieprzetworzony adres + +Nieprzetworzone adresy inteligentnych kontraktów składają się z identyfikatora łańcucha roboczego i identyfikatora konta *(workchain_id, account_id)* i są wyświetlane w następującym formacie: + +- [decimal workchain_id\]:[64 cyfry szesnastkowe z account_id\]. + +Poniżej znajduje się przykład nieprzetworzonego adresu inteligentnego kontraktu przy użyciu identyfikatora łańcucha roboczego i identyfikatora konta (wyrażonego jako **workchain_id** i **account_id**): + +`-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260` + +Proszę zauważyć `-1` na początku ciągu adresu, który oznacza *workchain_id* należący do Masterchain. + +:::note +Wielkie litery (takie jak "A", "B", "C", "D" itp.) mogą być używane w ciągach adresowych zamiast ich małych odpowiedników (takich jak "a", "b", "c", "d" itp.). +::: + +#### Problemy z surowymi adresami + +Korzystanie z formularza Raw Address wiąże się z dwoma głównymi problemami: + +1. W przypadku korzystania z nieprzetworzonego formatu adresu nie jest możliwa weryfikacja adresów w celu wyeliminowania błędów przed wysłaniem transakcji. + Oznacza to, że jeśli przypadkowo dodadzą lub usuną Państwo znaki w ciągu adresowym przed wysłaniem transakcji, zostanie ona wysłana do niewłaściwego miejsca docelowego, co spowoduje utratę środków. +2. Podczas korzystania z nieprzetworzonego formatu adresu niemożliwe jest dodanie specjalnych flag, takich jak te używane podczas wysyłania transakcji, które wykorzystują adresy przyjazne dla użytkownika. + Aby pomóc Państwu lepiej zrozumieć tę koncepcję, poniżej wyjaśnimy, które flagi mogą być używane. + +### Adres przyjazny dla użytkownika + +Przyjazne dla użytkownika adresy zostały opracowane w celu zabezpieczenia i uproszczenia doświadczenia użytkowników TON, którzy udostępniają adresy w Internecie (na przykład na publicznych platformach komunikacyjnych lub za pośrednictwem swoich dostawców usług poczty elektronicznej), a także w świecie rzeczywistym. + +#### Przyjazna dla użytkownika struktura adresów + +Przyjazne dla użytkownika adresy składają się łącznie z 36 bajtów i są uzyskiwane poprzez wygenerowanie następujących składników w kolejności: + +1. Flagi przypięte do adresów zmieniają sposób, w jaki inteligentne kontrakty reagują na otrzymaną wiadomość. + Typy flag, które wykorzystują przyjazny dla użytkownika format adresu obejmują: + + - isBounceable. Oznacza typ adresu bounceable lub non-bounceable. (*0x11* dla "bounceable", *0x51* dla "non-bounceable") + - isTestnetOnly. Oznacza typ adresu używany wyłącznie do celów sieci testowej. Adresy zaczynające się od *0x80* nie powinny być akceptowane przez oprogramowanie działające w sieci produkcyjnej. + - isUrlSafe. Oznacza przestarzałą flagę, która jest zdefiniowana jako URL-safe dla adresu. Wszystkie adresy są wtedy uważane za bezpieczne pod względem adresu URL. +2. *\[workchain_id - 1 bajt]* - Identyfikator łańcucha roboczego (*workchain_id*) jest zdefiniowany przez podpisaną 8-bitową liczbę całkowitą *workchain_id*.\ + (*0x00* dla BaseChain, *0xff* dla MasterChain) +3. Identyfikator konta składa się z ([big-endian](https://www.freecodecamp.org/news/what-is-endianness-big-endian-vs-little-endian/)) 256-bitowego adresu w łańcuchu roboczym. +4. Weryfikacja adresu - 2 bajty]_ - W adresach przyjaznych dla użytkownika weryfikacja adresu składa się z podpisu CRC16-CCITT z poprzednich 34 bajtów. ([Przykład](https://github.com/andreypfau/ton-kotlin/blob/ce9595ec9e2ad0eb311351c8a270ef1bd2f4363e/ton-kotlin-crypto/common/src/crc32.kt)) + W rzeczywistości idea weryfikacji adresów przyjaznych dla użytkownika jest dość podobna do [algorytmu Luhna](https://en.wikipedia.org/wiki/Luhn_algorithm), który jest używany na wszystkich kartach kredytowych, aby uniemożliwić użytkownikom omyłkowe wprowadzenie nieistniejących numerów kart. + +Dodanie tych 4 głównych składników oznacza, że: `1 + 1 + 32 + 2 = 36` bajtów łącznie (na adres przyjazny dla użytkownika). + +Aby wygenerować adres przyjazny dla użytkownika, programista musi zakodować wszystkie 36 bajtów za pomocą jednego z nich: + +- *base64* (tj. z cyframi, dużymi i małymi literami alfabetu łacińskiego, '/' i '+') +- *base64url* (z '_' i '-' zamiast '/' i '+') + +Po zakończeniu tego procesu generowany jest przyjazny dla użytkownika adres o długości 48 znaków bez odstępów. + +:::info FLAGI ADRESU DNS +W TON adresy DNS, takie jak mywallet.ton, są czasami używane zamiast surowych i przyjaznych dla użytkownika adresów. W rzeczywistości adresy DNS składają się z adresów przyjaznych dla użytkownika i zawierają wszystkie wymagane flagi, które umożliwiają programistom dostęp do wszystkich flag z rekordu DNS w domenie TON. +::: + +#### Przyjazne dla użytkownika przykłady kodowania adresów + +Przykładowo, inteligentny kontrakt "test giver" (specjalny inteligentny kontrakt rezydujący w łańcuchu głównym testnet, który wysyła 2 tokeny testowe do każdego, kto o nie poprosi) korzysta z następującego surowego adresu: + +`-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260` + +Powyższy nieprzetworzony adres "dawcy testu" musi zostać przekonwertowany na przyjazną dla użytkownika formę adresu. Uzyskuje się to za pomocą formularzy base64 lub base64url (które wprowadziliśmy wcześniej) w następujący sposób: + +- `kf/8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15+KsQHFLbKSMiYIny` (base64) +- `kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny` (base64url) + +:::info +Proszę zauważyć, że obie formy (*base64* i *base64url*) są poprawne i muszą zostać zaakceptowane! +::: + +#### Adresy odrzucające i nieodrzucające + +Główną ideą stojącą za flagą adresu zwrotnego jest bezpieczeństwo funduszy nadawcy. + +Na przykład, jeśli docelowy inteligentny kontrakt nie istnieje lub jeśli wystąpi jakiś problem podczas transakcji, wiadomość zostanie "odbita" z powrotem do nadawcy i będzie stanowić pozostałą część pierwotnej wartości transakcji (pomniejszoną o wszystkie opłaty za przelew i gaz). Gwarantuje to, że nadawca nie straci środków, które zostały przypadkowo wysłane na adres, który nie może zaakceptować transakcji. + +W szczególności w odniesieniu do adresów odrzucających: + +1. Flaga **bounceable=false** zazwyczaj oznacza, że odbiornik jest portfelem. +2. Flaga **bounceable=true** zazwyczaj oznacza niestandardowy inteligentny kontrakt z własną logiką aplikacji (na przykład DEX). W tym przykładzie wiadomości nie podlegające bounceable nie powinny być wysyłane ze względów bezpieczeństwa. + +Proszę przeczytać więcej na ten temat w naszej dokumentacji, aby lepiej zrozumieć [non-bouncable messages] (/develop/smart-contracts/guidelines/non-bouncable-messages). + +#### Reprezentacje bazy pancernej64 + +Dodatkowe dane binarne związane z TON Blockchain wykorzystują podobne "pancerne", przyjazne dla użytkownika reprezentacje adresów base64. Różnią się one od siebie w zależności od pierwszych 4 znaków ich znacznika bajtowego. Na przykład 256-bitowe klucze publiczne Ed25519 są reprezentowane przez utworzenie najpierw 36-bajtowej sekwencji przy użyciu poniższego procesu w kolejności: + +- Jednobajtowy znacznik w formacie *0x3E* oznacza klucz publiczny +- Jednobajtowy znacznik w formacie *0xE6* oznacza klucz publiczny Ed25519 +- 32 bajty zawierające standardową reprezentację binarną klucza publicznego Ed25519 +- 2 bajty zawierające reprezentację big-endian CRC16-CCITT poprzednich 34 bajtów + +Wynikowa 36-bajtowa sekwencja jest konwertowana na 48-znakowy ciąg base64 lub base64url w standardowy sposób. Na przykład klucz publiczny Ed25519 `E39ECDA0A7B0C60A7107EC43967829DBE8BC356A49B9DFC6186B3EAC74B5477D` (zwykle reprezentowany przez sekwencję 32 bajtów, takich jak: `0xE3, 0x9E, ..., 0x7D`) przedstawia się poprzez "pancerną" reprezentację w następujący sposób: + +`Pubjns2gp7DGCnEH7EOWeCnb6Lw1akm538YYaz6sdLVHfRB2` + +### Konwersja adresów przyjaznych dla użytkownika i adresów nieprzetworzonych + +Najprostszym sposobem konwersji przyjaznych dla użytkownika i nieprzetworzonych adresów jest użycie jednego z kilku interfejsów API TON i innych narzędzi, w tym: + +- [ton.org/address](https://ton.org/address) +- [dton.io API method](https://dton.io/api/address/0:867ac2b47d1955de6c8e23f57994fad507ea3bcfe2a7d76ff38f29ec46729627) +- [metody API toncenter w sieci głównej](https://toncenter.com/api/v2/#/accounts/pack_address_packAddress_get) +- [metody API toncenter w testnet](https://testnet.toncenter.com/api/v2/#/accounts/pack_address_packAddress_get) + +Ponadto istnieją dwa sposoby konwertowania przyjaznych dla użytkownika i nieprzetworzonych adresów portfeli za pomocą JavaScript: + +- [Konwersja adresu z/do postaci przyjaznej dla użytkownika lub nieprzetworzonej przy użyciu ton.js](https://github.com/ton-org/ton-core/blob/main/src/address/Address.spec.ts) +- [Proszę przekonwertować adres z/do postaci przyjaznej dla użytkownika lub nieprzetworzonej za pomocą tonweb](https://github.com/toncenter/tonweb/tree/master/src/utils#address-class) + +Możliwe jest również wykorzystanie podobnych mechanizmów za pomocą [SDK](/develop/dapps/apis/sdk). + +### Przykłady adresów + +Więcej przykładów na temat adresów TON można znaleźć w książce kucharskiej [TON Cookbook] (/develop/dapps/cookbook#working-with-contracts-addresses). + +## Możliwe problemy + +Podczas interakcji z blockchainem TON kluczowe jest zrozumienie konsekwencji przesyłania monet TON na adresy portfeli `uninit`. W tej sekcji przedstawiono różne scenariusze i ich wyniki, aby zapewnić jasność co do sposobu obsługi takich transakcji. + +### Co się stanie, gdy przeleją Państwo Toncoin na niezainicjowany adres? + +#### Transakcja z włączonym `state_init` + +Jeśli dołączą Państwo `state_init` (który składa się z kodu i danych portfela lub inteligentnego kontraktu) do swojej transakcji. Inteligentny kontrakt jest najpierw wdrażany przy użyciu dostarczonego `state_init`. Po wdrożeniu, przychodząca wiadomość jest przetwarzana, podobnie jak w przypadku wysyłania na już zainicjalizowane konto. + +#### Transakcja bez ustawionej flagi `state_init` i `bounce` + +Wiadomość nie może zostać dostarczona do inteligentnego kontraktu `uninit` i zostanie odesłana z powrotem do nadawcy. Po odjęciu zużytych opłat za gaz, pozostała kwota jest zwracana na adres nadawcy. + +#### Transakcja bez ustawionej flagi `state_init` i `bounce` + +Wiadomość nie może zostać dostarczona, ale nie zostanie odesłana do nadawcy. Zamiast tego wysłana kwota zostanie przelana na adres odbiorcy, zwiększając jego saldo, nawet jeśli portfel nie został jeszcze zainicjowany. Będą one tam przechowywane, dopóki posiadacz adresu nie wdroży kontraktu inteligentnego portfela, a następnie będzie mógł uzyskać dostęp do salda. + +#### Jak zrobić to dobrze + +Najlepszym sposobem na wdrożenie portfela jest wysłanie pewnej ilości TON na jego adres (który nie jest jeszcze zainicjowany) z wyczyszczoną flagą `bounce`. Po tym kroku właściciel może wdrożyć i zainicjować portfel przy użyciu środków na bieżącym niezainicjalizowanym adresie. Ten krok zwykle ma miejsce przy pierwszej operacji portfela. + +### Blockchain TON zapewnia ochronę przed błędnymi transakcjami + +W blockchainie TON standardowe portfele i aplikacje automatycznie zarządzają złożonością transakcji na niezainicjowane adresy za pomocą adresów bounceable i non-bounceable, które są opisane [tutaj] (#bounceable-vs-non-bounceable-addresses). Powszechną praktyką portfeli podczas wysyłania monet na niezainicjowane adresy jest wysyłanie monet zarówno na adresy bounceable, jak i non-bounceable bez zwrotu. + +Jeśli istnieje potrzeba szybkiego uzyskania adresu w formie odbijającej/nieodbijającej, można to zrobić [tutaj](https://ton.org/address/). + +### Odpowiedzialność za produkty niestandardowe + +Jeśli opracowują Państwo niestandardowy produkt na blockchainie TON, konieczne jest wdrożenie podobnych kontroli i logiki: + +Przed wysłaniem środków należy upewnić się, że aplikacja weryfikuje, czy adres odbiorcy został zainicjowany. +W oparciu o stan adresu, proszę używać adresów odrzucających dla inteligentnych kontraktów użytkownika z niestandardową logiką aplikacji, aby zapewnić zwrot środków. W przypadku portfeli proszę używać adresów niepodlegających odrzuceniu. diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/learn/overviews/cells.md b/i18n/pl/docusaurus-plugin-content-docs/current/learn/overviews/cells.md new file mode 100644 index 0000000000..9970ad995a --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/learn/overviews/cells.md @@ -0,0 +1,52 @@ +# Komórki jako magazyn danych + +Wszystko w TON jest przechowywane w komórkach. Komórka jest strukturą danych zawierającą: + +- do **1023 bitów** danych (nie bajtów!) +- do **4 odniesień** do innych komórek + +Bity i referencje nie są mieszane (są przechowywane oddzielnie). Odwołania cykliczne są zabronione: dla dowolnej komórki, żadna z komórek potomnych nie może mieć tej oryginalnej komórki jako odwołania. + +W ten sposób wszystkie komórki tworzą skierowany graf acykliczny (DAG). Oto dobry obrazek ilustrujący: + +Ukierunkowany graf acykliczny](/img/docs/dag.png) + +## Typy komórek + +Obecnie istnieje 5 rodzajów komórek: *zwykłe* i 4 *egzotyczne*. +Egzotyczne typy są następujące: + +- Przycięta komórka gałęzi +- Komórka referencyjna biblioteki +- Komórka Merkle proof +- Komórka aktualizacji Merkle + +:::tip +Więcej informacji na temat egzotycznych komórek można znaleźć w: [**TVM Whitepaper, Section 3**](https://ton.org/tvm.pdf). +::: + +## Smaki komórkowe + +Komórka jest nieprzezroczystym obiektem zoptymalizowanym pod kątem kompaktowego przechowywania. + +W szczególności deduplikuje dane: jeśli istnieje kilka równoważnych podkomórek, do których odwołują się różne gałęzie, ich zawartość jest przechowywana tylko raz. Nieprzezroczystość oznacza jednak, że komórki nie można bezpośrednio modyfikować ani odczytywać. Istnieją zatem 2 dodatkowe wersje komórek: + +- *Builder* dla częściowo skonstruowanych komórek, dla których można zdefiniować szybkie operacje dołączania ciągów bitów, liczb całkowitych, innych komórek i odwołań do innych komórek. +- *Slice* dla "wyciętych" komórek reprezentujących pozostałą część częściowo przeanalizowanej komórki lub wartość (podkomórkę) znajdującą się wewnątrz takiej komórki i wyodrębnioną z niej za pomocą instrukcji parsowania. + +Kolejna specjalna odmiana komórek jest używana w TVM: + +- *Continuation* dla komórek zawierających kody operacyjne (instrukcje) dla TON Virtual Machine, proszę zobaczyć [TVM bird's-eye overview](/learn/tvm-instructions/tvm-overview). + +## Serializacja danych do komórek + +Każdy obiekt w TON (wiadomość, kolejka wiadomości, blok, cały stan blockchain, kod kontraktu i dane) serializuje się do komórki. + +Proces serializacji jest opisany przez schemat TL-B: formalny opis tego, jak ten obiekt może być serializowany do *Builder* lub jak przeanalizować obiekt danego typu z *Slice*. +TL-B dla komórek jest taki sam jak TL lub ProtoBuf dla strumieni bajtów. + +Jeśli chcą Państwo dowiedzieć się więcej na temat (de)serializacji komórek, proszę przeczytać artykuł [Cell & Bag of Cells](/develop/data-formats/cell-boc). + +## Proszę zobaczyć również + +- [Język TL-B](/develop/data-formats/tl-b-language) diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/learn/overviews/ton-blockchain.md b/i18n/pl/docusaurus-plugin-content-docs/current/learn/overviews/ton-blockchain.md new file mode 100644 index 0000000000..603a33a29f --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/learn/overviews/ton-blockchain.md @@ -0,0 +1,72 @@ +# Blockchain łańcuchów bloków + +:::tip +Terminy "**smart contract**", "**account**" i "**actor**" są używane zamiennie w tym dokumencie w celu opisania podmiotu blockchain. +::: + +## Pojedynczy aktor + +Rozważmy jeden inteligentny kontrakt. + +W TON jest to *rzecz* z właściwościami takimi jak `adres`, `kod`, `dane`, `bilans` i innymi. Innymi słowy, jest to obiekt, który posiada *storage* i *behavior*. +To zachowanie ma następujący wzór: + +- coś się dzieje (najczęstszą sytuacją jest to, że umowa otrzymuje wiadomość) +- Kontrakt obsługuje to zdarzenie zgodnie z jego własnymi właściwościami, wykonując swój "kod" w wirtualnej maszynie TON. +- kontrakt modyfikuje swoje własne właściwości (`code`, `data` i inne) +- umowa opcjonalnie generuje wiadomości wychodzące +- Kontrakt przechodzi w tryb czuwania do momentu wystąpienia kolejnego zdarzenia + +Kombinacja tych kroków nazywana jest **transakcją**. Ważne jest, aby zdarzenia były obsługiwane jedno po drugim, dlatego *transakcje* są ściśle uporządkowane i nie mogą się wzajemnie przerywać. + +Ten wzorzec zachowania jest dobrze znany i nazywany "aktorem". + +### Najniższy poziom: Łańcuch kont + +Sekwencję *transakcji* `Tx1 -> Tx2 -> Tx3 -> ....` można nazwać **łańcuchem**. W rozważanym przypadku jest on nazywany **AccountChain**, aby podkreślić, że jest to *łańcuch* pojedynczego konta transakcji. + +Teraz, ponieważ węzły przetwarzające transakcje muszą od czasu do czasu koordynować stan inteligentnego kontraktu (aby osiągnąć *konsensus* co do stanu), te *transakcje* są grupowane: +`[Tx1 -> Tx2] -> [Tx3 -> Tx4 -> Tx5] -> [] -> [Tx6]`. +Batching nie ingeruje w sekwencjonowanie, każda transakcja nadal ma tylko jeden "prev tx" i co najwyżej jeden "next tx", ale teraz ta sekwencja jest pocięta na **bloki**. + +Wskazane jest również dołączenie kolejek wiadomości przychodzących i wychodzących do *blocks*. W takim przypadku *block* będzie zawierał pełny zestaw informacji, które określają i opisują, co stało się z inteligentnym kontraktem podczas tego bloku. + +## Wiele łańcuchów kont: Shards + +Rozważmy teraz wiele kont. Możemy uzyskać kilka *AccountChains* i przechowywać je razem, taki zestaw *AccountChains* nazywany jest **ShardChain**. W ten sam sposób możemy podzielić **ShardChain** na **ShardBlocks**, które są agregacją poszczególnych *AccountBlocks*. + +### Dynamiczne dzielenie i łączenie łańcuchów ShardChains + +Proszę zauważyć, że ponieważ *ShardChain* składa się z łatwo rozróżnialnych *AccountChains*, możemy go łatwo podzielić. W ten sposób, jeśli mamy 1 *ShardChain*, który opisuje zdarzenia, które mają miejsce z 1 milionem kont i jest zbyt wiele transakcji na sekundę, aby mogły być przetwarzane i przechowywane w jednym węźle, więc po prostu podzielimy (lub **split**) ten łańcuch na dwa mniejsze *ShardChains* z każdym łańcuchem odpowiadającym za pół miliona kont i każdym łańcuchem przetwarzanym na oddzielnym podzbiorze węzłów. + +Analogicznie, jeśli niektóre odłamki stały się zbyt wolne, mogą zostać **połączone** w jeden większy odłamek. + +Istnieją oczywiście dwa ograniczające przypadki: gdy shard zawiera tylko jedno konto (a zatem nie może być dalej dzielony) i gdy shard zawiera wszystkie konta. + +Konta mogą wchodzić ze sobą w interakcje poprzez wysyłanie wiadomości. Istnieje specjalny mechanizm routingu, który przenosi wiadomości z kolejek wychodzących do odpowiednich kolejek przychodzących i zapewnia, że 1) wszystkie wiadomości zostaną dostarczone 2) wiadomości zostaną dostarczone kolejno (wiadomość wysłana wcześniej dotrze do celu wcześniej). + +:::info UWAGA BOCZNA +Aby podział i łączenie były deterministyczne, agregacja AccountChains w shardy opiera się na bitowej reprezentacji adresów kont. Na przykład, adres wygląda jak `(prefiks shardu, adres)`. W ten sposób wszystkie konta w shardchainie będą miały dokładnie taki sam prefiks binarny (na przykład wszystkie adresy będą zaczynać się od `0b00101`). +::: + +## Blockchain + +Agregacja wszystkich odłamków, która zawiera wszystkie konta zachowujące się zgodnie z jednym zestawem reguł, nazywana jest **Blockchain**. + +W TON może istnieć wiele zestawów reguł, a tym samym wiele łańcuchów bloków, które działają jednocześnie i mogą wchodzić ze sobą w interakcje poprzez wysyłanie wiadomości crosschain w taki sam sposób, w jaki konta jednego łańcucha mogą wchodzić ze sobą w interakcje. + +### Workchain: Blockchain z własnymi zasadami + +Jeśli chcą Państwo dostosować zasady grupy Shardchainów, można utworzyć **Workchain**. Dobrym przykładem jest stworzenie łańcucha roboczego, który działa w oparciu o EVM, aby uruchamiać na nim inteligentne kontrakty Solidity. + +Teoretycznie każdy w społeczności może stworzyć własny łańcuch roboczy. W rzeczywistości jest to dość skomplikowane zadanie, aby go zbudować, a następnie zapłacić (kosztowną) cenę za jego utworzenie i otrzymać 2/3 głosów od walidatorów, aby zatwierdzić utworzenie Workchaina. + +TON pozwala na utworzenie do `2^32` łańcuchów roboczych, każdy podzielony na do `2^60` shardów. + +Obecnie w TON istnieją tylko 2 łańcuchy robocze: MasterChain i BaseChain. + +BaseChain jest używany do codziennych transakcji między aktorami, ponieważ jest dość tani, podczas gdy MasterChain ma kluczową funkcję dla TON, więc omówmy, co robi! + +### Masterchain: Blockchain of Blockchains + +Istnieje konieczność synchronizacji routingu wiadomości i wykonywania transakcji. Innymi słowy, węzły w sieci potrzebują sposobu na ustalenie pewnego "punktu" w stanie multichain i osiągnięcie konsensusu co do tego stanu. W TON do tego celu wykorzystywany jest specjalny łańcuch o nazwie **MasterChain**. Bloki *masterchain* zawierają dodatkowe informacje (najnowsze skróty bloków) o wszystkich innych łańcuchach w systemie, dzięki czemu każdy obserwator jednoznacznie określa stan wszystkich systemów multichain w pojedynczym bloku masterchain. diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/learn/tvm-instructions/tvm-overview.mdx b/i18n/pl/docusaurus-plugin-content-docs/current/learn/tvm-instructions/tvm-overview.mdx new file mode 100644 index 0000000000..a97f0a8d75 --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/learn/tvm-instructions/tvm-overview.mdx @@ -0,0 +1,133 @@ +import Button from '@site/src/components/button' + +# Przegląd TVM + +Wszystkie inteligentne kontrakty TON są wykonywane na własnej maszynie wirtualnej TON (TVM). TVM jest zbudowana na zasadzie _stack_, co czyni ją wydajną i łatwą do wdrożenia. + +Niniejszy dokument przedstawia z lotu ptaka sposób, w jaki TVM realizuje transakcje. + +:::tip + +- TVM Source - [**Implementacja TVM C++**](https://github.com/ton-blockchain/ton/tree/master/crypto/vm) + ::: + +## Kurs TON: TVM + +:::tip +Przed rozpoczęciem kursu prosimy upewnić się, że dobrze rozumieją Państwo podstawy technologii blockchain. Jeśli mają Państwo luki w wiedzy, zalecamy wzięcie udziału w kursie [Blockchain Basics with TON](https://stepik.org/course/201294/promo) ([wersja RU](https://stepik.org/course/202221/), [wersja CHN](https://stepik.org/course/200976/)). +::: + +Kurs [TON Blockchain Course] (https://stepik.org/course/176754/) to kompleksowy przewodnik po rozwoju TON Blockchain. + +Moduł 2 w całości obejmuje **TVM**, transakcje, skalowalność i przypadki biznesowe. + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Transakcje i fazy + +Kiedy jakieś zdarzenie ma miejsce na koncie w jednym z łańcuchów TON, powoduje to **transakcję**. Najczęstszym zdarzeniem jest "nadejście jakiejś wiadomości", ale ogólnie rzecz biorąc mogą to być zdarzenia typu `tick-tock`, `merge`, `split` i inne. + +Każda transakcja składa się z maksymalnie 5 faz: + +1. **Faza przechowywania** - w tej fazie obliczane są opłaty za przechowywanie zgromadzone przez umowę z powodu zajęcia pewnej przestrzeni w stanie łańcucha. Proszę przeczytać więcej w [Storage Fees](/develop/smart-contracts/fees#storage-fee). +2. **Faza kredytowania** - w tej fazie obliczane jest saldo umowy w odniesieniu do (możliwej) wartości przychodzącej wiadomości i pobranej opłaty za przechowywanie. +3. **Faza obliczeniowa** - w tej fazie TVM wykonuje kontrakt (patrz poniżej), a wynikiem wykonania kontraktu jest agregacja `exit_code`, `actions` (serializowana lista działań), `gas_details`, `new_storage` i kilku innych. +4. **Faza akcji** - jeśli faza obliczeniowa zakończyła się sukcesem, w tej fazie przetwarzane są `akcje` z fazy obliczeniowej. W szczególności działania mogą obejmować wysyłanie wiadomości, aktualizację kodu inteligentnego kontraktu, aktualizację bibliotek itp. Proszę zauważyć, że niektóre akcje mogą zakończyć się niepowodzeniem podczas przetwarzania (na przykład, jeśli spróbujemy wysłać wiadomość z większą liczbą TON niż posiada kontrakt), w takim przypadku cała transakcja może zostać cofnięta lub ta akcja może zostać pominięta (zależy to od trybu akcji, innymi słowy, kontrakt może wysłać wiadomość typu `send-or-revert` lub `try-send-if-no-ignore`). +5. **Faza odbicia** - jeśli faza obliczeniowa nie powiodła się (zwróciła `exit_code >= 2`), w tej fazie tworzony jest _bounce message_ dla transakcji zainicjowanych przez przychodzącą wiadomość. + +## Faza obliczeniowa + +W tej fazie następuje wykonanie TVM. + +### Stan TVM + +W danym momencie stan TVM jest w pełni określony przez 6 właściwości: + +- Stos (patrz poniżej) +- Rejestry kontrolne - (patrz poniżej), mówiąc prościej, oznacza to do 16 zmiennych, które mogą być bezpośrednio ustawiane i odczytywane podczas wykonywania. +- Bieżąca kontynuacja - obiekt opisujący aktualnie wykonywaną sekwencję instrukcji +- Bieżąca strona kodowa - w uproszczeniu oznacza to wersję TVM, która jest obecnie uruchomiona +- Limity gazu - zestaw 4 wartości całkowitych: aktualny limit gazugl, maksymalny limit gazugm, pozostały gazgr i kredyt gazu gc. +- Kontekst biblioteki - mapa bibliotek, które mogą być wywoływane przez TVM + +### TVM jest maszyną stosową + +TVM jest maszyną stosową typu ostatnie wejście-pierwsze wyjście. W sumie istnieje 7 typów zmiennych, które mogą być przechowywane na stosie - trzy typy niekomórkowe: + +- Integer - 257-bitowe liczby całkowite ze znakiem +- Tuple - uporządkowany zbiór do 255 elementów o dowolnych typach wartości, w miarę możliwości odrębnych. +- Null + +I cztery różne smaki komórek: + +- Cell - podstawowa (ewentualnie zagnieżdżona) nieprzezroczysta struktura używana przez TON Blockchain do przechowywania wszystkich danych. +- Slice - specjalny obiekt umożliwiający odczyt z komórki +- Builder - specjalny obiekt umożliwiający tworzenie nowych komórek +- Kontynuacja - specjalny obiekt, który pozwala wykorzystać komórkę jako źródło instrukcji TVM + +### Rejestry kontrolne + +- `c0` - Zawiera następną kontynuację lub kontynuację powrotu (podobną do adresu powrotu podprogramu w konwencjonalnych projektach). Ta wartość musi być kontynuacją. +- `c1` - Zawiera alternatywną (powrotną) kontynuację; ta wartość musi być kontynuacją. +- `c2` - Zawiera procedurę obsługi wyjątku. Ta wartość jest kontynuacją, wywoływaną za każdym razem, gdy zostanie wyzwolony wyjątek. +- `c3` - Rejestr pomocniczy, zawiera bieżący słownik, zasadniczo hashmap zawierający kod wszystkich funkcji używanych w programie. Ta wartość musi być kontynuacją. +- `c4` - Zawiera główną część trwałych danych lub po prostu sekcję `data` kontraktu. Ta wartość jest komórką. +- `c5` - Zawiera akcje wyjściowe. Ta wartość to komórka. +- `c7` - Zawiera korzeń danych tymczasowych. Jest to krotka. + +### Inicjalizacja TVM + +TVM inicjalizuje się, gdy wykonanie transakcji osiągnie fazę obliczeniową, a następnie wykonuje polecenia (kody operacyjne) z _Current continuation_, dopóki nie będzie więcej poleceń do wykonania (i nie będzie kontynuacji dla skoków powrotnych). + +Szczegółowy opis procesu inicjalizacji można znaleźć tutaj: [Inicjalizacja TVM](/learn/tvm-instructions/tvm-initialization.md). + +## Instrukcje TVM + +Listę instrukcji TVM można znaleźć tutaj: [Instrukcje TVM](/learn/tvm-instructions/instructions). + +### Wynik wykonania TVM + +Oprócz danych exit_code i zużytego gazu, TVM pośrednio wysyła następujące dane: + +- Rejestr c4 - komórka, która zostanie zapisana jako nowe `dane` inteligentnego kontraktu (jeśli wykonanie nie zostanie cofnięte w tej lub późniejszych fazach) +- c5 register - (lista akcji wyjściowych) komórka z ostatnią akcją na liście i odwołanie do komórki z poprzednią akcją (rekurencyjnie) + +Wszystkie inne wartości rejestru zostaną pominięte. + +Proszę zauważyć, że ponieważ istnieje limit maksymalnej głębokości komórki `<1024`, a w szczególności limit głębokości c4 i c5 `<=512`, będzie istniał limit liczby akcji wyjściowych w jednym tx `<=255`. Jeśli kontrakt musi wysłać więcej niż to, może wysłać wiadomość z żądaniem `continue_sending` do siebie i wysłać wszystkie potrzebne wiadomości w kolejnych transakcjach. + +## Proszę zobaczyć również + +- [Instrukcje TVM](/learn/tvm-instructions/instructions) +- [TON TVM](https://ton.org/tvm.pdf) Koncepcje TVM (mogą zawierać nieaktualne informacje) diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/participate/README.md b/i18n/pl/docusaurus-plugin-content-docs/current/participate/README.md new file mode 100644 index 0000000000..fabf98e52a --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/participate/README.md @@ -0,0 +1,38 @@ +# Przegląd + +Sekcja participate naszej dokumentacji jest dostosowana do umożliwienia użytkownikom odkrycia możliwości pracy z TON +. Ma ona również na celu zaoferowanie niezbędnych ram (eksploratorów, portfeli, TEP), które są niezbędne do uczestnictwa w ekosystemie TON i tworzenia wizji TON World Wide Web (TWW). + +## Udział w ekosystemie TON + +- [Odkrywcy TON](/uczestnictwo/odkrywcy) +- [Aplikacje portfela (dla programistów)](/participate/wallets/apps) +- [Rodzaje umów portfela](/uczestnictwo/portfele/umowy) + +### Dołącz do społeczności TON + +- [TON Enhancement Proposals (TEPs)](https://github.com/ton-blockchain/TEPs) +- [Odkryj innowacje TON na TON Research](https://tonresear.ch/) +- [Stawka z nominatorami TON](/uczestnictwo/utrzymanie-sieci/nominatorzy) + +### Mosty + +- [Przegląd mostów](/participate/crosschain/overview) +- [Adresy mostków](/participate/crosschain/bridge-addresses) + +### Uruchom węzeł + +- [Odkryj typy węzłów w TON](/participate/nodes/node-types) +- [Uruchom pełny węzeł lub walidator](/participate/run-nodes/full-node) +- [Konserwacja i bezpieczeństwo walidatora TON](/participate/nodes/node-maintenance-and-security) + +## Udział w TON Web3 + +- [Przegląd TON Web3](/participate/web3/overview) +- [Proszę używać TON DNS dla swoich domen](/participate/web3/dns) +- [Zarządzanie witrynami i domenami](/participate/web3/site-management) +- [\[Tutorial\] Jak uruchomić własną witrynę TON?] (/develop/dapps/tutorials/how-to-run-ton-site) + +### TON Proxy + +- [Jak otworzyć dowolną witrynę TON?](/participate/web3/how-to-open-any-ton-site) diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/participate/crosschain/overview.md b/i18n/pl/docusaurus-plugin-content-docs/current/participate/crosschain/overview.md new file mode 100644 index 0000000000..da0fd9d3d1 --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/participate/crosschain/overview.md @@ -0,0 +1,57 @@ +# Mostki międzyłańcuchowe + +Zdecentralizowane mosty międzyłańcuchowe działają na TON Blockchain, umożliwiając przesyłanie aktywów z TON Blockchain do innych łańcuchów bloków i odwrotnie. + +## Most Toncoin + +Most Toncoin umożliwia przesyłanie Toncoinów między TON Blockchain a blockchainem Ethereum, a także między TON Blockchain a BNB Smart Chain. + +Most jest zarządzany przez [zdecentralizowane wyrocznie] (/participate/crosschain/bridge-addresses). + +### Jak go używać? + +Frontend Bridge jest hostowany na stronie https://ton.org/bridge. + +:::info +[Kod źródłowy interfejsu Bridge](https://github.com/ton-blockchain/bridge) +::: + +### Kody źródłowe inteligentnych kontraktów TON-Ethereum + +- [FunC (strona TON)](https://github.com/ton-blockchain/bridge-func) +- [Solidity (strona Ethereum)](https://github.com/ton-blockchain/bridge-solidity/tree/eth_mainnet) + +### Kody źródłowe inteligentnych kontraktów TON-BNB Smart Chain + +- [FunC (strona TON)](https://github.com/ton-blockchain/bridge-func/tree/bsc) +- [Solidity (strona BSC)](https://github.com/ton-blockchain/bridge-solidity/tree/bsc_mainnet) + +### Konfiguracje blockchain + +Rzeczywiste adresy inteligentnych kontraktów bridge i adresy oracle można uzyskać, sprawdzając odpowiednią konfigurację: + +TON-Ethereum: [#71](https://github.com/ton-blockchain/ton/blob/35d17249e6b54d67a5781ebf26e4ee98e56c1e50/crypto/block/block.tlb#L738). + +TON-BSC: [#72](https://github.com/ton-blockchain/ton/blob/35d17249e6b54d67a5781ebf26e4ee98e56c1e50/crypto/block/block.tlb#L739). + +TON-Polygon: [#73](https://github.com/ton-blockchain/ton/blob/35d17249e6b54d67a5781ebf26e4ee98e56c1e50/crypto/block/block.tlb#L740). + +### Dokumentacja + +- [Jak działa most](https://github.com/ton-blockchain/TIPs/issues/24) + +### Międzyłańcuchowa mapa drogowa + +- https://t.me/tonblockchain/146 + +## Most Tonana + +### Jak wziąć udział? + +:::caution projekt\ +To jest artykuł koncepcyjny. Wciąż szukamy kogoś doświadczonego, kto mógłby go napisać. +::: + +Front-end znajdą Państwo tutaj: https://tonana.org/ + +Kod źródłowy znajduje się tutaj: https://github.com/tonanadao diff --git a/i18n/pl/docusaurus-plugin-content-docs/current/participate/web3/overview.mdx b/i18n/pl/docusaurus-plugin-content-docs/current/participate/web3/overview.mdx new file mode 100644 index 0000000000..280e3f370b --- /dev/null +++ b/i18n/pl/docusaurus-plugin-content-docs/current/participate/web3/overview.mdx @@ -0,0 +1,17 @@ +# Przegląd + +## Koncepcje + +Proszę przeczytać więcej o pomysłach w: + +- [Płatności na TON](https://blog.ton.org/ton-payments) +- [TON DNS & Domains](/participate/web3/dns) +- [TON Sites, TON WWW i TON Proxy](https://blog.ton.org/ton-sites) + +## Przypadki użycia + +- [\*.ton przyjazne dla użytkownika domeny dla dowolnego inteligentnego kontraktu](/participate/web3/dns) +- [Proszę połączyć się z witrynami TON za pomocą TON Proxy](/participate/web3/setting-proxy) +- [Uruchom własny serwer proxy TON, aby połączyć się z witrynami TON](/participate/web3/sites-and-proxy) +- [Proszę połączyć swój portfel TON lub witrynę TON z domeną](/participate/web3/site-management) +- [Jak utworzyć subdomenę przy użyciu inteligentnych kontraktów TON DNS] (/participate/web3/site-management#how-to-set-up-subdomains) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/contribute/README.md b/i18n/ru/docusaurus-plugin-content-docs/current/contribute/README.md new file mode 100644 index 0000000000..7a0b86cd7f --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/contribute/README.md @@ -0,0 +1,50 @@ +# Как внести вклад + +## Определите область для вклада + +Есть несколько способов определить область, в которой Вы можете внести свой вклад в TON Docs: + +- Присоединяйтесь к чату [TON Docs Club](https://t.me/+c-0fVO4XHQsyOWM8) в Telegram и получайте информацию о последних задачах от сопровождающих. +- Если у Вас на примете есть конкретный вклад, но Вы не уверены в нём, уточните, подходит ли + этот вклад, обратившись напрямую к одному из сопровождающих [Docs](/contribute/maintainers). +- Ознакомьтесь с наиболее часто задаваемыми вопросами в чатах [TON Developers](https://t.me/tondev_eng). +- Пожалуйста, ознакомьтесь с [issues](https://github.com/ton-community/ton-docs/issues) в репозитории GitHub. +- Изучите доступные [footsteps](https://github.com/ton-society/ton-footsteps/issues?q=documentation) для документации. + +## TL;DR + +- Если Вам нужно добавить или изменить что-то в TON Docs, создайте запрос тяги + к ветке `main`. +- Команда разработчиков документации рассмотрит запрос на привлечение или свяжется с Вами при необходимости. +- Репозиторий: https://github.com/ton-community/ton-docs + +## Разработка + +### Онлайновая установка взносов в один клик + +Вы можете использовать Gitpod (бесплатную, онлайновую, похожую на VS code IDE) для внесения вклада. Он запустит рабочую область одним щелчком мыши и автоматически: + +[![Открыть в Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/ton-community/ton-docs) + +### Кодовые конвенции + +- **Самое важное**: оглянитесь вокруг. Соответствуйте общему стилю проекта. Это включает форматирование, именование файлов, именование объектов в коде, именование вещей в документации и так далее. +- **Для документации**: При редактировании документации не заворачивайте строки на 80 символов; вместо этого настройте свой редактор на мягкое заворачивание. + +Не беспокойтесь слишком сильно о стилях в целом; сопровождающие помогут Вам исправить их, когда будут просматривать Ваш код. + +### Pull Requests + +Итак, Вы решили внести свой код обратно в upstream, открыв запрос на исправление. Вы приложили много усилий, и мы ценим это. Мы сделаем все возможное, чтобы сотрудничать с Вами и добиться рассмотрения запроса. + +При подаче запроса на исправление, пожалуйста, убедитесь в следующем: + +1. **Сохраняйте свой запрос на исправление небольшим**. Маленькие запросы (~300 строк различий) легче просматривать и больше шансов, что они будут объединены. Убедитесь, что запрос на исправление делает только одну вещь, в противном случае, пожалуйста, разделите его. +2. **Используйте описательные заголовки**. Рекомендуется придерживаться стиля сообщений фиксации. +3. **Тестируйте свои изменения**. Опишите план тестирования в описании Вашего запроса на выгрузку. + +Все запросы на исправление должны быть открыты в ветке `main`. + +## Что происходит дальше? + +Команда TON Docs будет следить за запросами на доработку. Пожалуйста, помогите нам, следуя приведенным выше рекомендациям, чтобы запросы на доработку были согласованными. diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md b/i18n/ru/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md new file mode 100644 index 0000000000..bda8c8d345 --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md @@ -0,0 +1,39 @@ +# Программа локализации + +Программа переводов - это совместная работа по переводу различных документов, связанных с TON, на множество языков, что делает сайт более доступным для миллиардов людей, не говорящих по-английски, по всему миру. + +## Философия проектирования системы + +![как это работает](/img/localizationProgramGuideline/localization-program.png) + +Программа локализации **запущена** и **активно поддерживается** компанией [**TownSquare Labs**](https://github.com/TownSquareXYZ), одним из ближайших партнеров **TON**. + +Мы стремимся создать открытую инфраструктуру для сотрудничества многоязычного сообщества, чтобы **перевести TON в лучшую фазу**, что включает в себя: + +1. **Подходит для многоязычных сообществ**\ + Программа поддерживает несколько языков, обеспечивая инклюзивность и простоту доступа для пользователей из разных языковых сред. + +2. **Автоматизация разработки, интеграции и развертывания**\ + Используя инструменты автоматизации, программа упрощает процессы разработки, интеграции и развертывания, сокращая ручные усилия и повышая эффективность и согласованность всех усилий по локализации. + +3. **Разделение ролей разработчика, переводчика и верификатора**\ + Наш подход разделяет обязанности разработчиков, переводчиков и верификаторов, позволяя каждой роли сосредоточиться на своих конкретных задачах. Это обеспечивает высокое качество переводов и слаженную совместную работу без дублирования или конфликта обязанностей. + +4. **Поощрение за вклад сообщества**\ + Мы поощряем членов сообщества, которые вносят свой вклад в процесс локализации. Это поощряет активное участие и вознаграждает тех, кто помогает улучшить программу, развивая чувство сопричастности и дух сообщества. + +5. **Интеграция передовых систем искусственного интеллекта**\ + Передовые системы искусственного интеллекта повышают точность и эффективность перевода, предоставляя интеллектуальные предложения и автоматизируя повторяющиеся задачи, обеспечивая высокое качество результатов при меньших усилиях. + +Этот проект предназначен не только для носителей одного языка; наша цель - **служить глобальной экосистеме разработчиков**. + +## Благодарности + +Мы очень благодарны тысячам членов сообщества, которые являются ключевой частью Программы переводов. Мы хотим отметить наших переводчиков и поддержать их на их карьерном пути. В ближайшем будущем мы отметим наших лучших переводчиков, создав таблицы лидеров и список всех участников Программы переводов. + +## Руководства и ресурсы + +Если Вы вносите свой вклад в Программу переводов или думаете о том, чтобы принять в ней участие, ознакомьтесь с приведенными ниже руководствами по переводу: + +- [**Руководство по стилю перевода**](/contribute/localization-program/translation-style-guide) - Инструкции и советы для переводчиков. +- [**Руководство по онлайн-редактору Crowdin**](https://support.crowdin.com/online-editor/) - Подробное руководство по использованию онлайн-редактора Crowdin и некоторых расширенных возможностей Crowdin. diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/README.md b/i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/README.md new file mode 100644 index 0000000000..47d5fac12e --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/README.md @@ -0,0 +1,587 @@ +import Button from '@site/src/components/button' +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Обработка платежей + +Эта страница **объясняет, как обрабатывать** (отправлять и принимать) `цифровые активы` на блокчейне TON. +Здесь **в основном** описывается работа с `монетами TON`, но **теоретическая часть** является **важной**, даже если Вы хотите обрабатывать только `джеттоны`. + +## Смарт-контракт кошелька + +Смарт-контракты кошелька - это контракты в сети TON, которые служат для того, чтобы позволить участникам, находящимся вне блокчейна, взаимодействовать с сущностями блокчейна. В целом, они решают три задачи: + +- удостоверяет подлинность владельца: Отказывается обрабатывать и оплачивать запросы лиц, не являющихся владельцами. +- Защита от повторов: Запрещает повторное выполнение одного запроса, например, отправку активов другому смарт-контракту. +- инициирует произвольное взаимодействие с другими смарт-контрактами. + +Стандартным решением первой задачи является криптография с открытым ключом: `кошелек` хранит открытый ключ и проверяет, что входящее сообщение с запросом подписано соответствующим закрытым ключом, который известен только его владельцу. + +Решение третьей задачи также является общим; обычно запрос содержит полностью сформированное внутреннее сообщение, которое `кошелек` отправляет в сеть. Однако для защиты от воспроизведения существует несколько различных подходов. + +### Кошельки на основе Seqno + +Кошельки на основе Seqno используют наиболее простой подход к определению последовательности сообщений. Каждое сообщение имеет специальное целое число `seqno`, которое должно совпадать со счетчиком, хранящимся в смарт-контракте `wallet`. `wallet` обновляет свой счетчик при каждом запросе, гарантируя тем самым, что один запрос не будет обработан дважды. Существует несколько версий `wallet`, которые отличаются от общедоступных методов: возможность ограничивать запросы по времени истечения срока действия и возможность иметь несколько кошельков с одним и тем же открытым ключом. Однако неотъемлемым требованием такого подхода является отправка запросов по одному, поскольку любой разрыв в последовательности `seqno` приведет к невозможности обработки всех последующих запросов. + +### Кошельки с высокой нагрузкой + +Этот тип `кошелька` использует подход, основанный на хранении идентификатора непросроченных обработанных запросов в хранилище смарт-контрактов. При таком подходе любой запрос проверяется на предмет дублирования уже обработанного запроса и, в случае обнаружения повтора, отбрасывается. Из-за истечения срока действия контракт не может хранить все запросы вечно, но он будет удалять те, которые не могут быть обработаны из-за ограничения срока действия. Запросы к этому `кошельку` могут отправляться параллельно, не мешая друг другу; однако такой подход требует более сложного контроля за обработкой запросов. + +### Развертывание кошелька + +Чтобы развернуть кошелек с помощью TonLib, необходимо: + +1. Сгенерируйте пару закрытый/открытый ключ с помощью [createNewKey](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L244) или ее функций-оберток (пример в [tonlib-go](https://github.com/mercuryoio/tonlib-go/tree/master/v2#create-new-private-key)). Обратите внимание, что закрытый ключ генерируется локально и не покидает хост-машину. +2. Сформируйте структуру [InitialAccountWallet](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L62), соответствующую одному из включенных `кошельков`. В настоящее время доступны `wallet.v3`, `wallet.v4`, `wallet.highload.v1`, `wallet.highload.v2`. +3. Вычислите адрес нового смарт-контракта `кошелька` с помощью метода [getAccountAddress](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L283). Мы рекомендуем использовать ревизию по умолчанию `0`, а также развертывать кошельки в базовой цепи `workchain=0` для снижения платы за обработку и хранение данных. +4. Отправьте несколько Toncoin на вычисленный адрес. Обратите внимание, что отправлять их нужно в режиме `non-bounce`, поскольку этот адрес еще не имеет кода и поэтому не может обрабатывать входящие сообщения. Флаг `non-bounce` указывает, что даже если обработка не удалась, деньги не должны быть возвращены с сообщением об отказе. Мы не рекомендуем использовать флаг `non-bounce` для других транзакций, особенно при переводе больших сумм, поскольку механизм отказов обеспечивает некоторую степень защиты от ошибок. +5. Сформируйте желаемое [действие](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L154), например, `actionNoop` только для развертывания. Затем используйте [createQuery](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L292) и [sendQuery](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L300), чтобы инициировать взаимодействие с блокчейном. +6. Проверьте контракт за несколько секунд с помощью метода [getAccountState](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L288). + +:::tip +Подробнее читайте в [Учебнике по кошельку] (/develop/smart-contracts/tutorials/wallet#-deploying-a-wallet) +::: + +### Проверьте действительность адреса кошелька + +Большинство SDK заставляют Вас проверять адрес (большинство проверяет его в процессе создания кошелька или подготовки транзакции), поэтому, как правило, это не требует от Вас никаких дополнительных сложных действий. + + + + + +```js + const TonWeb = require("tonweb") + TonWeb.utils.Address.isValid('...') +``` + + + + +```python +package main + +import ( + "fmt" + "github.com/xssnick/tonutils-go/address" +) + +if _, err := address.ParseAddr("EQCD39VS5j...HUn4bpAOg8xqB2N"); err != nil { + return errors.New("invalid address") +} +``` + + + + +```javascript +try { + Address.of("..."); + } catch (e) { + // not valid address +} +``` + + + + +```javascript + try { + AddrStd("...") + } catch(e: IllegalArgumentException) { + // not valid address + } +``` + + + + +:::tip +Полное описание адресов на странице [Адреса смарт-контрактов](/learn/overviews/addresses). +::: + +## Работа с переводами + +### Проверьте сделки по контракту + +Транзакции контракта можно получить с помощью метода [getTransactions](https://toncenter.com/api/v2/#/accounts/get_transactions_getTransactions_get). Этот метод позволяет получить 10 транзакций с некоторого `последнего_transaction_id` и более ранних. Чтобы обработать все входящие транзакции, необходимо выполнить следующие шаги: + +1. Последний `последний_транзакционный_ид` можно получить с помощью [getAddressInformation](https://toncenter.com/api/v2/#/accounts/get_address_information_getAddressInformation_get) +2. Список из 10 транзакций должен быть загружен с помощью метода `getTransactions`. +3. Обрабатывайте транзакции с непустым источником во входящем сообщении и адресом назначения, равным адресу счета. +4. Следующие 10 транзакций должны быть загружены, и шаги 2,3,4,5 должны повторяться до тех пор, пока Вы не обработаете все входящие транзакции. + +### Получение входящих/исходящих транзакций + +Можно отслеживать поток сообщений во время обработки транзакций. Поскольку поток сообщений представляет собой DAG, достаточно получить текущую транзакцию с помощью метода [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get) и найти входящую транзакцию по `out_msg` с помощью [tryLocateResultTx](https://testnet.toncenter.com/api/v2/#/transactions/get_try_locate_result_tx_tryLocateResultTx_get) или исходящую транзакцию по `in_msg` с помощью [tryLocateSourceTx](https://testnet.toncenter.com/api/v2/#/transactions/get_try_locate_source_tx_tryLocateSourceTx_get). + + + + +```ts +import { TonClient, Transaction } from '@ton/ton'; +import { getHttpEndpoint } from '@orbs-network/ton-access'; +import { CommonMessageInfoInternal } from '@ton/core'; + +async function findIncomingTransaction(client: TonClient, transaction: Transaction): Promise { + const inMessage = transaction.inMessage?.info; + if (inMessage?.type !== 'internal') return null; + return client.tryLocateSourceTx(inMessage.src, inMessage.dest, inMessage.createdLt.toString()); +} + +async function findOutgoingTransactions(client: TonClient, transaction: Transaction): Promise { + const outMessagesInfos = transaction.outMessages.values() + .map(message => message.info) + .filter((info): info is CommonMessageInfoInternal => info.type === 'internal'); + + return Promise.all( + outMessagesInfos.map((info) => client.tryLocateResultTx(info.src, info.dest, info.createdLt.toString())), + ); +} + +async function traverseIncomingTransactions(client: TonClient, transaction: Transaction): Promise { + const inTx = await findIncomingTransaction(client, transaction); + // now you can traverse this transaction graph backwards + if (!inTx) return; + await traverseIncomingTransactions(client, inTx); +} + +async function traverseOutgoingTransactions(client: TonClient, transaction: Transaction): Promise { + const outTxs = await findOutgoingTransactions(client, transaction); + // do smth with out txs + for (const out of outTxs) { + await traverseOutgoingTransactions(client, out); + } +} + +async function main() { + const endpoint = await getHttpEndpoint({ network: 'testnet' }); + const client = new TonClient({ + endpoint, + apiKey: '[API-KEY]', + }); + + const transaction: Transaction = ...; // Obtain first transaction to start traversing + await traverseIncomingTransactions(client, transaction); + await traverseOutgoingTransactions(client, transaction); +} + +main(); +``` + + + + +### Отправляйте платежи + +1. Сервис должен развернуть `кошелек` и постоянно пополнять его, чтобы предотвратить разрушение контракта из-за платы за хранение. Обратите внимание, что плата за хранение обычно составляет менее 1 Тонкоина в год. +2. Сервис должен получить от пользователя `адрес_назначения` и необязательный `комментарий`. Обратите внимание, что на данный момент мы рекомендуем либо запретить незавершенные исходящие платежи с одинаковым набором (`адрес_назначения`, `значение`, `комментарий`), либо правильно планировать эти платежи; таким образом, следующий платеж будет инициирован только после подтверждения предыдущего. +3. Сформируйте [msg.dataText](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L103) с `comment` в качестве текста. +4. Форма [msg.message](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L113), содержащая `адрес_назначения`, пустой `публичный_ключ`, `сумму` и `msg.dataText`. +5. Форма [Действие](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L154), содержащая набор исходящих сообщений. +6. Используйте запросы [createQuery](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L292) и [sendQuery](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L300) для отправки исходящих платежей. +7. Сервис должен регулярно опрашивать метод [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get) для контракта `wallet`. Сопоставление подтвержденных транзакций с исходящими платежами по (`адрес_назначения`, `значение`, `комментарий`) позволяет пометить платежи как завершенные; обнаружить и показать пользователю соответствующий хэш транзакции и lt (логическое время). +8. Запросы к `v3` кошелькам с `высокой нагрузкой` по умолчанию имеют время истечения, равное 60 секундам. По истечении этого времени необработанные запросы могут быть безопасно повторно отправлены в сеть (см. шаги 3-6). + +### Получите идентификатор транзакции + +Может быть неясно, что для получения дополнительной информации о транзакции пользователь должен просканировать блокчейн с помощью функции [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get). +Невозможно получить идентификатор транзакции сразу после отправки сообщения, поскольку транзакция сначала должна быть подтверждена сетью блокчейн. +Чтобы понять, что требуется для этого, внимательно прочитайте [Send payments](https://docs.ton.org/develop/dapps/asset-processing/#send-payments), особенно 7-й пункт. + +## Подход на основе счета-фактуры + +Чтобы принимать платежи на основании прикрепленных комментариев, сервис должен + +1. Разверните контракт `wallet`. +2. Сгенерируйте уникальный `счет` для каждого пользователя. Строкового представления uuid32 будет достаточно. +3. Пользователям следует дать указание отправить Тонкоин на `кошелек` сервиса с приложенным `счетом-фактурой` в качестве комментария. +4. Сервис должен регулярно опрашивать метод [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get) для контракта `wallet`. +5. Для новых транзакций входящее сообщение должно быть извлечено, `комментарий` сопоставлен с базой данных, а **значение входящего сообщения** зачислено на счет пользователя. + +Чтобы вычислить **значение входящего сообщения**, которое сообщение приносит контракту, необходимо разобрать транзакцию. Это происходит, когда сообщение попадает в контракт. Транзакцию можно получить с помощью [getTransactions](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L268). Для входящей транзакции кошелька правильные данные состоят из одного входящего сообщения и нуля исходящих сообщений. В противном случае либо в кошелек отправляется внешнее сообщение, и тогда владелец тратит Toncoin, либо кошелек не развернут, и входящая транзакция возвращается обратно. + +В любом случае, в общем случае, сумма, которую сообщение приносит контракту, может быть рассчитана как стоимость входящего сообщения минус сумма стоимостей исходящих сообщений минус комиссия: `value_{in_msg} - SUM(value_{out_msg}) - fee`. Технически, представление транзакций содержит три различных поля с `fee` в имени: `fee`, `storage_fee` и `other_fee`, то есть общая плата, часть платы, связанная с расходами на хранение, и часть платы, связанная с обработкой транзакций. Следует использовать только первую. + +### Счета-фактуры с помощью TON Connect + +Лучше всего подходит для dApp, которым нужно подписывать несколько платежей/транзакций в течение сессии или поддерживать соединение с кошельком в течение некоторого времени. + +- ✅ Существует постоянный канал связи с кошельком, информация об адресе пользователя + +- ✅ Пользователям нужно сканировать QR-код только один раз + +- ✅ Можно узнать, подтвердил ли пользователь транзакцию в кошельке, отследить транзакцию по возвращенному BOC + +- ✅ Готовые SDK и наборы пользовательского интерфейса доступны для разных платформ + +- ❌ Если Вам нужно отправить только один платеж, пользователю необходимо выполнить два действия: подключить кошелек и подтвердить транзакцию + +- ❌ Интеграция сложнее, чем просто ссылка ton://. + +```mdx-code-block + +``` + +### Счета-фактуры со ссылкой ton:// + +:::warning +Ссылка Ton устарела, избегайте ее использования +::: + +Если Вам нужна простая интеграция для простого потока пользователей, лучше всего использовать ссылку ton://. +Лучше всего подходит для разовых платежей и счетов-фактур. + +```bash +ton://transfer/? + [nft=&] + [fee-amount=&] + [forward-amount=] +``` + +- ✅ Легкая интеграция + +- ✅ Нет необходимости подключать кошелек + +- ❌ Пользователям необходимо сканировать новый QR-код для каждого платежа + +- ❌ Невозможно отследить, подписал ли пользователь транзакцию или нет. + +- ❌ Нет информации об адресе пользователя + +- ❌ Необходимы обходные пути на платформах, где такие ссылки не кликабельны (например, сообщения от ботов для настольных клиентов Telegram). + +[Подробнее о тонких ссылках здесь](https://github.com/tonkeeper/wallet-api#payment-urls) + +## Explorers + +Исследователь блокчейна - https://tonscan.org. + +Чтобы создать ссылку на транзакцию в проводнике, служба должна получить lt (логическое время), хэш транзакции и адрес счета (адрес счета, для которого lt и txhash были получены с помощью метода [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get)). https://tonscan.org и https://explorer.toncoin.org/ могут затем показать страницу для этого tx в следующем формате: + +`https://tonviewer.com/transaction/{txhash as base64url}`. + +`https://tonscan.org/tx/{lt as int}:{txhash as base64url}:{account address}` + +`https://explorer.toncoin.org/transaction?account={account address}<={lt as int}&hash={txhash as base64url}` + +## Лучшие практики + +### Создание кошелька + + + + +- **toncenter:** + - [Создание кошелька + получение адреса кошелька](https://github.com/toncenter/examples/blob/main/common.js) + +- **ton-community/ton:** + - [Создание кошелька + получение баланса](https://github.com/ton-community/ton#usage) + + + + + +- **xssnick/tonutils-go:**. + - [Создание кошелька + получение баланса](https://github.com/xssnick/tonutils-go?tab=readme-ov-file#wallet) + + + + + +- **psylopunk/pythonlib:**. + - [Создание кошелька + получение адреса кошелька](https://github.com/psylopunk/pytonlib/blob/main/examples/generate_wallet.py) +- **yungwine/pytoniq:**. + +```py +import asyncio + +from pytoniq.contract.wallets.wallet import WalletV4R2 +from pytoniq.liteclient.balancer import LiteBalancer + + +async def main(): + provider = LiteBalancer.from_mainnet_config(2) + await provider.start_up() + + mnemonics, wallet = await WalletV4R2.create(provider) + print(f"{wallet.address=} and {mnemonics=}") + + await provider.close_all() + + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + + +### Депозиты в тонкоинах (Получите тонкоины) + + + + +- **toncenter:** + - [Обработать депозит в Toncoins](https://github.com/toncenter/examples/blob/main/deposits.js) + - [Обработка депозита Toncoins на несколько кошельков](https://github.com/toncenter/examples/blob/main/deposits-multi-wallets.js) + + + + + +- **xssnick/tonutils-go:**. + +
+Депозиты в чеках + +```go +package main + +import ( + "context" + "encoding/base64" + "log" + + "github.com/xssnick/tonutils-go/address" + "github.com/xssnick/tonutils-go/liteclient" + "github.com/xssnick/tonutils-go/ton" +) + +const ( + num = 10 +) + +func main() { + client := liteclient.NewConnectionPool() + err := client.AddConnectionsFromConfigUrl(context.Background(), "https://ton.org/global.config.json") + if err != nil { + panic(err) + } + + api := ton.NewAPIClient(client, ton.ProofCheckPolicyFast).WithRetry() + + accountAddr := address.MustParseAddr("0QA__NJI1SLHyIaG7lQ6OFpAe9kp85fwPr66YwZwFc0p5wIu") + + // we need fresh block info to run get methods + b, err := api.CurrentMasterchainInfo(context.Background()) + if err != nil { + log.Fatal(err) + } + + // we use WaitForBlock to make sure block is ready, + // it is optional but escapes us from liteserver block not ready errors + res, err := api.WaitForBlock(b.SeqNo).GetAccount(context.Background(), b, accountAddr) + if err != nil { + log.Fatal(err) + } + + lastTransactionId := res.LastTxHash + lastTransactionLT := res.LastTxLT + + headSeen := false + + for { + trxs, err := api.ListTransactions(context.Background(), accountAddr, num, lastTransactionLT, lastTransactionId) + if err != nil { + log.Fatal(err) + } + + for i, tx := range trxs { + // should include only first time lastTransactionLT + if !headSeen { + headSeen = true + } else if i == 0 { + continue + } + + if tx.IO.In == nil || tx.IO.In.Msg.SenderAddr().IsAddrNone() { + // external message should be omitted + continue + } + + if tx.IO.Out != nil { + // no outgoing messages - this is incoming Toncoins + continue + } + + // process trx + log.Printf("found in transaction hash %s", base64.StdEncoding.EncodeToString(tx.Hash)) + } + + if len(trxs) == 0 || (headSeen && len(trxs) == 1) { + break + } + + lastTransactionId = trxs[0].Hash + lastTransactionLT = trxs[0].LT + } +} +``` + +
+
+ + + +- **yungwine/pytoniq:**. + +Депозиты в чеках + +```python +import asyncio + +from pytoniq_core import Transaction + +from pytoniq import LiteClient, Address + +MY_ADDRESS = Address("kf8zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM_BP") + + +async def main(): + client = LiteClient.from_mainnet_config(ls_i=0, trust_level=2) + + await client.connect() + + last_block = await client.get_trusted_last_mc_block() + + _account, shard_account = await client.raw_get_account_state(MY_ADDRESS, last_block) + assert shard_account + + last_trans_lt, last_trans_hash = ( + shard_account.last_trans_lt, + shard_account.last_trans_hash, + ) + + while True: + print(f"Waiting for{last_block=}") + + transactions = await client.get_transactions( + MY_ADDRESS, 1024, last_trans_lt, last_trans_hash + ) + toncoin_deposits = [tx for tx in transactions if filter_toncoin_deposit(tx)] + print(f"Got {len(transactions)=} with {len(toncoin_deposits)=}") + + for deposit_tx in toncoin_deposits: + # Process toncoin deposit transaction + print(deposit_tx.cell.hash.hex()) + + last_trans_lt = transactions[0].lt + last_trans_hash = transactions[0].cell.hash + + +def filter_toncoin_deposit(tx: Transaction): + if tx.out_msgs: + return False + + if tx.in_msg: + return False + + return True + + +if __name__ == "__main__": + asyncio.run(main()) +``` + + +
+ +### Вывод Тонкоинов (Отправить Тонкоины) + + + + +- **toncenter:** + - [Вывод Тонкоинов из кошелька партиями](https://github.com/toncenter/examples/blob/main/withdrawals-highload-batch.js) + - [Вывести Тонкоины из кошелька](https://github.com/toncenter/examples/blob/main/withdrawals-highload.js) + +- **ton-community/ton:** + - [Вывести Тонкоины из кошелька](https://github.com/ton-community/ton#usage) + + + + + +- **xssnick/tonutils-go:**. + - [Вывести Тонкоины из кошелька](https://github.com/xssnick/tonutils-go?tab=readme-ov-file#wallet) + + + + + +- **psylopunk/pythonlib:**. + - [Вывести Тонкоины из кошелька](https://github.com/psylopunk/pytonlib/blob/main/examples/transactions.py) + +- **yungwine/pytoniq:**. + +```python +import asyncio + +from pytoniq_core import Address +from pytoniq.contract.wallets.wallet import WalletV4R2 +from pytoniq.liteclient.balancer import LiteBalancer + + +MY_MNEMONICS = "one two tree ..." +DESTINATION_WALLET = Address("Destination wallet address") + + +async def main(): + provider = LiteBalancer.from_mainnet_config() + await provider.start_up() + + wallet = await WalletV4R2.from_mnemonic(provider, MY_MNEMONICS) + + await wallet.transfer(DESTINATION_WALLET, 5) + + await provider.close_all() + + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + + +### Получите транзакции контракта + + + + +- **ton-community/ton:** + - [Клиент с методом getTransaction](https://github.com/ton-community/ton/blob/master/src/client/TonClient.ts) + + + + + +- **xssnick/tonutils-go:**. + - [Получить транзакции] (https://github.com/xssnick/tonutils-go?tab=readme-ov-file#account-info-and-transactions) + + + + + +- **psylopunk/pythonlib:**. + - [Получить транзакции] (https://github.com/psylopunk/pytonlib/blob/main/examples/transactions.py) +- **yungwine/pytoniq:**. + - [Получить транзакции] (https://github.com/yungwine/pytoniq/blob/master/examples/transactions.py) + + + + + +## SDKs + +Вы можете найти список SDK для различных языков (JS, Python, Golang, C#, Rust и т.д.) список [здесь](/develop/dapps/apis/sdk). diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md b/i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md new file mode 100644 index 0000000000..437ce0869f --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md @@ -0,0 +1,1205 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import Button from '@site/src/components/button'; + +# Тонна переработки Jetton + +:::info +Для ясного понимания читатель должен быть знаком с основными принципами обработки активов, описанными в [разделе обработки платежей](/develop/dapps/asset-processing/) нашей документации. +::: + +Джеттоны - это токены на блокчейне TON - их можно рассматривать аналогично токенам ERC-20 на Ethereum. + +В этом анализе мы глубже погружаемся в формальные стандарты, подробно описывающие [поведение] (https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md) и [метаданные] (https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md) jetton. +Менее формальный обзор архитектуры jetton, ориентированный на шардинг, можно найти в нашем блоге +[анатомия jettons](https://blog.ton.org/how-to-shard-your-ton-smart-contract-and-why-studying-the-anatomy-of-tons-jettons). + +Также Вам следует помнить, что существует два подхода к работе с выводами средств из jetton: + +- [Memo Deposits](https://github.com/toncenter/examples/blob/main/deposits-jettons.js) - Это позволяет Вам держать один депозитный кошелек, а пользователи добавляют в него памятку, чтобы быть идентифицированными Вашей системой. Это означает, что Вам не нужно сканировать весь блокчейн, но это немного менее удобно для пользователей. +- [Депозиты без мемо](https://github.com/gobicycle/bicycle) - Это решение также существует, но его сложнее интегрировать. Тем не менее, мы можем помочь Вам, если Вы хотите пойти этим путем. Пожалуйста, уведомите нас, прежде чем принять решение о применении этого подхода. + +## Jetton Architecture + +Стандартизированные токены TON реализуются с помощью набора смарт-контрактов, включая: + +- [Jetton master](https://github.com/ton-blockchain/token-contract/blob/main/ft/jetton-minter.fc) смарт-контракт +- [Кошелек Jetton](https://github.com/ton-blockchain/token-contract/blob/main/ft/jetton-wallet.fc) смарт-контракты + +

+
+ contracts scheme +
+

+ +## Главный смарт-контракт Jetton + +Главный смарт-контракт jetton хранит общую информацию о джеттоне (включая общий запас, ссылку на метаданные или сами метаданные). + +:::warning Остерегайтесь мошенничества от Jetton + +Джеттоны с `символом`==`TON` или те, которые содержат системные уведомления, такие как: +`ERROR`, `SYSTEM` и другие. Обязательно проверьте, что джеттоны отображаются в Вашем интерфейсе таким образом, чтобы их нельзя было +смешать с передачей TON, системными уведомлениями и т.д.. Иногда даже `symbol`, `name` и `image` +создаются так, чтобы выглядеть почти идентично оригиналу, в надежде ввести пользователей в заблуждение. + +Чтобы исключить возможность мошенничества для пользователей TON, пожалуйста, посмотрите **оригинальный адрес джеттона** (Jetton master contract) для конкретных типов джеттонов или **следуйте за официальным каналом проекта в социальных сетях** или веб-сайтом, чтобы найти **корректную информацию**. Проверьте активы, чтобы исключить возможность мошенничества, с помощью [Tonkeeper ton-assets list](https://github.com/tonkeeper/ton-assets). +::: + +### Извлечение данных Jetton + +Чтобы получить более конкретные данные Jetton, используйте метод *get* контракта `get_jetton_data()`. + +Этот метод возвращает следующие данные: + +| Имя | Тип | Описание | +| -------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `total_supply` | `int` | общее количество выпущенных джеттонов, измеренное в неделимых единицах. | +| `mintable` | `int` | Подробно описывает, можно ли чеканить новые джеттоны или нет. Это значение равно либо -1 (можно чеканить), либо 0 (нельзя чеканить). | +| `admin_address` | `slice` | | +| `jetton_content` | `ячейка` | Данные в соответствии с [TEP-64](https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md), подробнее смотрите на странице [jetton metadata parsing page](/develop/dapps/asset-processing/metadata). | +| `jetton_wallet_code` | `ячейка` | | + +Вы можете вызвать его через [Toncenter API](https://toncenter.com/api/v3/#/default/get_jetton_masters_api_v3_jetton_masters_get) или один из [SDK](https://docs.ton.org/develop/dapps/apis/sdk). + + + + +> Запустите метод `jetton/masters` из [Toncenter API] (https://toncenter.com/api/v3/#/default/get_jetton_masters_api_v3_jetton_masters_get) + + + + +```js +import TonWeb from "tonweb"; +const tonweb = new TonWeb(); +const jettonMinter = new TonWeb.token.jetton.JettonMinter(tonweb.provider, {address: ""}); +const data = await jettonMinter.getJettonData(); +console.log('Total supply:', data.totalSupply.toString()); +console.log('URI to off-chain metadata:', data.jettonContentUri); +``` + + + + +### Джеттон минтер + +Как уже упоминалось, джеттоны могут быть как `мятными`, так и `немятными`. + +Если они не чеканятся, логика становится простой - нет возможности чеканить дополнительные жетоны. Для первой чеканки джеттонов обратитесь к странице [Mint your first jetton](/develop/dapps/tutorials/jetton-minter). + +Если джеттоны можно чеканить, в контракте [minter contract](https://github.com/ton-blockchain/minter-contract/blob/main/contracts/jetton-minter.fc) есть специальная функция для чеканки дополнительных джеттонов. Эту функцию можно вызвать, отправив с адреса администратора `внутреннее сообщение` с указанным опкодом. + +Если администратор jetton хочет ограничить создание jetton, есть три способа сделать это: + +1. Если Вы не можете или не хотите обновлять код контракта, администратору необходимо передать право собственности от текущего администратора на нулевой адрес. В результате контракт останется без действующего администратора, что не позволит никому чеканить джеттоны. Однако это также предотвратит любые изменения в метаданных джеттона. +2. Если у Вас есть доступ к исходному коду и Вы можете его изменить, Вы можете создать метод в контракте, который устанавливает флаг для прерывания любого процесса чеканки после его вызова, и добавить оператор для проверки этого флага в функцию mint. +3. Если Вы можете обновить код контракта, Вы можете добавить ограничения, обновив код уже развернутого контракта. + +## Смарт-контракт для кошелька Jetton + +Контракты `Jetton wallet` используются для **отправки**, **получения** и **сжигания** джеттонов. Каждый контракт *кошелька джеттона* хранит информацию о балансе кошелька для конкретных пользователей. +В отдельных случаях джеттоновые кошельки используются для отдельных держателей джеттонов каждого типа. + +`Джеттон-кошельки` **не следует путать с кошельками**, предназначенными для взаимодействия с блокчейном и хранения +только актива Toncoin (например, кошельки v3R2, highload-кошельки и другие), +которые отвечают за поддержку и управление **только определенным типом джеттона**. + +### Развертывание кошелька Jetton + +При `передаче джеттонов` между кошельками транзакции (сообщения) требуют определенного количества TON +в качестве оплаты сетевых **газовых сборов** и выполнения действий в соответствии с кодом контракта кошелька Jetton. +Это означает, что **получателю не нужно разворачивать кошелек jetton перед получением джеттонов**. +Кошелек Jetton получателя будет развернут автоматически, пока отправитель имеет в кошельке достаточное количество TON +, чтобы оплатить необходимые сборы за газ. + +### Получение адресов кошельков Jetton для данного пользователя + +Чтобы получить `адрес` кошелька `jetton` с помощью `адреса владельца` (адреса кошелька TON), +главный контракт `Jetton` предоставляет метод get `get_wallet_address(slice owner_address)`. + + + + +> Запустите `get_wallet_address(slice owner_address)` через метод `/runGetMethod` из [Toncenter API](https://toncenter.com/api/v3/#/default/run_get_method_api_v3_runGetMethod_post). + + + + +```js +import TonWeb from "tonweb"; +const tonweb = new TonWeb(); +const jettonMinter = new TonWeb.token.jetton.JettonMinter(tonweb.provider, {address: ""}); +const address = await jettonMinter.getJettonWalletAddress(new TonWeb.utils.Address("")); +// It is important to always check that wallet indeed is attributed to desired Jetton Master: +const jettonWallet = new TonWeb.token.jetton.JettonWallet(tonweb.provider, { + address: jettonWalletAddress +}); +const jettonData = await jettonWallet.getData(); +if (jettonData.jettonMinterAddress.toString(false) !== new TonWeb.utils.Address(info.address).toString(false)) { + throw new Error('jetton minter address from jetton wallet doesnt match config'); +} + +console.log('Jetton wallet address:', address.toString(true, true, true)); +``` + + + + +### Получение данных для определенного кошелька Jetton + +Чтобы получить баланс кошелька, идентификационные данные владельца и другую информацию, относящуюся к конкретному контракту кошелька jetton, используйте метод `get_wallet_data()` для получения данных в контракте кошелька jetton. + +Этот метод возвращает следующие данные: + +| Имя | Тип | +| -------------------- | -------- | +| `баланс` | int | +| `владелец` | нарезать | +| `jetton` | нарезать | +| `jetton_wallet_code` | клетка | + + + + +> Используйте метод `/jetton/wallets` get из [Toncenter API](https://toncenter.com/api/v3/#/default/get_jetton_wallets_api_v3_jetton_wallets_get), чтобы получить ранее расшифрованные данные кошелька jetton. + + + + + +```js +import TonWeb from "tonweb"; +const tonweb = new TonWeb(); +const walletAddress = "EQBYc3DSi36qur7-DLDYd-AmRRb4-zk6VkzX0etv5Pa-Bq4Y"; +const jettonWallet = new TonWeb.token.jetton.JettonWallet(tonweb.provider,{address: walletAddress}); +const data = await jettonWallet.getData(); +console.log('Jetton balance:', data.balance.toString()); +console.log('Jetton owner address:', data.ownerAddress.toString(true, true, true)); +// It is important to always check that Jetton Master indeed recognize wallet +const jettonMinter = new TonWeb.token.jetton.JettonMinter(tonweb.provider, {address: data.jettonMinterAddress.toString(false)}); +const expectedJettonWalletAddress = await jettonMinter.getJettonWalletAddress(data.ownerAddress.toString(false)); +if (expectedJettonWalletAddress.toString(false) !== new TonWeb.utils.Address(walletAddress).toString(false)) { + throw new Error('jetton minter does not recognize the wallet'); +} + +console.log('Jetton master address:', data.jettonMinterAddress.toString(true, true, true)); +``` + + + + +## Обзор коммуникаций с кошельками Jetton + +Обмен данными между кошельками Jetton и кошельками TON происходит в следующей последовательности: + +![](/img/docs/asset-processing/jetton_transfer.svg) + +#### Сообщение 0 + +`Отправитель -> кошелек jetton отправителя`. Сообщение *Transfer* содержит следующие данные: + +| Имя | Тип | Описание | +| ---------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `query_id` | uint64 | Позволяет приложениям связывать между собой три типа сообщений `Передача`, `Уведомление о передаче` и `Излишки`. Чтобы этот процесс выполнялся правильно, рекомендуется **всегда использовать уникальный идентификатор запроса**. | +| `сумма` | монеты | Общее количество `тонн монет`, которое будет отправлено с сообщением. | +| `назначение` | адрес | Адрес нового владельца джеттонов | +| `response_destination` | адрес | Адрес кошелька, используемый для возврата оставшихся тонн монет с сообщением о превышении. | +| `custom_payload` | возможно, клетка | Размер всегда >= 1 бит. Пользовательские данные (которые используются либо отправителем, либо получателем кошелька jetton для внутренней логики). | +| `передняя_тонна_суммы` | монеты | Должно быть > 0, если Вы хотите отправить `уведомление о передаче` с `передаваемой полезной нагрузкой`. Это **часть значения `суммы`** и **должно быть меньше, чем `сумма`**. | +| `forward_payload` | возможно, клетка | Размер всегда >= 1 биту. Если первые 32 бита = 0x0, то это простое сообщение. | + +#### Сообщение 2' + +Кошелек jetton -> payee`. Сообщение-уведомление о переводе. **Отправляется только в том случае, если** `переданная_тонная_сумма\` **не нулевая**. Содержит следующие данные: + +| Имя | Тип | +| ----------------- | ------ | +| `query_id` | uint64 | +| `сумма` | монеты | +| `sender` | адрес | +| `forward_payload` | клетка | + +Здесь адрес `отправителя` - это адрес `Джеттон-кошелька` Алисы. + +#### Сообщение 2'' + +Кошелек jetton от `payee` -> Отправитель\`. Тело сообщения. **Отправляется только в том случае, если после оплаты взносов остались монеты тонны**. Содержит следующие данные: + +| Имя | Тип | +| ---------- | ------ | +| `query_id` | uint64 | + +:::tip Стандартные джеттоны +Подробное описание полей контракта кошелька jetton можно найти в описании интерфейса [TEP-74](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md) `Jetton standard`. +::: + +## Отправить джеттоны с комментариями + +Для этого перевода потребуется несколько тонн монет для **fees** и, по желанию, **сообщение об уведомлении о переводе** (проверьте поле "Сумма перевода"). + +Для отправки **комментария** Вам необходимо настроить `передачу полезной нагрузки`. Установите **первые 32 бита в 0x0** и добавьте **ваш текст**. + +`Передаваемая полезная нагрузка` отправляется во внутреннем сообщении `уведомление о переводе`. Оно будет сгенерировано только в том случае, если `переданная сумма` > 0. + +Наконец, чтобы получить сообщение `Excess`, Вы должны настроить `назначение ответа`. + +:::tip +Проверьте [лучшие практики](/develop/dapps/asset-processing/jettons#best-practices) на примере *"отправлять джеттоны с комментариями"*. +::: + +## Внецепочечная обработка Jetton + +:::info Подтверждение транзакции +Транзакции TON становятся необратимыми после одного подтверждения. Для достижения наилучшего пользовательского опыта рекомендуется избегать ожидания дополнительных блоков после завершения транзакций на блокчейне TON. Подробнее читайте в [Catchain.pdf](https://docs.ton.org/catchain.pdf#page=3). +::: + +Существует два способа приема джеттонов: + +- в рамках **централизованного горячего кошелька**. +- использование кошелька с **отдельным адресом** для **каждого отдельного пользователя**. + +В целях безопасности предпочтительно иметь **отдельные горячие кошельки** для **отдельных джеттонов** (много кошельков для каждого типа активов). + +При обработке средств также рекомендуется предусмотреть "холодный" кошелек для хранения избыточных средств, которые не участвуют в процессах автоматического ввода и вывода. + +### Добавление новых джеттонов для обработки активов и первичной проверки + +1. Найдите правильный адрес [смарт-контракта] (/develop/dapps/asset-processing/jettons#jetton-master-smart-contract). +2. Получите [метаданные](/develop/dapps/asset-processing/jettons#retrieving-jetton-data). +3. Проверьте наличие [мошенничества](/develop/dapps/asset-processing/jettons#jetton-master-smart-contract). + +### Идентификация неизвестного Jetton при получении сообщения об уведомлении о передаче + +Если в Ваш кошелек поступило уведомление о переводе неизвестного Jetton, значит, Ваш кошелек +был создан для хранения конкретного Jetton. + +Адрес отправителя внутреннего сообщения, содержащего тело `Transfer notification`, - это адрес нового кошелька Jetton. +Его не следует путать с полем `отправитель` в теле сообщения `Уведомление о переводе` (/develop/dapps/asset-processing/jettons#jetton-wallets-communication-overview). + +1. Получите главный адрес Jetton для нового кошелька Jetton, используя [получение данных кошелька] (/develop/dapps/asset-processing/jettons#retrieving-data-for-a-specific-jetton-wallet). +2. Получите адрес кошелька Jetton для Вашего адреса кошелька (как владельца), используя главный контракт Jetton: [Как получить адрес кошелька Jetton для данного пользователя](#retrieving-jetton-wallet-addresses-for-a-given-user) +3. Сравните адрес, возвращенный главным контрактом, и фактический адрес токена в кошельке. + Если они совпадают, то это идеальный вариант. Если нет, то, скорее всего, Вы получили мошеннический токен, который является подделкой. +4. Получение метаданных Jetton: [Как получить метаданные Jetton] (#retrieving-jetton-data). +5. Проверьте поля `symbol` и `name` на наличие признаков мошенничества. При необходимости предупредите пользователя. [Добавление нового джеттона для обработки и первичной проверки](#adding-new-jettons-for-asset-processing-and-initial-verification). + +### Прием джеттонов от пользователей через централизованный кошелек + +:::info +Чтобы не допустить узкого места в транзакциях, поступающих на один кошелек, рекомендуется принимать депозиты на несколько кошельков и расширять их количество по мере необходимости. +::: + +В этом сценарии платежный сервис создает уникальный идентификатор мемо для каждого отправителя, раскрывая +адрес централизованного кошелька и отправляемые суммы. Отправитель посылает токены +на указанный централизованный адрес с обязательной памяткой в комментарии. + +**Плюсы этого метода:** Этот метод очень прост, поскольку при приеме токенов не взимается никаких дополнительных комиссий, и они поступают непосредственно в горячий кошелек. + +**Недостатки этого метода:** этот метод требует, чтобы все пользователи прикрепляли комментарий к переводу, что может привести к большему количеству ошибок при внесении средств (забытые записки, неправильные записки и т.д.), что означает большую нагрузку на сотрудников службы поддержки. + +Примеры Tonweb: + +1. [Прием депозитов Jetton на индивидуальный кошелек HOT с комментариями (памятка)](https://github.com/toncenter/examples/blob/main/deposits-jettons.js) +2. [Пример снятия денег с карты Jettons](https://github.com/toncenter/examples/blob/main/withdrawals-jettons.js) + +#### Препараты + +1. [Подготовьте список принятых джеттонов](/develop/dapps/asset-processing/jettons#adding-new-jettons-for-asset-processing-and-initial-verification) (адреса мастеров джеттонов). +2. Разверните горячий кошелек (используя v3R2, если не ожидается вывод средств с Jetton; highload v3 - если ожидается вывод средств с Jetton). [Развертывание кошелька](/develop/dapps/asset-processing/#wallet-deployment). +3. Выполните тестовый перевод Jetton, используя адрес "горячего" кошелька, чтобы инициализировать кошелек. + +#### Обработка поступающих джеттонов + +1. Загрузите список принятых джеттонов. +2. [Получите адрес кошелька Jetton] (#retrieving-jetton-wallet-addresses-for-a-given-user) для Вашего развернутого горячего кошелька. +3. Получите главный адрес Jetton для каждого кошелька Jetton, используя [получение данных кошелька] (/develop/dapps/asset-processing/jettons#retrieving-data-for-a-specific-jetton-wallet). +4. Сравните адреса основных контрактов Jetton из шага 1. и шага 3 (непосредственно выше). + Если адреса не совпадают, необходимо сообщить об ошибке проверки адреса Jetton. +5. Получите список последних необработанных транзакций по счету "горячего" кошелька и + проведите его итерацию (сортируя каждую транзакцию по очереди). См: [Проверка транзакций контракта](https://docs.ton.org/develop/dapps/asset-processing/#checking-contracts-transactions). +6. Проверьте входное сообщение (in_msg) на наличие транзакций и извлеките адрес источника из входного сообщения. [Пример Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-jettons-single-wallet.js#L84) +7. Если исходный адрес совпадает с адресом в кошельке Jetton, то необходимо продолжить обработку транзакции. + Если нет, то пропустите обработку транзакции и проверьте следующую транзакцию. +8. Убедитесь, что тело сообщения не пустое и что первые 32 бита сообщения соответствуют коду операции `transfer notification` `0x7362d09c`. + [Пример Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-jettons-single-wallet.js#L91) + Если тело сообщения пустое или оп-код недействителен - пропустите транзакцию. +9. Прочитайте другие данные тела сообщения, включая `query_id`, `amount`, `sender`, `forward_payload`. + [Макеты сообщений для контрактов Jetton](#jetton-contract-message-layouts), [Пример Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-jettons-single-wallet.js#L105) +10. Попытайтесь извлечь текстовые комментарии из данных `forward_payload`. Первые 32 бита должны совпадать с + оп-кодом текстового комментария `0x000000`, а остальные - с текстом в кодировке UTF-8. + [Пример Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-jettons-single-wallet.js#L110) +11. Если данные `forward_payload` пусты или код операции недействителен - пропустите транзакцию. +12. Сравните полученный комментарий с сохраненными заметками. Если есть совпадение (идентификация пользователя всегда возможна) - пополните счет. +13. Перезапустите с шага 5 и повторяйте процесс до тех пор, пока не пройдете весь список транзакций. + +### Прием джеттонов с депозитных адресов пользователей + +Чтобы принимать джеттоны с депозитных адресов пользователей, необходимо, чтобы платежный сервис создавал +собственный индивидуальный адрес (депозит) для каждого участника, отправляющего средства. Предоставление услуг в этом случае предполагает +выполнение нескольких параллельных процессов, включая создание новых депозитов, сканирование блоков на предмет транзакций, +вывод средств с депозитов на горячий кошелек и так далее. + +Поскольку горячий кошелек может использовать один кошелек Jetton для каждого типа Jetton, необходимо создать несколько кошельков +для инициирования депозитов. Чтобы создать большое количество кошельков, но в то же время управлять ими с помощью +одной начальной фразы (или закрытого ключа), необходимо указывать различные `subwallet_id` при создании кошелька. +На TON функциональность, необходимая для создания подкошелька, поддерживается кошельками версии v3 и выше. + +#### Создание субкошелька в Tonweb + +```js +const WalletClass = tonweb.wallet.all['v3R2']; +const wallet = new WalletClass(tonweb.provider, { + publicKey: keyPair.publicKey, + wc: 0, + walletId: , +}); +``` + +#### Подготовка + +1. [Подготовьте список принятых джеттонов](#adding-new-jettons-for-asset-processing-and-initial-verification). +2. Разверните горячий кошелек (используя v3R2, если не ожидается вывод средств с Jetton; highload v3 - если ожидается вывод средств с Jetton). [Развертывание кошелька](/develop/dapps/asset-processing/#wallet-deployment). + +#### Создание депозитов + +1. Примите запрос на создание нового депозита для пользователя. +2. Сгенерируйте новый адрес субкошелька (v3R2) на основе семян горячего кошелька. [Создание субкошелька в Tonweb](#creating-a-subwallet-in-tonweb) +3. Адрес получения может быть указан пользователю как адрес, используемый для депозитов Джеттон (это адрес + владельца депозитного кошелька Джеттон). Инициализация кошелька не требуется, это можно + сделать при выводе Джеттонов с депозита. +4. Для получения этого адреса необходимо вычислить адрес кошелька Jetton через главный контракт Jetton. + [Как получить адрес кошелька Jetton для данного пользователя] (#retrieving-jetton-wallet-addresses-for-a-given-user). +5. Добавьте адрес кошелька Jetton в пул адресов для мониторинга транзакций и сохраните адрес субкошелька. + +#### Обработка транзакций + +:::info Подтверждение транзакции +Транзакции TON становятся необратимыми после одного подтверждения. Для достижения наилучшего пользовательского опыта рекомендуется избегать ожидания дополнительных блоков после завершения транзакций на блокчейне TON. Подробнее читайте в [Catchain.pdf](https://docs.ton.org/catchain.pdf#page=3). +::: + +Не всегда можно определить точное количество джеттонов, полученных из сообщения, поскольку кошельки Jetton +могут не отправлять сообщения `уведомления о переводе`, `дополнения` и `внутренний перевод`. Они не стандартизированы. Это означает, +что нет никакой гарантии, что сообщение `внутренней передачи` может быть декодировано. + +Поэтому, чтобы определить сумму, поступившую в кошелек, необходимо запросить баланс с помощью метода get. +Для получения ключевых данных при запросе баланса используются блоки в соответствии с состоянием счета для конкретного блока на цепи. +[Подготовка к приему блоков с помощью Tonweb](https://github.com/toncenter/tonweb/blob/master/src/test-block-subscribe.js). + +Этот процесс осуществляется следующим образом: + +1. Подготовка к приему блоков (подготовка системы к приему новых блоков). +2. Извлеките новый блок и сохраните ID предыдущего блока. +3. Получайте транзакции из блоков. +4. Фильтруйте транзакции, используемые только с адресами из пула депозитных кошельков Jetton. +5. Декодируйте сообщения, используя тело `transfer notification`, чтобы получить более подробные данные, включая адрес + `отправителя`, сумму Джеттона и комментарий. (См.: [Обработка входящих джеттонов](#processing-incoming-jettons)) +6. Если в рамках счета + есть хотя бы одна транзакция с недекодируемыми исходящими сообщениями (в теле сообщения отсутствуют оп-коды для + `уведомления о переводе` и оп-коды для `выводов`) или без исходящих сообщений, то баланс Jetton должен быть запрошен методом get для текущего блока, а для расчета разницы в балансах используется предыдущий блок + . Теперь становится известно об изменении общего баланса благодаря + транзакциям, проводимым внутри блока. +7. В качестве идентификатора для неопознанной передачи Jettons (без `уведомления о передаче`) можно использовать данные транзакции + , если присутствует одна такая транзакция, или данные блока (если в блоке присутствует несколько). +8. Теперь необходимо проверить правильность баланса депозита. Если баланс депозита достаточен для того, чтобы инициировать перевод между горячим кошельком и существующим кошельком Jetton, необходимо вывести джеттоны, чтобы убедиться, что баланс кошелька уменьшился. +9. Перезапустите с шага 2 и повторите весь процесс. + +#### Снятие средств с депозитов + +Не следует осуществлять переводы с депозита на горячий кошелек при каждом пополнении депозита, +поскольку за операцию перевода берется комиссия в TON (оплачивается в виде платы за газ в сети). +Важно определить определенное минимальное количество джеттонов, которое необходимо для того, чтобы перевод +(и, соответственно, депозит) был выгодным. + +По умолчанию владельцы депозитных кошельков Jetton не инициализируются. Это связано с тем, что не существует заранее установленного требования +платить за хранение. Депозитные кошельки Jetton могут быть развернуты при отправке сообщений с телом +`transfer`, которое затем может быть немедленно уничтожено. Для этого инженер должен использовать специальный механизм +для отправки сообщений: [128 + 32](/develop/smart-contracts/messages#message-modes). + +1. Получите список депозитов, помеченных для вывода на горячий кошелек +2. Получите сохраненные адреса владельцев для каждого депозита +3. Затем сообщения отправляются на каждый адрес владельца (путем объединения нескольких таких сообщений в пакет) с высоконагруженного кошелька + с привязанной суммой TON Jetton. Эта сумма определяется путем сложения сборов, использованных для инициализации кошелька v3R2* сборов за отправку сообщения с телом `transfer` + произвольной суммы TON, связанной с `forward_ton_amount` + (если необходимо). Прилагаемая сумма TON определяется путем сложения платы за инициализацию кошелька v3R2 (значение) + + платы за отправку сообщения с телом `transfer` (значение) + произвольной суммы TON + для `forward_ton_amount` (значение) (если необходимо). +4. Когда баланс на адресе становится ненулевым, статус аккаунта меняется. Подождите несколько секунд и проверьте статус + аккаунта, вскоре он изменится с состояния `nonexists` на `uninit`. +5. Для каждого адреса владельца (со статусом `uninit`) необходимо отправить внешнее сообщение с кошельком v3R2 + init и телом с сообщением `transfer` для пополнения кошелька Jetton = 128 + 32. Для `перевода`, + пользователь должен указать адрес горячего кошелька в качестве `назначения` и `ответного назначения`. + Для упрощения идентификации перевода можно добавить текстовый комментарий. +6. Проверить доставку Джеттонов с помощью адреса депозита на адрес горячего кошелька можно по адресу + , принимая во внимание [информацию об обработке входящих Джеттонов, найденную здесь](#processing-incoming-jettons). + +### Вывод средств из оборота Jetton + +:::info Важно + +Ниже Вы найдете пошаговое руководство по снятию средств с карты jetton. +::: + +Чтобы вывести Джеттоны, кошелек отправляет сообщения с телом `transfer` на соответствующий кошелек Jetton. +Затем кошелек Jetton отправляет Джеттоны получателю. По доброй воле важно прикрепить некоторое количество TON +в качестве `forward_ton_amount` (и необязательный комментарий к `forward_payload`), чтобы вызвать уведомление о `переводе`. +См: [Макеты сообщений по контрактам Jetton](#jetton-contract-message-layouts) + +#### Подготовка + +1. Подготовьте список джеттонов для снятия средств: [Добавление новых джеттонов для обработки и первичной проверки](#adding-new-jettons-for-asset-processing-and-initial-verification) +2. Начато развертывание горячего кошелька. Рекомендуется использовать Highload v3. [Развертывание кошелька](/develop/dapps/asset-processing/#wallet-deployment) +3. Выполните перевод Jetton, используя адрес "горячего" кошелька, чтобы инициализировать кошелек Jetton и пополнить его баланс. + +#### Обработка снятия средств + +1. Загрузить список обработанных джеттонов +2. Получите адреса кошельков Jetton для развернутого горячего кошелька: [Как получить адреса кошельков Jetton для данного пользователя] (#retrieving-jetton-wallet-addresses-for-a-given-user) +3. Получите главные адреса Jetton для каждого кошелька Jetton: [Как получить данные для кошельков Jetton](#retrieving-data-for-a-specific-jetton-wallet). + Требуется параметр `jetton` (который на самом деле является адресом мастер-контракта Jetton). +4. Сравните адреса из основных контрактов Jetton из шага 1. и шага 3. Если адреса не совпадают, то следует сообщить об ошибке проверки адреса в Jetton. +5. Поступают запросы на вывод средств, в которых указывается тип Jetton, переводимая сумма и адрес кошелька получателя. +6. Проверьте баланс кошелька Jetton, чтобы убедиться в наличии достаточного количества средств для осуществления вывода. +7. Сгенерируйте [сообщение](/develop/dapps/asset-processing/jettons#message-0). +8. При использовании кошелька с высокой нагрузкой рекомендуется собирать партии сообщений и отправлять по одной партии за раз, чтобы оптимизировать комиссионные сборы. +9. Сохраните время истечения срока действия для исходящих внешних сообщений (это время, пока кошелек успешно + обработает сообщение, после этого кошелек больше не будет принимать сообщение) +10. Отправьте одно сообщение или несколько сообщений (пакетная передача сообщений). +11. Получите список последних необработанных транзакций на счете "горячего" кошелька и выполните его итерацию. + Подробнее здесь: [Проверка транзакций контракта](/develop/dapps/asset-processing/#checking-contracts-transactions), + [Пример Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-single-wallet.js#L43) или + используйте метод Toncenter API `/getTransactions`. +12. Просмотрите исходящие сообщения в аккаунте. +13. Если существует сообщение с кодом операции `transfer`, то его следует декодировать, чтобы получить значение `query_id`. + Полученные `query_id` должны быть отмечены как успешно отправленные. +14. Если время, необходимое для обработки текущей отсканированной транзакции, превышает + время истечения срока действия, а исходящее сообщение с заданным `query_id` + не найдено, то запрос должен (это необязательно) быть помечен как истекший и должен быть безопасно отправлен повторно. +15. Просмотрите входящие сообщения в аккаунте. +16. Если существует сообщение, в котором используется операционный код `excesses`, сообщение должно быть декодировано и в нем должно быть найдено значение `query_id` + . Найденный `query_id` должен быть помечен как успешно доставленный. +17. Перейдите к шагу 5. Просроченные запросы, которые не были успешно отправлены, должны быть перемещены обратно в список снятия. + +## Обработка цепи Jetton + +Как правило, для приема и обработки джеттонов обработчик сообщений, отвечающий за внутренние сообщения, использует оп-код `op=0x7362d09c`. + +:::info Подтверждение транзакции +Транзакции TON становятся необратимыми после одного подтверждения. Для достижения наилучшего пользовательского опыта рекомендуется избегать ожидания дополнительных блоков после завершения транзакций на блокчейне TON. Подробнее читайте в [Catchain.pdf](https://docs.ton.org/catchain.pdf#page=3). +::: + +### Рекомендации по обработке на цепочке + +Ниже приведен `список рекомендаций`, которые необходимо учитывать при **проведении обработки джеттона на цепи**: + +1. **Идентифицируйте входящие джеттоны** по типу их кошелька, а не по их мастер-контракту Jetton. Другими словами, Ваш контракт должен взаимодействовать (получать и отправлять сообщения) с конкретным кошельком Jetton (а не с каким-то неизвестным кошельком, использующим конкретный мастер-контракт Jetton). +2. При установлении связи между кошельком Jetton и мастер-контрактом Jetton, **убедитесь**, что эта **связь является двунаправленной**, когда кошелек распознает мастер-контракт и наоборот. Например, если Ваша контрактная система получает уведомление от кошелька Jetton (который считает свой MySuperJetton своим мастер-контрактом), то информация о переводе должна быть показана пользователю, прежде чем показывать `symbol`, `name` и `image` + контракта MySuperJetton, проверьте, что кошелек MySuperJetton использует правильную контрактную систему. В свою очередь, если Ваша контрактная система по каким-то причинам должна отправлять джеттоны, используя мастер-контракты MySuperJetton или MySuperJetton, проверьте, что кошелек X, как и кошелек, использует те же параметры контракта. + Кроме того, перед отправкой запроса `перевода` на X убедитесь, что он признает MySuperJetton своим мастером. +3. Истинная сила\*\* децентрализованных финансов (DeFi) основана на возможности складывать протоколы друг на друга, как блоки лего. Например, скажем, джеттон А обменивается на джеттон Б, который, в свою очередь, затем используется в качестве рычага в протоколе кредитования (когда пользователь предоставляет ликвидность), который затем используется для покупки NFT .... и так далее. Таким образом, рассмотрим, как контракт может обслуживать не только пользователей вне цепи, но и сущности на цепи, присоединяя токенизированную ценность к уведомлению о передаче, добавляя пользовательскую полезную нагрузку, которая может быть отправлена вместе с уведомлением о передаче. +4. **Обратите внимание**, что не все джеттоны следуют одним и тем же стандартам. К сожалению, некоторые джеттоны могут быть враждебными (использующими векторы атак) и созданными исключительно для того, чтобы атаковать ничего не подозревающих пользователей. В целях безопасности, если рассматриваемый протокол состоит из множества контрактов, не создавайте большое количество джеттон-кошельков одного типа. В частности, не отправляйте джеттоны внутри протокола между контрактом депозита, контрактом хранилища, контрактом пользовательского счета и т.д. Злоумышленники могут намеренно вмешиваться в логику контракта, подделывая уведомления о переводе, суммы джеттонов или параметры полезной нагрузки. Уменьшите вероятность атак, используя только один кошелек в системе для одного джеттона (для всех депозитов и снятий). +5. Также **часто хорошей идеей** является создание субконтрактов для каждого отдельного джеттона, чтобы снизить вероятность подмены адреса (например, когда сообщение о передаче отправляется на джеттон B с использованием контракта, предназначенного для джеттона A). +6. Настоятельно рекомендуется\*\* работать с неделимыми единицами джеттона на уровне контракта. Логика, связанная с десятичными единицами, обычно используется для улучшения пользовательского интерфейса (UI) дипломата и не связана с ведением числовых записей на цепи. + +Чтобы узнать **больше** о [Secure Smart Contract Programming in FunC by CertiK](https://blog.ton.org/secure-smart-contract-programming-in-func), не стесняйтесь читать этот ресурс. Разработчикам рекомендуется **разрабатывать все исключения смарт-контрактов**, чтобы не пропустить их во время разработки приложения. + +## Рекомендации по обработке кошельков Jetton + +Как правило, все процедуры проверки, используемые для обработки внецепочечного джеттона, подходят и для кошельков. Для обработки кошельков Jetton наши самые важные рекомендации заключаются в следующем: + +1. Когда кошелек получает уведомление о переводе средств от неизвестного кошелька jetton, **очень важно** доверять кошельку jetton и его мастер-адресу, поскольку это может быть вредоносная подделка. Чтобы защитить себя, проверьте Jetton Master (главный контракт) по указанному адресу, чтобы убедиться, что Ваши процессы верификации распознают кошелек jetton как легитимный. После того, как Вы доверитесь кошельку и он будет признан легитимным, Вы можете разрешить ему получить доступ к остаткам на Ваших счетах и другим данным в кошельке. Если Jetton Master не распознает этот кошелек, рекомендуется вообще не инициировать и не раскрывать свои переводы jetton, а показывать только входящие переводы TON (из Toncoin, прикрепленных к уведомлениям о переводе). +2. На практике, если пользователь хочет взаимодействовать с Jetton, а не с кошельком Jetton. Другими словами, пользователи отправляют wTON/oUSDT/jUSDT, jUSDC, jDAI вместо `EQAjN...`/`EQBLE...` + и т.д.. Часто это означает, что когда пользователь инициирует перевод на jetton, кошелек спрашивает у соответствующего мастера jetton, какой кошелек jetton (принадлежащий пользователю) должен инициировать запрос на перевод. Очень **важно никогда слепо не доверять** этим данным от мастера (мастер-контракта). Прежде чем отправлять запрос на перевод в кошелек jetton, всегда убедитесь, что кошелек jetton действительно принадлежит тому Мастеру Jetton, за которого он себя выдает. +3. **Примите во внимание**, что недружественные Jetton Masters/jetton wallets **могут со временем менять** свои кошельки/мастера. Поэтому пользователи должны проявлять должную осмотрительность и проверять легитимность любых кошельков, с которыми они взаимодействуют, перед каждым использованием. +4. **Всегда убедитесь**, что Вы отображаете джеттоны в своем интерфейсе таким образом, чтобы они **не смешивались с передачей TON**, системными уведомлениями и т.д.. Даже параметры `symbol`, `name` и `image` + могут быть составлены таким образом, чтобы ввести пользователей в заблуждение, оставив их потенциальными жертвами мошенничества. Было несколько случаев, когда вредоносные джеттоны использовались для выдачи себя за переводы TON, ошибки в уведомлениях, получение вознаграждений или объявления о замораживании активов. +5. **Всегда будьте начеку с потенциальными злоумышленниками**, которые создают поддельные джеттоны, и всегда хорошо предоставить пользователям функциональность, необходимую для устранения нежелательных джеттонов в их основном пользовательском интерфейсе. + +Авторы: [kosrk](https://github.com/kosrk), [krigga](https://github.com/krigga), [EmelyanenkoK](https://github.com/EmelyanenkoK/) и [tolya-yanot](https://github.com/tolya-yanot/). + +## Лучшие практики + +Если Вам нужны готовые к тестированию примеры, проверьте [SDKs](/develop/dapps/asset-processing/jettons#sdks) и попробуйте их запустить. Ниже приведены фрагменты кода, которые помогут Вам понять процесс обработки джеттонов на примерах кода. + +### Отправить Джеттоны с комментарием + + + + +
+ +Исходный код + + +```js +// first 4 bytes are tag of text comment +const comment = new Uint8Array([... new Uint8Array(4), ... new TextEncoder().encode('text comment')]); + +await wallet.methods.transfer({ + secretKey: keyPair.secretKey, + toAddress: JETTON_WALLET_ADDRESS, // address of Jetton wallet of Jetton sender + amount: TonWeb.utils.toNano('0.05'), // total amount of TONs attached to the transfer message + seqno: seqno, + payload: await jettonWallet.createTransferBody({ + jettonAmount: TonWeb.utils.toNano('500'), // Jetton amount (in basic indivisible units) + toAddress: new TonWeb.utils.Address(WALLET2_ADDRESS), // recepient user's wallet address (not Jetton wallet) + forwardAmount: TonWeb.utils.toNano('0.01'), // some amount of TONs to invoke Transfer notification message + forwardPayload: comment, // text comment for Transfer notification message + responseAddress: walletAddress // return the TONs after deducting commissions back to the sender's wallet address + }), + sendMode: 3, +}).send() +``` + +
+ +
+ + +
+ +Исходный код + + +```go +client := liteclient.NewConnectionPool() + +// connect to testnet lite server +err := client.AddConnectionsFromConfigUrl(context.Background(), "https://ton.org/global.config.json") +if err != nil { + panic(err) +} + +ctx := client.StickyContext(context.Background()) + +// initialize ton api lite connection wrapper +api := ton.NewAPIClient(client) + +// seed words of account, you can generate them with any wallet or using wallet.NewSeed() method +words := strings.Split("birth pattern then forest walnut then phrase walnut fan pumpkin pattern then cluster blossom verify then forest velvet pond fiction pattern collect then then", " ") + +w, err := wallet.FromSeed(api, words, wallet.V3R2) +if err != nil { + log.Fatalln("FromSeed err:", err.Error()) + return +} + +token := jetton.NewJettonMasterClient(api, address.MustParseAddr("EQD0vdSA_NedR9uvbgN9EikRX-suesDxGeFg69XQMavfLqIw")) + +// find our jetton wallet +tokenWallet, err := token.GetJettonWallet(ctx, w.WalletAddress()) +if err != nil { + log.Fatal(err) +} + +amountTokens := tlb.MustFromDecimal("0.1", 9) + +comment, err := wallet.CreateCommentCell("Hello from tonutils-go!") +if err != nil { + log.Fatal(err) +} + +// address of receiver's wallet (not token wallet, just usual) +to := address.MustParseAddr("EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N") +transferPayload, err := tokenWallet.BuildTransferPayload(to, amountTokens, tlb.ZeroCoins, comment) +if err != nil { + log.Fatal(err) +} + +// your TON balance must be > 0.05 to send +msg := wallet.SimpleMessage(tokenWallet.Address(), tlb.MustFromTON("0.05"), transferPayload) + +log.Println("sending transaction...") +tx, _, err := w.SendWaitTransaction(ctx, msg) +if err != nil { + panic(err) +} +log.Println("transaction confirmed, hash:", base64.StdEncoding.EncodeToString(tx.Hash)) +``` + +
+ +
+ + +
+ +Исходный код + + +```py +my_wallet = Wallet(provider=client, mnemonics=my_wallet_mnemonics, version='v4r2') + +# for TonCenterClient and LsClient +await my_wallet.transfer_jetton(destination_address='address', jetton_master_address=jetton.address, jettons_amount=1000, fee=0.15) + +# for all clients +await my_wallet.transfer_jetton_by_jetton_wallet(destination_address='address', jetton_wallet='your jetton wallet address', jettons_amount=1000, fee=0.1) +``` + +
+ +
+ + + +
+ +Исходный код + + +```py +from pytoniq import LiteBalancer, WalletV4R2, begin_cell +import asyncio + +mnemonics = ["your", "mnemonics", "here"] + +async def main(): + provider = LiteBalancer.from_mainnet_config(1) + await provider.start_up() + + wallet = await WalletV4R2.from_mnemonic(provider=provider, mnemonics=mnemonics) + USER_ADDRESS = wallet.address + JETTON_MASTER_ADDRESS = "EQBlqsm144Dq6SjbPI4jjZvA1hqTIP3CvHovbIfW_t-SCALE" + DESTINATION_ADDRESS = "EQAsl59qOy9C2XL5452lGbHU9bI3l4lhRaopeNZ82NRK8nlA" + + USER_JETTON_WALLET = (await provider.run_get_method(address=JETTON_MASTER_ADDRESS, + method="get_wallet_address", + stack=[begin_cell().store_address(USER_ADDRESS).end_cell().begin_parse()]))[0].load_address() + forward_payload = (begin_cell() + .store_uint(0, 32) # TextComment op-code + .store_snake_string("Comment") + .end_cell()) + transfer_cell = (begin_cell() + .store_uint(0xf8a7ea5, 32) # Jetton Transfer op-code + .store_uint(0, 64) # query_id + .store_coins(1 * 10**9) # Jetton amount to transfer in nanojetton + .store_address(DESTINATION_ADDRESS) # Destination address + .store_address(USER_ADDRESS) # Response address + .store_bit(0) # Custom payload is None + .store_coins(1) # Ton forward amount in nanoton + .store_bit(1) # Store forward_payload as a reference + .store_ref(forward_payload) # Forward payload + .end_cell()) + + await wallet.transfer(destination=USER_JETTON_WALLET, amount=int(0.05*1e9), body=transfer_cell) + await provider.close_all() + +asyncio.run(main()) +``` + +
+ +
+
+ +### Примите Jetton Transfer с разбором комментария + + + + +
+ +Исходный код + + +```ts +import { + Address, + TonClient, + Cell, + beginCell, + storeMessage, + JettonMaster, + OpenedContract, + JettonWallet, + Transaction +} from '@ton/ton'; + + +export async function retry(fn: () => Promise, options: { retries: number, delay: number }): Promise { + let lastError: Error | undefined; + for (let i = 0; i < options.retries; i++) { + try { + return await fn(); + } catch (e) { + if (e instanceof Error) { + lastError = e; + } + await new Promise(resolve => setTimeout(resolve, options.delay)); + } + } + throw lastError; +} + +export async function tryProcessJetton(orderId: string) : Promise { + + const client = new TonClient({ + endpoint: 'https://toncenter.com/api/v2/jsonRPC', + apiKey: 'TONCENTER-API-KEY', // https://t.me/tonapibot + }); + + interface JettonInfo { + address: string; + decimals: number; + } + + interface Jettons { + jettonMinter : OpenedContract, + jettonWalletAddress: Address, + jettonWallet: OpenedContract + } + + const MY_WALLET_ADDRESS = 'INSERT-YOUR-HOT-WALLET-ADDRESS'; // your HOT wallet + + const JETTONS_INFO : Record = { + 'jUSDC': { + address: 'EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728', // + decimals: 6 + }, + 'jUSDT': { + address: 'EQBynBO23ywHy_CgarY9NK9FTz0yDsG82PtcbSTQgGoXwiuA', + decimals: 6 + }, + } + const jettons: Record = {}; + + const prepare = async () => { + for (const name in JETTONS_INFO) { + const info = JETTONS_INFO[name]; + const jettonMaster = client.open(JettonMaster.create(Address.parse(info.address))); + const userAddress = Address.parse(MY_WALLET_ADDRESS); + + const jettonUserAddress = await jettonMaster.getWalletAddress(userAddress); + + console.log('My jetton wallet for ' + name + ' is ' + jettonUserAddress.toString()); + + const jettonWallet = client.open(JettonWallet.create(jettonUserAddress)); + + //const jettonData = await jettonWallet; + const jettonData = await client.runMethod(jettonUserAddress, "get_wallet_data") + + jettonData.stack.pop(); //skip balance + jettonData.stack.pop(); //skip owneer address + const adminAddress = jettonData.stack.readAddress(); + + + if (adminAddress.toString() !== (Address.parse(info.address)).toString()) { + throw new Error('jetton minter address from jetton wallet doesnt match config'); + } + + jettons[name] = { + jettonMinter: jettonMaster, + jettonWalletAddress: jettonUserAddress, + jettonWallet: jettonWallet + }; + } + } + + const jettonWalletAddressToJettonName = (jettonWalletAddress : Address) => { + const jettonWalletAddressString = jettonWalletAddress.toString(); + for (const name in jettons) { + const jetton = jettons[name]; + + if (jetton.jettonWallet.address.toString() === jettonWalletAddressString) { + return name; + } + } + return null; + } + + // Subscribe + const Subscription = async ():Promise =>{ + + const client = new TonClient({ + endpoint: 'https://toncenter.com/api/v2/jsonRPC', + apiKey: 'TONCENTER-API-KEY', // https://t.me/tonapibot + }); + + const myAddress = Address.parse('INSERT-YOUR-HOT-WALLET'); // Address of receiver TON wallet + const transactions = await client.getTransactions(myAddress, { + limit: 5, + }); + return transactions; + } + + return retry(async () => { + + await prepare(); + const Transactions = await Subscription(); + + for (const tx of Transactions) { + + const sourceAddress = tx.inMessage?.info.src; + if (!sourceAddress) { + // external message - not related to jettons + continue; + } + + if (!(sourceAddress instanceof Address)) { + continue; + } + + const in_msg = tx.inMessage; + + if (in_msg?.info.type !== 'internal') { + // external message - not related to jettons + continue; + } + + // jetton master contract address check + const jettonName = jettonWalletAddressToJettonName(sourceAddress); + if (!jettonName) { + // unknown or fake jetton transfer + continue; + } + + if (tx.inMessage === undefined || tx.inMessage?.body.hash().equals(new Cell().hash())) { + // no in_msg or in_msg body + continue; + } + + const msgBody = tx.inMessage; + const sender = tx.inMessage?.info.src; + const originalBody = tx.inMessage?.body.beginParse(); + let body = originalBody?.clone(); + const op = body?.loadUint(32); + if (!(op == 0x7362d09c)) { + continue; // op != transfer_notification + } + + console.log('op code check passed', tx.hash().toString('hex')); + + const queryId = body?.loadUint(64); + const amount = body?.loadCoins(); + const from = body?.loadAddress(); + const maybeRef = body?.loadBit(); + const payload = maybeRef ? body?.loadRef().beginParse() : body; + const payloadOp = payload?.loadUint(32); + if (!(payloadOp == 0)) { + console.log('no text comment in transfer_notification'); + continue; + } + + const comment = payload?.loadStringTail(); + if (!(comment == orderId)) { + continue; + } + + console.log('Got ' + jettonName + ' jetton deposit ' + amount?.toString() + ' units with text comment "' + comment + '"'); + const txHash = tx.hash().toString('hex'); + return (txHash); + } + throw new Error('Transaction not found'); + }, {retries: 30, delay: 1000}); +} +``` + +
+ +
+ + +
+ +Исходный код + + +```go +import ( + "context" + "fmt" + "log" + + "github.com/xssnick/tonutils-go/address" + "github.com/xssnick/tonutils-go/liteclient" + "github.com/xssnick/tonutils-go/tlb" + "github.com/xssnick/tonutils-go/ton" + "github.com/xssnick/tonutils-go/ton/jetton" + "github.com/xssnick/tonutils-go/tvm/cell" +) + +const ( + MainnetConfig = "https://ton.org/global.config.json" + TestnetConfig = "https://ton.org/global.config.json" + MyWalletAddress = "INSERT-YOUR-HOT-WALLET-ADDRESS" +) + +type JettonInfo struct { + address string + decimals int +} + +type Jettons struct { + jettonMinter *jetton.Client + jettonWalletAddress string + jettonWallet *jetton.WalletClient +} + +func prepare(api ton.APIClientWrapped, jettonsInfo map[string]JettonInfo) (map[string]Jettons, error) { + userAddress := address.MustParseAddr(MyWalletAddress) + block, err := api.CurrentMasterchainInfo(context.Background()) + if err != nil { + return nil, err + } + + jettons := make(map[string]Jettons) + + for name, info := range jettonsInfo { + jettonMaster := jetton.NewJettonMasterClient(api, address.MustParseAddr(info.address)) + jettonWallet, err := jettonMaster.GetJettonWallet(context.Background(), userAddress) + if err != nil { + return nil, err + } + + jettonUserAddress := jettonWallet.Address() + + jettonData, err := api.RunGetMethod(context.Background(), block, jettonUserAddress, "get_wallet_data") + if err != nil { + return nil, err + } + + slice := jettonData.MustCell(0).BeginParse() + slice.MustLoadCoins() // skip balance + slice.MustLoadAddr() // skip owneer address + adminAddress := slice.MustLoadAddr() + + if adminAddress.String() != info.address { + return nil, fmt.Errorf("jetton minter address from jetton wallet doesnt match config") + } + + jettons[name] = Jettons{ + jettonMinter: jettonMaster, + jettonWalletAddress: jettonUserAddress.String(), + jettonWallet: jettonWallet, + } + } + + return jettons, nil +} + +func jettonWalletAddressToJettonName(jettons map[string]Jettons, jettonWalletAddress string) string { + for name, info := range jettons { + if info.jettonWallet.Address().String() == jettonWalletAddress { + return name + } + } + return "" +} + +func GetTransferTransactions(orderId string, foundTransfer chan<- *tlb.Transaction) { + jettonsInfo := map[string]JettonInfo{ + "jUSDC": {address: "EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728", decimals: 6}, + "jUSDT": {address: "EQBynBO23ywHy_CgarY9NK9FTz0yDsG82PtcbSTQgGoXwiuA", decimals: 6}, + } + + client := liteclient.NewConnectionPool() + + cfg, err := liteclient.GetConfigFromUrl(context.Background(), MainnetConfig) + if err != nil { + log.Fatalln("get config err: ", err.Error()) + } + + // connect to lite servers + err = client.AddConnectionsFromConfig(context.Background(), cfg) + if err != nil { + log.Fatalln("connection err: ", err.Error()) + } + + // initialize ton api lite connection wrapper + api := ton.NewAPIClient(client, ton.ProofCheckPolicySecure).WithRetry() + master, err := api.CurrentMasterchainInfo(context.Background()) + if err != nil { + log.Fatalln("get masterchain info err: ", err.Error()) + } + + // address on which we are accepting payments + treasuryAddress := address.MustParseAddr("EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N") + + acc, err := api.GetAccount(context.Background(), master, treasuryAddress) + if err != nil { + log.Fatalln("get masterchain info err: ", err.Error()) + } + + jettons, err := prepare(api, jettonsInfo) + if err != nil { + log.Fatalln("can't prepare jettons data: ", err.Error()) + } + + lastProcessedLT := acc.LastTxLT + + transactions := make(chan *tlb.Transaction) + + go api.SubscribeOnTransactions(context.Background(), treasuryAddress, lastProcessedLT, transactions) + + log.Println("waiting for transfers...") + + // listen for new transactions from channel + for tx := range transactions { + if tx.IO.In == nil || tx.IO.In.MsgType != tlb.MsgTypeInternal { + // external message - not related to jettons + continue + } + + msg := tx.IO.In.Msg + sourceAddress := msg.SenderAddr() + + // jetton master contract address check + jettonName := jettonWalletAddressToJettonName(jettons, sourceAddress.String()) + if len(jettonName) == 0 { + // unknown or fake jetton transfer + continue + } + + if msg.Payload() == nil || msg.Payload() == cell.BeginCell().EndCell() { + // no in_msg body + continue + } + + msgBodySlice := msg.Payload().BeginParse() + + op := msgBodySlice.MustLoadUInt(32) + if op != 0x7362d09c { + continue // op != transfer_notification + } + + // just skip bits + msgBodySlice.MustLoadUInt(64) + amount := msgBodySlice.MustLoadCoins() + msgBodySlice.MustLoadAddr() + + payload := msgBodySlice.MustLoadMaybeRef() + payloadOp := payload.MustLoadUInt(32) + if payloadOp == 0 { + log.Println("no text comment in transfer_notification") + continue + } + + comment := payload.MustLoadStringSnake() + if comment != orderId { + continue + } + + // process transaction + log.Printf("Got %s jetton deposit %d units with text comment %s\n", jettonName, amount, comment) + foundTransfer <- tx + } +} +``` + +
+
+ + + +
+ +Исходный код + + +```py +import asyncio + +from pytoniq import LiteBalancer, begin_cell + +MY_WALLET_ADDRESS = "EQAsl59qOy9C2XL5452lGbHU9bI3l4lhRaopeNZ82NRK8nlA" + + +async def parse_transactions(provider: LiteBalancer, transactions): + for transaction in transactions: + if not transaction.in_msg.is_internal: + continue + if transaction.in_msg.info.dest.to_str(1, 1, 1) != MY_WALLET_ADDRESS: + continue + + sender = transaction.in_msg.info.src.to_str(1, 1, 1) + value = transaction.in_msg.info.value_coins + if value != 0: + value = value / 1e9 + + if len(transaction.in_msg.body.bits) < 32: + print(f"TON transfer from {sender} with value {value} TON") + continue + + body_slice = transaction.in_msg.body.begin_parse() + op_code = body_slice.load_uint(32) + if op_code != 0x7362D09C: + continue + + body_slice.load_bits(64) # skip query_id + jetton_amount = body_slice.load_coins() / 1e9 + jetton_sender = body_slice.load_address().to_str(1, 1, 1) + if body_slice.load_bit(): + forward_payload = body_slice.load_ref().begin_parse() + else: + forward_payload = body_slice + + jetton_master = ( + await provider.run_get_method( + address=sender, method="get_wallet_data", stack=[] + ) + )[2].load_address() + jetton_wallet = ( + ( + await provider.run_get_method( + address=jetton_master, + method="get_wallet_address", + stack=[ + begin_cell() + .store_address(MY_WALLET_ADDRESS) + .end_cell() + .begin_parse() + ], + ) + )[0] + .load_address() + .to_str(1, 1, 1) + ) + + if jetton_wallet != sender: + print("FAKE Jetton Transfer") + continue + + if len(forward_payload.bits) < 32: + print( + f"Jetton transfer from {jetton_sender} with value {jetton_amount} Jetton" + ) + else: + forward_payload_op_code = forward_payload.load_uint(32) + if forward_payload_op_code == 0: + print( + f"Jetton transfer from {jetton_sender} with value {jetton_amount} Jetton and comment: {forward_payload.load_snake_string()}" + ) + else: + print( + f"Jetton transfer from {jetton_sender} with value {jetton_amount} Jetton and unknown payload: {forward_payload} " + ) + + print(f"Transaction hash: {transaction.cell.hash.hex()}") + print(f"Transaction lt: {transaction.lt}") + + +async def main(): + provider = LiteBalancer.from_mainnet_config(1) + await provider.start_up() + transactions = await provider.get_transactions(address=MY_WALLET_ADDRESS, count=5) + await parse_transactions(provider, transactions) + await provider.close_all() + + +if __name__ == "__main__": + asyncio.run(main()) +``` + +
+
+
+ +## SDKs + +Вы можете найти список SDK для различных языков (js, python, golang, C#, Rust и т.д.) список [здесь](/develop/dapps/apis/sdk). + +## См. также + +- [Обработка платежей](/develop/dapps/asset-processing/) +- [Обработка NFT на TON](/develop/dapps/asset-processing/nfts) +- [Разбор метаданных на TON](/develop/dapps/asset-processing/metadata) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md b/i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md new file mode 100644 index 0000000000..b54b07a5b8 --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md @@ -0,0 +1,62 @@ +import Button from '@site/src/components/button' +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Обзор обработки активов + +Здесь Вы найдете **краткий обзор** о том, [как работают переводы в TON](/develop/dapps/asset-processing/overview#overview-on-messages-and-transactions), какие [типы активов](/develop/dapps/asset-processing/overview#digital-asset-types-on-ton) вы можете найти в TON (и о чем вы будете читать [дальше](/develop/dapps/asset-processing/overview#read-next)) и как [взаимодействовать с ton](/develop/dapps/asset-processing/overview#interaction-with-ton-blockchain), используя ваш язык программирования, Рекомендуется ознакомиться со всей информацией, представленной ниже, прежде чем переходить к следующим страницам. + +## Обзор сообщений и транзакций + +Воплощая полностью асинхронный подход, блокчейн TON включает в себя несколько концепций, которые не характерны для традиционных блокчейнов. В частности, каждое взаимодействие любого актора с блокчейном состоит из графа асинхронно передаваемых [сообщений](/develop/smart-contracts/guidelines/message-delivery-guarantees) между смарт-контрактами и/или внешним миром. Каждая транзакция состоит из одного входящего сообщения и до 512 исходящих сообщений. + +Существует 3 типа сообщений, которые полностью описаны [здесь](/develop/smart-contracts/messages#types-of-messages). Если говорить кратко: + +- [внешнее сообщение](/develop/smart-contracts/guidelines/external-messages): + - Внешнее сообщение" (иногда его называют просто "внешнее сообщение") - это сообщение, которое отправляется из *вне* блокчейна смарт-контракту *внутри* блокчейна. + - Внешнее сообщение (обычно называемое "сообщение в журнале") отправляется от *блокчейн-субъекта* во *внешний мир*. +- [Внутреннее сообщение] (/develop/smart-contracts/guidelines/internal-messages) отправляется от одного *блокчейн-субъекта* к *другому*, может нести некоторое количество цифровых активов и произвольную порцию данных. + +Общий путь любого взаимодействия начинается с внешнего сообщения, отправленного смарт-контракту `wallet`, который аутентифицирует отправителя сообщения с помощью криптографии с открытым ключом, берет на себя оплату комиссии и отправляет внутренние сообщения блокчейна. Очередь этих сообщений образует направленный ациклический граф, или дерево. + +Например: + +![](/img/docs/asset-processing/alicemsgDAG.svg) + +- Алиса" использует, например, [Tonkeeper](https://tonkeeper.com/), чтобы отправить "внешнее сообщение" на свой кошелек. +- `Внешнее сообщение` - это входное сообщение для контракта `кошелек A v4` с пустым суром (сообщение из ниоткуда, например, [Tonkeeper](https://tonkeeper.com/)). +- `Исходящее сообщение` - это выходное сообщение для контракта `кошелек A v4` и входное сообщение для контракта `кошелек B v4` с источником `кошелек A v4` и пунктом назначения `кошелек B v4`. + +В результате существует 2 транзакции со своим набором входных и выходных сообщений. + +Каждое действие, когда контракт принимает сообщение на вход (инициируется им), обрабатывает его и генерирует или не генерирует исходящие сообщения на выходе, называется `транзакцией`. Подробнее о транзакциях читайте [здесь](/develop/smart-contracts/guidelines/message-delivery-guarantees#what-is-a-transaction). + +Эти `транзакции` могут охватывать **продолжительный период** времени. Технически, транзакции с очередями сообщений объединяются в блоки, обрабатываемые валидаторами. Асинхронная природа блокчейна TON **не позволяет предсказать хэш и lt (логическое время) транзакции** на этапе отправки сообщения. + +Принятая в блок `транзакция` является окончательной и не может быть изменена. + +:::info Подтверждение транзакции +Транзакции TON становятся необратимыми после одного подтверждения. Для достижения наилучшего пользовательского опыта рекомендуется избегать ожидания дополнительных блоков после завершения транзакций на блокчейне TON. Подробнее читайте в [Catchain.pdf](https://docs.ton.org/catchain.pdf#page=3). +::: + +Смарт-контракты платят несколько типов [сборов](/develop/smart-contracts/fees) за транзакции (обычно из баланса входящего сообщения, поведение зависит от [режима сообщения](/develop/smart-contracts/messages#message-modes)). Размер сборов зависит от конфигурации workchain: максимальные сборы на `masterchain` и значительно меньшие на `basechain`. + +## Типы цифровых активов на TON + +У TON есть три типа цифровых активов. + +- Тонкоин, основной токен сети. Он используется для всех основных операций в блокчейне, например, для оплаты газа или ставки для подтверждения. +- Контрактные активы, такие как токены и NFT, которые являются аналогом стандартов ERC-20/ERC-721, управляются произвольными контрактами и поэтому могут требовать пользовательских правил для обработки. Более подробную информацию об их обработке Вы можете найти в статьях [process NFTs](/develop/dapps/asset-processing/nfts) и [process Jettons](/develop/dapps/asset-processing/jettons). +- Нативные токены - это особый вид активов, которые могут быть прикреплены к любому сообщению в сети. Но в настоящее время эти активы не используются, поскольку функция выпуска новых нативных токенов закрыта. + +## Взаимодействие с блокчейном TON + +Основные операции с блокчейном TON можно выполнять с помощью TonLib. Это общая библиотека, которая может быть скомпилирована вместе с узлом TON и предоставляет API для взаимодействия с блокчейном через так называемые lite-серверы (серверы для lite-клиентов). TonLib придерживается бездоверительного подхода, проверяя доказательства для всех входящих данных; таким образом, нет необходимости в доверенном поставщике данных. Методы, доступные TonLib, перечислены [в схеме TL](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L234). Их можно использовать либо как общую библиотеку через [обертки](/develop/dapps/asset-processing/#repositories). + +## Читать далее + +Прочитав эту статью, Вы сможете проверить: + +1. [Обработка платежей](/develop/dapps/asset-processing/), чтобы узнать, как работать с `TON-монетами`. +2. [Обработка джеттонов](/develop/dapps/asset-processing/jettons), чтобы узнать, как работать с `джеттонами` (иногда их называют `токенами`) +3. [Обработка NFT](/develop/dapps/asset-processing/nfts), чтобы узнать, как работать с `NFT` (это специальный тип `jetton`) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx new file mode 100644 index 0000000000..408970bf2b --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx @@ -0,0 +1,113 @@ +import Button from '@site/src/components/button' + +# О компании TON Connect + +TON Connect - это мощный набор инструментов с открытым исходным кодом, который служит универсальным стандартом авторизации приложений в экосистеме [TON](/learn/introduction), позволяя пользователям безопасно и удобно входить в приложения и сервисы, используя свои TON-кошельки вместо традиционных логинов и паролей. + +![](/img/docs/ton-connect/ton-connect-overview.png?raw=true) + +Не стесняйтесь использовать один из следующих потоков для интеграции Вашего приложения: + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Примеры использования Вашего DApp + +Ознакомьтесь с этими результатами, которые экосистема TON предоставляет для превосходной интеграции DAppintegration. + +- **Трафик**. Обеспечьте дополнительные посещения пользователей через криптовалютные кошельки, поддерживающие TON Connect. +- **Аутентичность**. Используйте кошельки пользователей TON в качестве готовых учетных записей, устраняя необходимость в дополнительных шагах аутентификации и, таким образом, повышая удобство использования. +- **Платежи**. Быстро и безопасно обрабатывайте транзакции через блокчейн TON, используя Toncoin или обернутые стабильные монеты (jUSDC/jUSDT). +- **Удержание**. Повысьте уровень удержания пользователей благодаря функции сохранения списков в приложении, которая позволяет пользователям следить за недавно открытыми и любимыми приложениями. + +## Для разработчиков кошельков + +Если Вы являетесь разработчиком кошелька, Вы можете подключить свой кошелек к TON Connect и позволить своим пользователям взаимодействовать с приложениями TON безопасным и удобным способом, прочитайте, как [интегрировать TON Connect в свой кошелек](/develop/dapps/ton-connect/wallet/). + +## Истории успеха + +- [GetGems - Открытый сетевой рынок](https://getgems.io/) +- [STON.fi - AMM DEX для блокчейна TON](https://ston.fi/) +- [Tonstarter](http://tonstarter.com/) + +
+ Показать весь список + +- [getgems.io](https://getgems.io/) +- [fragment.com](https://fragment.com/) (Ton Connect v.1) +- [ston.fi](https://ston.fi/) +- [ton.diamonds](https://ton.diamonds/) +- [beta.disintar.io](https://beta.disintar.io/) +- [tegro.finance](https://tegro.finance/liquidity) +- [minter.ton.org](https://minter.ton.org/) +- [libermall.com](https://libermall.com/) +- [dedust.io](https://dedust.io/swap) +- [toncap.net](https://toncap.net/) +- [cryptomus.com](https://cryptomus.com/) +- [avanchange.com](https://avanchange.com/) +- [wton.dev](https://wton.dev/) +- [mint.spiroverse.io/shop](https://mint.spiroverse.io/shop) +- [vk.com/vk_nft_hub](https://vk.com/vk_nft_hub) +- [tonverifier.live](https://verifier.ton.org/) +- [stickerface.io/member](https://stickerface.io/member) +- [tonstarter.com](https://tonstarter.com/) +- [cryptogas.shop/ton](https://cryptogas.shop/ton) +- [megaton.fi](https://megaton.fi/) +- [dns.ton.org](https://dns.ton.org/) +- [coinpaymaster.com](https://coinpaymaster.com/) +- [ton.gagarin.world/app/](https://ton.gagarin.world/app) +- [daolama.co](https://daolama.co/) +- [marketplace.playmuse.org](http://marketplace.playmuse.org/) +- [ton.vote](https://ton.vote/) +- [plane.tonfancy.io](https://plane.tonfancy.io/) +- [pi.oberton.io](https://pi.oberton.io/) +- [business.thetonpay.app](https://business.thetonpay.app/) +- [bridge.orbitchain.io](https://bridge.orbitchain.io/) +- [connecton-web-new.vercel.app](https://connecton-web-new.vercel.app/) +- [app.fanz.ee/staking](https://app.fanz.ee/staking) +- [testnet.pton.fi](https://testnet.pton.fi/) +- [tonft.app](https://tonft.app/) +- [cardify.casino](https://cardify.casino/) +- [4riends.org](https://4riends.org/#/) +- [tonflex.fi](https://tonflex.fi/swap) +- [soquest.xyz](https://soquest.xyz/) +- [app.evaa.finance](https://app.evaa.finance/) + +
+ +## Присоединяйтесь к экосистеме TON + +Чтобы подключить свой сервис к экосистеме TON, Вам необходимо выполнить следующие действия: + +- **TON Connect**. Включите протокол TON Connect в свое приложение. +- **Транзакции**. Создавайте заданные сообщения транзакций с помощью библиотек TON. Погрузитесь в процесс [отправки сообщений](/develop/dapps/ton-connect/message-builders) с помощью нашего исчерпывающего руководства. +- **Платежи**. Обрабатывайте платежи через публичный API ([tonapi](https://tonapi.io/)) или Ваш собственный индексатор, например, [gobycicle](http://github.com/gobicycle/bicycle). Узнайте больше из нашего подробного руководства по [обработке активов](/develop/dapps/asset-processing). diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/develop/fift/overview.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/develop/fift/overview.mdx new file mode 100644 index 0000000000..1fd78849ba --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/develop/fift/overview.mdx @@ -0,0 +1,57 @@ +import Button from '@site/src/components/button' + +# Обзор + +Fift - это основанный на стеке язык программирования общего назначения, оптимизированный для создания, отладки и управления смарт-контрактами TON Blockchain. +Fift был специально разработан для взаимодействия с виртуальной машиной TON (TON VM или TVM) и блокчейном TON. + +```fift +{ ."hello " } execute ."world" +hello world ok +``` + +:::info +Обычно использование языка Fift не требуется для программирования смарт-контрактов в TON. Однако иногда Вам может понадобиться использовать язык Fift для решения нестандартных технических задач в рамках Вашего задания. +::: + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +



+ +## Документация + +- [Fift: A Brief Introduction](https://ton.org/fiftbase.pdf) +- [Виртуальная машина TON](/learn/tvm-instructions/tvm-overview) + +## Примеры + +- [Примеры смарт-контрактов Fift] (/develop/smart-contracts/examples#fift-smart-contracts) + +## Учебники + +- [Introduction To Fift](https://blog.ton.org/introduction-to-fift) +- [\[YouTube\]Его величество Фифт](https://www.youtube.com/watch?v=HVsveTmVowc&list=PLtUBO1QNEKwttRsAs9eacL2oCMOhWaOZs) \[[RU-версия](https://www.youtube.com/playlist?list=PLyDBPwv9EPsCYG-hR4N5FRTKUkfM8POgh)] от **@MarcoDaTr0p0je** & **@Wikimar**. + +## Источники + +- [Скрипты Fift для стандартных смарт-контрактов](https://github.com/ton-blockchain/ton/tree/master/crypto/smartcont) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/develop/overview.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/develop/overview.mdx new file mode 100644 index 0000000000..ead7734072 --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/develop/overview.mdx @@ -0,0 +1,207 @@ +import Button from '@site/src/components/button' +import Player from '@site/src/components/player' + +# Документация TON + +Добро пожаловать в официальную документацию по разработке TON Blockchain! + +Этот ресурс призван предоставить Вам всю необходимую информацию, которая понадобится Вам для создания, тестирования и развертывания приложений на блокчейне TON. + +Это совместная инициатива с открытым исходным кодом, и вклад всегда приветствуется. Вся документация может быть отредактирована через GitHub, просто [следуйте этим инструкциям](/contribute). + +- Серия _TON Hello World_ содержит подробные пошаговые руководства по кошелькам, смарт-контрактам, мини-приложениям, а также тестированию и отладке смарт-контрактов на TON. +- _Get Started with TON_ - это пошаговое руководство по взаимодействию с блокчейном TON. (Видеоурок прилагается) + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +### Основы блокчейна с TON + +Этот курс знакомит с основами блокчейна, уделяя особое внимание практическим навыкам работы в экосистеме TON. Вы поймете, как функционирует блокчейн и каковы его разнообразные применения. + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +### Курс TON + +Мы с гордостью представляем курс **TON Blockchain Course**, который является исчерпывающим руководством по блокчейну TON. Курс предназначен для разработчиков, которые хотят научиться создавать смарт-контракты и децентрализованные приложения на блокчейне TON в увлекательной и интерактивной форме. + +Он состоит из **9 модулей** и охватывает основы блокчейна TON, языка программирования FunC и виртуальной машины TON (TVM). + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Модули разработки + +Если Вы новичок в разработке TON Blockchain, рекомендуем Вам начать с самого начала и пройти свой путь через эти темы. + +### Основополагающие концепции + +- [The Open Network](/learn/introduction) - высокоуровневый обзор блокчейна TON. +- [Blockchain of Blockchains](/learn/overviews/ton-blockchain) - приземленное объяснение TON Blockchain. +- [Адреса смарт-контрактов](/learn/overviews/addresses) - Подробное объяснение адресов. +- [Ячейки как структура данных](/learn/overviews/cells) - Высокоуровневое объяснение структур данных. +- [TON Networking](/learn/networking/overview) - Высокоуровневый обзор протоколов TON peer-to-peer. +- [Виртуальная машина TON (TVM)](/learn/tvm-instructions/tvm-overview) - Высокоуровневый обзор виртуальной машины TON. +- [Транзакции и фазы](/learn/tvm-instructions/tvm-overview#transactions-and-phases) - Подробное объяснение транзакций и фаз. +- [Комиссионные за транзакции](/develop/smart-contracts/fees) - высокоуровневое объяснение комиссионных за транзакции. + +### Инфраструктура + +- [Типы узлов](/participate/nodes/node-types) - Подробное объяснение типов узлов. +- [Run a Full Node](/participate/run-nodes/full-node) - Подробное объяснение того, как запустить узел. +- [TON DNS & Sites](/participate/web3/dns) - Подробное объяснение TON DNS & Sites. +- [TON Storage](/participate/ton-storage/storage-daemon) - Подробное объяснение работы TON Storage. + +### Дополнительные ресурсы + +- [**FAQ**](/develop/howto/faq) - Часто задаваемые вопросы +- [Документация FunC](/develop/func/overview) +- [Документация по Fift](/develop/fift/overview) + +## Разработка смарт-контрактов + +Смарт-контракты - это строительные блоки децентрализованных приложений (DApps) на блокчейне TON. Если Вы хотите разработать собственное dApps, очень важно понимать, как работают смарт-контракты. + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +



+ +Следующие ресурсы предоставляют ценную информацию для разработки смарт-контрактов TON: + +- [TON Hello World: Пошаговое руководство по написанию Вашего первого смарт-контракта](https://ton-community.github.io/tutorials/02-contract/) - Доступное и лаконичное объяснение основ работы с JS. +- [Как работать со смарт-контрактами кошелька](/develop/smart-contracts/tutorials/wallet) - Подробное и тщательное объяснение основ смарт-контрактов с использованием JS и GO. +- [Изучение смарт-контрактов на примерах](/develop/smart-contracts/examples) (FunC, Fift) +- [Speed Run TON](/develop/smart-contracts/examples) - 6 интерактивных задач и пошаговых руководств для изучения разработки смарт-контрактов. + +## Разработка DApp + +Децентрализованные приложения (DApps) - это приложения, которые работают не на одном компьютере (блокчейн TON), а на одноранговой сети компьютеров. Они похожи на традиционные веб-приложения, но построены поверх сети блокчейн. Это означает, что DApps децентрализованы, то есть ни один субъект не контролирует их. + +```mdx-code-block + +``` + +### DeFi Development + +- [TON Connect](/develop/dapps/ton-connect/overview) - интеграция и аутентификация для DApps. +- [Обработка внецепочечных платежей](/develop/dapps/asset-processing) - примеры и концепции обработки платежей. +- [Обработка джеттонов TON](/develop/dapps/asset-processing/jettons) - примеры и концепции для обработки джеттонов. +- [Fungible (FT) / Non-fungible (NFT) tokens](/develop/dapps/defi/tokens) - смарт-контракты, примеры, инструменты + +Сделайте первые шаги в разработке DApps с помощью исчерпывающего руководства по созданию DApps: + +- [TON Hello World: пошаговое руководство по созданию вашего первого веб-клиента](https://ton-community.github.io/tutorials/03-client/) +- [Интеграция бота Telegram через TON Connect](/develop/dapps/ton-connect/tg-bot-integration) + +### API и SDK + +- [APIs](/develop/dapps/apis) +- [SDKs](/develop/dapps/apis/sdk) + +## Часто задаваемые вопросы + +Перейдите в раздел [Часто задаваемые вопросы](/develop/howto/faq). diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/develop/smart-contracts/testing/overview.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/develop/smart-contracts/testing/overview.mdx new file mode 100644 index 0000000000..32da941a50 --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/develop/smart-contracts/testing/overview.mdx @@ -0,0 +1,141 @@ +# Написание тестов с помощью Blueprint + +## Обзор + +Инструментарий для тестирования (обычно это песочница) уже включен в TypeScript SDK под названием [Blueprint](/develop/smart-contracts/sdk/javascript). Вы можете создать демо-проект и запустить тест по умолчанию в два этапа: + +1. Создайте новый проект Blueprint: + +```bash +npm create ton@latest MyProject +``` + +2. Проведите тест: + +```bash +cd MyProject +npx blueprint test +``` + +В результате Вы увидите соответствующий вывод в окне терминала: + +```bash +% npx blueprint test + +> MyProject@0.0.1 test +> jest + + PASS tests/Main.spec.ts + Main + ✓ should deploy (127 ms) + +Test Suites: 1 passed, 1 total +Tests: 1 passed, 1 total +Snapshots: 0 total +Time: 1.224 s, estimated 2 s +Ran all test suites. +``` + +## Базовое использование + +Тестирование смарт-контрактов позволяет обеспечить безопасность, оптимизировать расход газа и изучить крайние случаи. +Написание тестов в Blueprint (основанном на [Sandbox](https://github.com/ton-org/sandbox)) осуществляется путем определения произвольных действий с контрактом и сравнения результатов тестирования с ожидаемым результатом, например: + +```typescript +it('should execute with success', async () => { // description of the test case + const res = await main.sendMessage(sender.getSender(), toNano('0.05')); // performing an action with contract main and saving result in res + + expect(res.transactions).toHaveTransaction({ // configure the expected result with expect() function + from: main.address, // set expected sender for transaction we want to test matcher properties from + success: true // set the desirable result using matcher property success + }); + + printTransactionFees(res.transactions); // print table with details on spent fees +}); +``` + +### Написание тестов для сложных утверждений + +Основная схема создания теста такова: + +1. Создайте определенную обернутую сущность `Contract` с помощью функции `blockchain.openContract()`. +2. Опишите действия, которые должен выполнить Ваш `контракт`, и сохраните результат выполнения в переменной `res`. +3. Проверьте свойства с помощью функции `expect()` и матчера `toHaveTransaction()`. + +Матчер `toHaveTransaction` ожидает объект с любой комбинацией полей из типа `FlatTransaction`, определенных со следующими свойствами + +| Имя | Тип | Описание | +| --------------------------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| с сайта | Адрес? | Контрактный адрес отправителя сообщения | +| на | Адрес | Контрактный адрес назначения сообщения (альтернативное имя свойства `to`). | +| значение | bigint? | Количество Тонкоинов в сообщении в нанотонах | +| тело | Клетка | Тело сообщения определяется как ячейка | +| op | число? | Код операции - это номер идентификатора операции (обычно crc32 из TL-B). Ожидается в первых 32 битах тела сообщения. | +| успех | булево? | Пользовательский флаг песочницы, определяющий результирующий статус определенной транзакции. True - если фаза вычислений и действий прошла успешно. В противном случае - False. | + +Вы можете опустить поля, которые Вас не интересуют, и передать функции, принимающие типы, возвращающие булевы (`true` означает "хорошо"), для проверки, например, диапазонов чисел, опкодов сообщений и т.д. Обратите внимание, что если поле является необязательным (например, `from?: Address`), то функция должна принимать и необязательный тип. + +:::tip +Весь список полей матчера Вы можете узнать из [Документации по песочнице](https://github.com/ton-org/sandbox#test-a-transaction-with-matcher). +::: + +### Конкретный набор тестов + +#### Извлечение SendMode + +Чтобы извлечь режим отправки отправленного сообщения, Вы можете использовать следующий код: + +```ts + +const smc = await blockchain.getContract(addr); + +const re = blockchain.executor.runTransaction({ + config: blockchain.configBase64, libs: null, verbosity: 'full', + now: Math. floor (Date.now) / 1000), + lt: BigInt(Date.now()), + randomSeed: null, + ignoreChksig: false, + debugEnabled: true, + shardAccount: beginCell() + .store (storeShardAccount (smc.account)) + .endCell() + .toBoc() + .toString('base64'), + message: beginCell() + .store (storeMessageRelaxed (...)) + .endCell(), +}); + +if (!re.result. success || !re.result.actions) { + throw new Error('fail'); +} +const actions = loadoutList(Cell.fromBase64(re.result.actions).beginParse()); +actions[0].type === 'sendMsg' && actions[0].mode; + +``` + +## Учебники + +Узнайте больше о тестировании из самых ценных уроков сообщества на TON: + +- [Урок 2: Тестирование FunC для смарт-контракта](https://github.com/romanovichim/TonFunClessons_Eng/blob/main/lessons/smartcontract/2lesson/secondlesson.md) +- [TON Hello World часть 4: Пошаговое руководство по тестированию вашего первого смарт-контракта](https://ton-community.github.io/tutorials/04-testing/) +- [TON Smart Contract Pipeline](https://dev.to/roma_i_m/ton-smart-contract-pipeline-write-simple-contract-and-compile-it-4pnh) +- [\[YouTube\]Шестой урок FunC & Blueprint. Газ, оплата, тесты](https://youtu.be/3XIpKZ6wNcg) + +## Примеры + +Проверьте тестовые наборы, используемые для контрактов экосистемы TON, и учитесь на примерах. + +- [тесты песочницы liquid-staking-contract](https://github.com/ton-blockchain/liquid-staking-contract/tree/main/tests) +- [governance_tests](https://github.com/Trinketer22/governance_tests/blob/master/config_tests/tests/) +- [JettonWallet.spec.ts](https://github.com/EmelyanenkoK/modern_jetton/blob/master/tests/JettonWallet.spec.ts) +- [governance_tests](https://github.com/Trinketer22/governance_tests/blob/master/elector_tests/tests/complaint-test.fc) +- [MassSender.spec.ts](https://github.com/Gusarich/ton-mass-sender/blob/main/tests/MassSender.spec.ts) +- [TonForwarder.spec.ts](https://github.com/TrueCarry/ton-contract-forwarder/blob/main/src/contracts/ton-forwarder/TonForwarder.spec.ts) +- [Assurer.spec.ts](https://github.com/aSpite/dominant-assurance-contract/blob/main/tests/Assurer.spec.ts) + +## См. также + +- [Blueprint](/develop/smart-contracts/sdk/javascript) +- [toncli](/develop/smart-contracts/testing/toncli) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/learn/academy/academy-overview.md b/i18n/ru/docusaurus-plugin-content-docs/current/learn/academy/academy-overview.md new file mode 100644 index 0000000000..67acdd7dcf --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/learn/academy/academy-overview.md @@ -0,0 +1,16 @@ +# Образовательные ресурсы + +### TON Speedrun + +- [TON Speedrun](https://tonspeedrun.com/) - специализированная платформа, предназначенная для практического подхода к обучению в разработке TON. + +### Курсы + +- [Основы блокчейна с TON](https://stepik.org/course/201294/promo) ([RU версия](https://stepik.org/course/202221/), [CHN версия](https://stepik.org/course/200976/)) - + Этот курс знакомит с основами блокчейна, уделяя особое внимание практическим навыкам работы в экосистеме TON. Вы поймете, как функционирует блокчейн и каковы его разнообразные применения. + +## См. также + +- [Speedrun TON](https://tonspeedrun.com/) +- [TON Hello World](https://tonhelloworld.com/01-wallet/) +- [[YouTube] TON Dev Study EN ](https://www.youtube.com/@TONDevStudy)[[RU]](https://www.youtube.com/results?search_query=tondevstudy) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/learn/introduction.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/learn/introduction.mdx new file mode 100644 index 0000000000..6a5fd4a4db --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/learn/introduction.mdx @@ -0,0 +1,81 @@ +import Player from '@site/src/components/player' +import Button from '@site/src/components/button' + +# Открытая сеть + +**The Open Network (TON)** - это децентрализованная и открытая интернет-платформа, состоящая из нескольких компонентов. К ним относятся: TON Blockchain, TON DNS, TON Storage и TON Sites. TON Blockchain - это основной протокол, который соединяет базовую инфраструктуру TON вместе, образуя большую экосистему TON. + +TON нацелен на достижение широкой межцепочечной совместимости, работая при этом в высокомасштабируемой безопасной системе. TON рассчитан на обработку миллионов транзакций в секунду (TPS), а в перспективе - на сотни миллионов пользователей. + +**TON Blockchain** разработан как распределенный суперкомпьютер, или "_суперсервер_", предназначенный для предоставления различных продуктов и услуг, способствующих развитию децентрализованного видения нового Интернета. + +- Узнайте, какие услуги TON предоставляет своим пользователям, просмотрев этот раздел: [Участвуйте в TON](/participate/) +- Чтобы узнать больше о технических аспектах TON Blockchain, ознакомьтесь с [Blockchain of Blockchains](/learn/overviews/ton-blockchain) +- Узнайте больше о разработке всех вещей TON, просмотрев этот раздел: [Начало работы](/develop/overview) + +## Обзор с высоты птичьего полета + +Чтобы понять истинное видение децентрализованного Интернета и то, как TON вносит свой вклад в эту неизбежность, ознакомьтесь с видео ниже: + + + +## Основы блокчейна с TON + +Этот курс знакомит с основами блокчейна, уделяя особое внимание практическим навыкам работы в экосистеме TON. Вы поймете, как функционирует блокчейн и каковы его разнообразные применения. Вы также получите важнейшие навыки, связанные с TON, включая настройку кошелька, торговлю NFT, создание Jetton и транзакции с монетами TON на децентрализованных биржах (DEX). Курс также вооружит Вас важнейшими знаниями о криптовалютных угрозах и мошенничестве и даст практические советы о том, как защитить свои криптоактивы. + +- [Основы блокчейна с TON](https://stepik.org/course/201294/) ([RU версия](https://stepik.org/course/202221/), [CHN версия](https://stepik.org/course/200976/)) + +## Курс TON Blockchain + +Мы с гордостью представляем **TON Blockchain Course**, который является исчерпывающим руководством по блокчейну TON. Курс предназначен для разработчиков, которые хотят научиться создавать смарт-контракты и децентрализованные приложения на блокчейне TON. + +Он состоит из **9 модулей** и охватывает основы блокчейна TON, языка программирования FunC и виртуальной машины TON (TVM). + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Новичок в блокчейне? + +Если Вы новичок в блокчейне и не понимаете, что делает эту технологию такой революционной, ознакомьтесь с этими важными ресурсами: + +- [Что такое блокчейн? Что такое смарт-контракт? Что такое газ?](https://blog.ton.org/what_is_blockchain) +- [Как блокчейн может помочь Вам на необитаемом острове](https://talkol.medium.com/why-decentralized-consensus-blockchain-is-good-for-business-5ff263468210) +- [\[YouTube\] Криптосети и почему они имеют значение](https://youtu.be/2wxtiNgXBaU) + +## Отношения TON с Ethereum + +Для тех, кто знаком с разработкой Ethereum, мы написали две вводные статьи, чтобы помочь Вам понять, что отличает TON в этом отношении: + +- [Шесть уникальных аспектов блокчейна TON, которые удивят разработчиков Solidity](https://blog.ton.org/six-unique-aspects-of-ton-blockchain-that-will-surprise-solidity-developers) +- [Пришло время попробовать что-то новое: асинхронные смарт-контракты](https://telegra.ph/Its-time-to-try-something-new-Asynchronous-smart-contracts-03-25) +- [Сравнение блокчейнов](https://ton.org/comparison_of_blockchains.pdf) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/learn/networking/overview.md b/i18n/ru/docusaurus-plugin-content-docs/current/learn/networking/overview.md new file mode 100644 index 0000000000..abb9281b21 --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/learn/networking/overview.md @@ -0,0 +1,19 @@ +# TON Networking + +Проект TON использует собственные протоколы одноранговой сети. + +- Блокчейн **TON использует эти протоколы** для распространения новых блоков, отправки и сбора кандидатов на транзакцию и так далее. + + В то время как сетевые требования одноблокчейновых проектов, таких как Bitcoin или Ethereum, могут быть удовлетворены довольно легко (по сути, необходимо построить + одноранговую оверлейную сеть и затем распространять все новые блоки и + кандидатов на транзакции с помощью протокола [gossip](https://en.wikipedia.org/wiki/Gossip_protocol)), многоблокчейновые проекты, такие как + TON, гораздо более требовательны (например, необходимо иметь возможность + подписаться на обновления только некоторых шардчейнов, не обязательно всех). + +- Сервисы экосистемы **TON (например, TON Proxy, TON Sites, TON Storage) работают на этих протоколах.**. + + Как только более сложные сетевые протоколы, необходимые + для поддержки блокчейна TON, будут созданы, окажется, что их можно легко + использовать для целей, не обязательно связанных с непосредственными потребностями самого + блокчейна, что дает больше возможностей и гибкости для создания + новых услуг в экосистеме TON. diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/learn/overviews/addresses.md b/i18n/ru/docusaurus-plugin-content-docs/current/learn/overviews/addresses.md new file mode 100644 index 0000000000..9090c650d1 --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/learn/overviews/addresses.md @@ -0,0 +1,220 @@ +# Адреса смарт-контрактов + +В этом разделе будут описаны особенности адресации смарт-контрактов в блокчейне TON. Также будет объяснено, как акторы являются синонимами смарт-контрактов на TON. + +## Все является умным контрактом + +В TON смарт-контракты строятся с использованием модели [Actor model] (/learn/overviews/ton-blockchain#single-actor). Фактически, акторы в TON технически представлены в виде смарт-контрактов. Это означает, что даже Ваш кошелек является простым актором (и смарт-контрактом). + +Как правило, акторы обрабатывают входящие сообщения, изменяют свое внутреннее состояние и в результате генерируют исходящие сообщения. Именно поэтому каждый актор (т.е. смарт-контракт) в блокчейне TON должен иметь адрес, чтобы иметь возможность получать сообщения от других акторов. + +:::info ОПЫТ РАБОТЫ С EVM +В виртуальной машине Ethereum (EVM) адреса полностью отделены от смарт-контрактов. Не стесняйтесь узнать больше о различиях, прочитав нашу статью ["Шесть уникальных аспектов блокчейна TON, которые удивят разработчиков Solidity"](https://blog.ton.org/six-unique-aspects-of-ton-blockchain-that-will-surprise-solidity-developers), написанную Талом Колом. +::: + +## Адрес смарт-контракта + +Адреса смарт-контрактов, работающих на TON, обычно состоят из двух основных компонентов: + +- **(workchain_id)**: обозначает ID рабочей цепи (знаковое 32-битное целое число) + +- **(account_id)** обозначает адрес аккаунта (64-512 бит, в зависимости от рабочего цепочки) + +В разделе этой документации, посвященном обзору сырых адресов, мы обсудим, как выглядят пары **(workchain_id, account_id)**. + +### Идентификатор рабочей цепи и идентификатор учетной записи + +#### Идентификатор рабочей цепи + +[Как мы уже видели ранее](/learn/overviews/ton-blockchain#workchain-blockchain-with-your-own-rules), на блокчейне TON можно создать до `2^32` рабочих цепей. Мы также отметили, что адреса смарт-контрактов с 32-битным префиксом идентифицируют и связываются с адресами смарт-контрактов в разных рабочих цепях. Это позволяет смарт-контрактам отправлять и получать сообщения в разные рабочие цепочки TON Blockchain и из них. + +В настоящее время в блокчейне TON работает только мастерчейн (workchain_id=-1) и время от времени основной workchain (workchain_id=0). + +Оба они имеют 256-битные адреса, поэтому мы предполагаем, что workchain_id равен либо 0, либо -1, а адрес внутри рабочей цепочки точно равен 256 битам. + +#### Идентификатор счета + +Все идентификаторы учетных записей на TON используют 256-битные адреса на Мастерчейне и Бейсчейне (или базовом рабочем цепочке). + +Фактически, идентификаторы аккаунта **(account_id)** определяются как хэш-функции для объектов смарт-контракта (в частности, SHA-256). Каждый смарт-контракт, работающий на блокчейне TON, хранит два основных компонента. К ним относятся: + +1. *Скомпилированный код*. Логика смарт-контракта, скомпилированная в виде байткода. +2. *Инициальное состояние*. Значения контракта в момент его развертывания на цепи. + +Наконец, чтобы точно определить адрес контракта, необходимо вычислить хэш, соответствующий паре **(Начальный код, Начальное состояние)** объектов. Сейчас мы не будем глубоко вникать в то, как работает [TVM](/learn/tvm-instructions/tvm-overview), но важно понимать, что идентификаторы счетов на TON определяются по такой формуле: +: +**account_id = hash(начальный код, начальное состояние)**. + +Со временем, на протяжении всей этой документации, мы будем углубляться в технические характеристики и обзор схемы TVM и TL-B. Теперь, когда мы знакомы с генерацией **account_id** и их взаимодействием с адресами смарт-контрактов на TON, давайте объясним, что такое Raw и User-Friendly адреса. + +## Обращается к государству + +Каждый адрес может находиться в одном из возможных состояний: + +- `nonexist` - по этому адресу не было принято ни одной транзакции, поэтому он не содержит никаких данных (или контракт был удален). Можно сказать, что изначально все2256 адресов находятся в таком состоянии. +- `uninit` - адрес имеет некоторые данные, которые содержат баланс и мета-информацию. В этом состоянии у адреса еще нет кода смарт-контракта/постоянных данных. Адрес переходит в это состояние, например, когда он не существовал, и какой-то другой адрес отправил ему токены. +- `Активный` - адрес имеет код смарт-контракта, постоянные данные и баланс. В этом состоянии он может выполнять некоторую логику во время транзакции и изменять свои постоянные данные. Адрес переходит в это состояние, когда он был `uninit` и поступило сообщение с параметром state_init (обратите внимание, что для развертывания этого адреса хэш из `state_init` и `code` должен быть равен адресу). +- `заморозка` - адрес не может выполнять никаких операций, это состояние содержит только два хэша предыдущего состояния (ячейки кода и состояния соответственно). Когда заряд памяти адреса превышает его баланс, он переходит в это состояние. Чтобы разморозить его, Вы можете послать внутреннее сообщение с `state_init` и `code`, которые хранят описанные ранее хэши и некоторое количество Toncoin. Восстановить его может быть сложно, поэтому не стоит допускать такой ситуации. Существует проект по размораживанию адреса, который Вы можете найти [здесь](https://unfreezer.ton.org/). + +## Сырые и удобные адреса + +После краткого обзора того, как адреса смарт-контрактов на TON используют рабочие цепи и идентификаторы учетных записей (для Мастерчейна и Бейсчейна в частности), важно понять, что эти адреса выражаются в двух основных форматах: + +- **Сырые адреса**: Оригинальное полное представление адресов смарт-контрактов. +- **Удобные для пользователя адреса**: Удобные для пользователя адреса - это улучшенный формат сырого адреса, который обеспечивает лучшую безопасность и простоту использования. + +Ниже мы расскажем о различиях между этими двумя типами адресов и более подробно рассмотрим, почему на TON используются удобные для пользователя адреса. + +### Сырой адрес + +Необработанные адреса смарт-контрактов состоят из идентификатора рабочей цепи и идентификатора учетной записи *(workchain_id, account_id)* и отображаются в следующем формате: + +- [десятичный workchain_id\]:[64 шестнадцатеричных цифр с account_id\]. + +Ниже приведен пример необработанного адреса смарт-контракта, в котором используются идентификатор рабочей цепи и идентификатор учетной записи вместе (выраженные как **workchain_id** и **account_id**): + +`-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260` + +Обратите внимание на `-1` в начале строки адресов, которая обозначает *workchain_id*, принадлежащий Мастерчейну. + +:::note +Прописные буквы (такие как 'A', 'B', 'C', 'D' и т.д.) могут использоваться в адресных строках вместо их строчных аналогов (таких как 'a', 'b', 'c' 'd' и т.д.). +::: + +#### Проблемы с сырыми адресами + +При использовании формы "Сырой адрес" возникают две основные проблемы: + +1. При использовании необработанного формата адресов невозможно проверить адреса, чтобы исключить ошибки перед отправкой транзакции. + Это означает, что если Вы случайно добавите или удалите символы в адресной строке перед отправкой транзакции, Ваша транзакция будет отправлена не по назначению, что приведет к потере средств. +2. При использовании необработанного формата адреса невозможно добавить специальные флаги, подобные тем, что используются при отправке транзакций, в которых используются удобные для пользователя адреса. + Чтобы помочь Вам лучше понять эту концепцию, ниже мы объясним, какие флаги можно использовать. + +### Удобный для пользователя адрес + +Удобные адреса были разработаны для обеспечения безопасности и упрощения работы пользователей TON, которые обмениваются адресами в Интернете (например, на публичных платформах обмена сообщениями или через своих поставщиков услуг электронной почты), а также в реальном мире. + +#### Удобная структура адресов + +Удобные для пользователя адреса состоят всего из 36 байт и получаются путем генерации следующих компонентов по порядку: + +1. *[флаги - 1 байт]* - Флаги, которые прикрепляются к адресам, изменяют способ реакции смарт-контрактов на полученное сообщение. + Типы флагов, использующие удобный формат адреса, включают: + + - isBounceable. Обозначает отскакивающий или неотскакивающий тип адреса. (*0x11* для "bounceable", *0x51* для "non-bounceable") + - isTestnetOnly. Обозначает тип адреса, используемый только для целей тестовой сети. Адреса, начинающиеся с *0x80*, не должны приниматься программным обеспечением, работающим в рабочей сети + - isUrlSafe. Обозначает устаревший флаг, который определен как URL-safe для адреса. После этого все адреса считаются безопасными для URL. +2. *\[workchain_id - 1 байт]* - Идентификатор рабочей цепи (*workchain_id*) определяется подписанным 8-битным целым числом *workchain_id*.\ + (*0x00* для BaseChain, *0xff* для MasterChain) +3. *\[account_id - 32 байта]* - ID счета состоит из ([big-endian](https://www.freecodecamp.org/news/what-is-endianness-big-endian-vs-little-endian/)) 256-битного адреса в рабочей цепочке. +4. *\[Проверка адреса - 2 байта]* - В дружественных адресах проверка адреса состоит из CRC16-CCITT-подписи из предыдущих 34 байт. ([Пример](https://github.com/andreypfau/ton-kotlin/blob/ce9595ec9e2ad0eb311351c8a270ef1bd2f4363e/ton-kotlin-crypto/common/src/crc32.kt)) + На самом деле, идея, относящаяся к проверке для дружественных адресов, очень похожа на [алгоритм Luhn](https://en.wikipedia.org/wiki/Luhn_algorithm), который используется на всех кредитных картах, чтобы предотвратить ввод пользователями несуществующих номеров карт по ошибке. + +Сложение этих 4 основных компонентов означает, что: `1 + 1 + 32 + 2 = 36` байт в сумме (на один удобный для пользователя адрес). + +Чтобы сгенерировать удобный для пользователя адрес, разработчик должен закодировать все 36 байт, используя либо: + +- *base64* (т.е. с цифрами, латинскими буквами верхнего и нижнего регистра, '/' и '+') +- *base64url* (с '_' и '-' вместо '/' и '+') + +После этого процесса создание удобного для пользователя адреса длиной 48 символов без пробелов завершается. + +:::info ФЛАГИ АДРЕСОВ DNS +На TON вместо необработанных и удобных для пользователя адресов иногда используются DNS-адреса, такие как mywallet.ton. На самом деле, DNS-адреса состоят из удобных для пользователя адресов и включают в себя все необходимые флаги, которые позволяют разработчикам получить доступ ко всем флагам из DNS-записи в домене TON. +::: + +#### Примеры удобной кодировки адресов + +Например, смарт-контракт "test giver" (специальный смарт-контракт, находящийся в мастерчейне testnet, который отправляет 2 тестовых токена всем, кто их запрашивает) использует следующий сырой адрес: + +`-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260` + +Приведенный выше сырой адрес "test giver" должен быть преобразован в удобную для пользователя форму адреса. Это можно сделать с помощью форм base64 или base64url (которые мы представили ранее) следующим образом: + +- `kf/8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15+KsQHFLbKSMiYIny` (base64) +- `kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny` (base64url) + +:::info +Обратите внимание, что обе формы (*base64* и *base64url*) действительны и должны быть приняты! +::: + +#### Отказоустойчивые и неотказоустойчивые адреса + +Основная идея, лежащая в основе флага отклоняемого адреса, заключается в безопасности средств отправителя. + +Например, если целевой смарт-контракт не существует, или если во время транзакции возникли какие-то проблемы, сообщение будет "отбито" обратно отправителю и составит остаток первоначальной стоимости транзакции (за вычетом всех комиссий за перевод и газ). Это гарантирует, что отправитель не потеряет свои средства, которые были случайно отправлены на адрес, который не может принять транзакцию. + +Что касается конкретно отказоустойчивых адресов: + +1. Флаг **bounceable=false** обычно означает, что получателем является кошелек. +2. Флаг **bounceable=true** обычно обозначает пользовательский смарт-контракт с собственной прикладной логикой (например, DEX). В этом примере сообщения, не подлежащие отмене, не должны отправляться по соображениям безопасности. + +Не стесняйтесь читать больше на эту тему в нашей документации, чтобы лучше понять [непрыгающие сообщения] (/develop/smart-contracts/guidelines/non-bouncable-messages). + +#### Представления Armored base64 + +Дополнительные двоичные данные, связанные с блокчейном TON, используют аналогичные "бронированные" представления адресов в формате base64. Они отличаются друг от друга в зависимости от первых 4 символов их байтовой метки. Например, 256-битные открытые ключи Ed25519 представляются путем создания 36-байтовой последовательности, используя следующий процесс по порядку: + +- Однобайтовая метка, использующая формат *0x3E*, обозначает открытый ключ +- Однобайтовая метка, использующая формат *0xE6*, обозначает открытый ключ Ed25519. +- 32 байта, содержащие стандартное двоичное представление открытого ключа Ed25519 +- 2 байта, содержащие представление CRC16-CCITT предыдущих 34 байт в большом порядке + +Полученная 36-байтовая последовательность преобразуется в 48-символьную строку base64 или base64url стандартным образом. Например, открытый ключ Ed25519 `E39ECDA0A7B0C60A7107EC43967829DBE8BC356A49B9DFC6186B3EAC74B5477D` (обычно представленный последовательностью из 32 байт, такой как: `0xE3, 0x9E, ..., 0x7D`) представляет себя через "бронированное" представление следующим образом: + +`Pubjns2gp7DGCnEH7EOWeCnb6Lw1akm538YYaz6sdLVHfRB2` + +### Преобразование адресов, удобных для пользователя, и сырых адресов + +Самый простой способ преобразовать удобные для пользователя и необработанные адреса - использовать один из нескольких API TON и других инструментов, включая: + +- [ton.org/address](https://ton.org/address) +- [dton.io API method](https://dton.io/api/address/0:867ac2b47d1955de6c8e23f57994fad507ea3bcfe2a7d76ff38f29ec46729627) +- [Методы API toncenter в mainnet](https://toncenter.com/api/v2/#/accounts/pack_address_packAddress_get) +- [методы API toncenter в testnet](https://testnet.toncenter.com/api/v2/#/accounts/pack_address_packAddress_get) + +Кроме того, существует два способа преобразования удобных и необработанных адресов кошельков с помощью JavaScript: + +- [Преобразование адреса из/в удобную для пользователя или сырую форму с помощью ton.js](https://github.com/ton-org/ton-core/blob/main/src/address/Address.spec.ts) +- [Преобразование адреса из/в удобную для пользователя или сырую форму с помощью tonweb](https://github.com/toncenter/tonweb/tree/master/src/utils#address-class) + +Также можно использовать подобные механизмы с помощью [SDKs](/develop/dapps/apis/sdk). + +### Примеры адресов + +Узнайте больше примеров по адресам TON в [Поваренной книге TON] (/develop/dapps/cookbook#working-with-contracts-addresses). + +## Возможные проблемы + +При взаимодействии с блокчейном TON крайне важно понимать последствия перевода монет TON на адреса `uninit` кошельков. В этом разделе описаны различные сценарии и их результаты, чтобы прояснить, как обрабатываются такие транзакции. + +### Что произойдет, если Вы переведете Toncoin на неинициативный адрес? + +#### Транзакция с включенным `state_init` + +Если Вы включите `state_init` (который состоит из кода и данных кошелька или смарт-контракта) в Вашу транзакцию. Сначала смарт-контракт развертывается с помощью предоставленного `state_init`. После развертывания входящее сообщение обрабатывается, аналогично отправке на уже инициализированный счет. + +#### Транзакция без установленного флага `state_init` и `bounce` + +Сообщение не может быть доставлено смарт-контракту `uninit`, и оно будет отклонено обратно отправителю. После вычета платы за потребленный газ оставшаяся сумма возвращается на адрес отправителя. + +#### Транзакция без установленного флага `state_init` и `bounce` + +Сообщение не может быть доставлено, но оно не вернется обратно к отправителю. Вместо этого отправленная сумма будет зачислена на адрес получателя, увеличив его баланс, даже если кошелек еще не инициализирован. Они будут храниться там до тех пор, пока владелец адреса не запустит контракт умного кошелька, после чего он сможет получить доступ к балансу. + +#### Как сделать это правильно + +Лучший способ развернуть кошелек - отправить несколько TON на его адрес (который еще не инициализирован) со снятым флагом `bounce`. После этого владелец может развернуть и инициализировать кошелек, используя средства на текущем неинициализированном адресе. Этот шаг обычно происходит при первой операции с кошельком. + +### В блокчейне TON реализована защита от ошибочных транзакций + +В блокчейне TON стандартные кошельки и приложения автоматически справляются со сложностями транзакций на неинициализированные адреса, используя отскакивающие и неотскакивающие адреса, которые описаны [здесь](#bounceable-vs-non-bounceable-addresses). Обычно кошельки, отправляя монеты на неинициализированные адреса, отправляют монеты как на bounceable, так и на non-bounceable адреса без возврата. + +Если необходимо быстро получить адрес в форме bounceable/non-bounceable, это можно сделать [здесь](https://ton.org/address/). + +### Ответственность за заказные продукты + +Если Вы разрабатываете собственный продукт на блокчейне TON, необходимо реализовать аналогичные проверки и логику: + +Перед отправкой средств убедитесь, что Ваше приложение проверяет, инициализирован ли адрес получателя. +Основываясь на состоянии адреса, используйте отказоустойчивые адреса для пользовательских смарт-контрактов с пользовательской логикой приложения для обеспечения возврата средств. Для кошельков используйте адреса без отказов. diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/learn/overviews/cells.md b/i18n/ru/docusaurus-plugin-content-docs/current/learn/overviews/cells.md new file mode 100644 index 0000000000..825b22232a --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/learn/overviews/cells.md @@ -0,0 +1,52 @@ +# Клетки как хранилище данных + +Все данные в TON хранятся в ячейках. Ячейка - это структура данных, содержащая: + +- до **1023 бит** данных (не байтов!) +- до **4 ссылок** на другие ячейки + +Биты и ссылки не смешиваются (они хранятся отдельно). Циклические ссылки запрещены: для любой ячейки ни одна из ее потомков не может иметь эту исходную ячейку в качестве ссылки. + +Таким образом, все клетки представляют собой направленный ациклический граф (DAG). Вот хороший рисунок для иллюстрации: + +![Directed Acylic Graph](/img/docs/dag.png) + +## Типы клеток + +В настоящее время существует 5 типов клеток: *обычные* и 4 *экзотических*. +К экзотическим типам относятся следующие: + +- Обрезанная клетка ветви +- Справочная ячейка библиотеки +- Ячейка с доказательством Меркла +- Ячейка обновления Меркле + +:::tip +Подробнее об экзотических клетках см: [**TVM Whitepaper, раздел 3**] (https://ton.org/tvm.pdf). +::: + +## Вкусовые качества клеток + +Ячейка - это непрозрачный объект, оптимизированный для компактного хранения. + +В частности, она дедуплицирует данные: если в разных ветвях есть несколько эквивалентных подячеек, на которые ссылаются разные ветви, их содержимое хранится только один раз. Однако непрозрачность означает, что ячейка не может быть изменена или прочитана напрямую. Таким образом, существует 2 дополнительных вида ячеек: + +- *Строитель* для частично построенных ячеек, для которых могут быть определены быстрые операции по добавлению битовых строк, целых чисел, других ячеек и ссылок на другие ячейки. +- *Slice* для "разрезанных" ячеек, представляющих собой либо остаток частично разобранной ячейки, либо значение (подячейку), находящееся внутри такой ячейки и извлеченное из нее с помощью инструкции синтаксического анализа. + +В TVM используется еще один особый клеточный вкус: + +- *Продолжение* для ячеек, содержащих оп-коды (инструкции) для виртуальной машины TON, смотрите [обзор TVM с высоты птичьего полета](/learn/tvm-instructions/tvm-overview). + +## Сериализация данных в ячейки + +Любой объект в TON (сообщение, очередь сообщений, блок, состояние всего блокчейна, код и данные контракта) сериализуется в ячейку. + +Процесс сериализации описывается схемой TL-B: формальное описание того, как данный объект может быть сериализован в *Builder* или как разобрать объект заданного типа из *Slice*. +TL-B для ячеек - это то же самое, что TL или ProtoBuf для байтовых потоков. + +Если Вы хотите узнать больше подробностей о (де)сериализации ячеек, Вы можете прочитать статью [Cell & Bag of Cells](/develop/data-formats/cell-boc). + +## См. также + +- [Язык TL-B](/develop/data-formats/tl-b-language) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/learn/overviews/ton-blockchain.md b/i18n/ru/docusaurus-plugin-content-docs/current/learn/overviews/ton-blockchain.md new file mode 100644 index 0000000000..6c8de1a137 --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/learn/overviews/ton-blockchain.md @@ -0,0 +1,72 @@ +# Блокчейн из блокчейнов + +:::tip +Термины "**умный контракт**", "**аккаунт**" и "**актор**" используются в этом документе как взаимозаменяемые для описания сущности блокчейна. +::: + +## Одиночный актер + +Давайте рассмотрим один смарт-контракт. + +В TON это *вещь* с такими свойствами, как `адрес`, `код`, `данные`, `баланс` и другими. Другими словами, это объект, который обладает некоторым *хранилищем* и *поведением*. +Это поведение имеет следующий вид: + +- Что-то происходит (наиболее распространенная ситуация - контракт получает сообщение) +- Контракт обрабатывает это событие в соответствии со своими свойствами, выполняя свой `код` в виртуальной машине TON. +- контракт изменяет свои собственные свойства (`код`, `данные` и другие) +- контракт опционально генерирует исходящие сообщения +- контракт переходит в режим ожидания до наступления следующего события + +Комбинация этих шагов называется **транзакцией**. Важно, чтобы события обрабатывались поочередно, поэтому *транзакции* строго упорядочены и не могут прерывать друг друга. + +Эта модель поведения хорошо известна и называется "Актер". + +### Самый низкий уровень: Цепочка счетов + +Последовательность *транзакций* `Tx1 -> Tx2 -> Tx3 -> ....` можно назвать **цепочкой**. А в рассматриваемом случае она называется **AccountChain**, чтобы подчеркнуть, что это *цепочка* одного счета транзакций. + +Теперь, поскольку узлам, обрабатывающим транзакции, необходимо время от времени согласовывать состояние смарт-контракта (чтобы достичь *консенсуса* по поводу состояния), эти *транзакции* разбиваются на блоки: +`[Tx1 -> Tx2] -> [Tx3 -> Tx4 -> Tx5] -> [] -> [Tx6]`. +Пакетирование не вмешивается в последовательность, каждая транзакция по-прежнему имеет только один "предыдущий tx" и максимум один "следующий tx", но теперь эта последовательность разбита на **блоки**. + +Также целесообразно включить в *блоки* очереди входящих и исходящих сообщений. В этом случае *блок* будет содержать полный набор информации, определяющей и описывающей, что произошло со смарт-контрактом во время этого блока. + +## Множество AccountChains: Осколки + +Теперь рассмотрим множество аккаунтов. Мы можем получить несколько *AccountChains* и хранить их вместе, такой набор *AccountChains* называется **ShardChain**. Таким же образом мы можем разрезать **ShardChain** на **ShardBlocks**, которые представляют собой совокупность отдельных *AccountBlocks*. + +### Динамическое разделение и объединение цепочек шардов + +Обратите внимание, что поскольку *ShardChain* состоит из легко различимых *AccountChain*, мы можем легко разделить его. Таким образом, если у нас есть 1 *ShardChain*, которая описывает события, происходящие с 1 миллионом аккаунтов, и в ней слишком много транзакций в секунду для обработки и хранения на одном узле, мы просто разделим (или **разделим**) эту цепочку на две меньшие *ShardChain*, каждая из которых будет учитывать полмиллиона аккаунтов, и каждая цепочка будет обрабатываться на отдельном подмножестве узлов. + +Аналогичным образом, если некоторые осколки стали слишком незанятыми, они могут быть **слиты** в один больший осколок. + +Очевидно, что существует два предельных случая: когда осколок содержит только одну учетную запись (и поэтому не может быть разделен дальше) и когда осколок содержит все учетные записи. + +Учетные записи могут взаимодействовать друг с другом, посылая сообщения. Существует специальный механизм маршрутизации, который перемещает сообщения из исходящих очередей в соответствующие входящие очереди и гарантирует, что 1) все сообщения будут доставлены 2) сообщения будут доставлены последовательно (сообщение, отправленное раньше, достигнет места назначения раньше). + +:::info БОКОВОЕ ПРИМЕЧАНИЕ +Чтобы сделать разделение и объединение детерминированным, объединение цепочек счетов в шарды основано на битовом представлении адресов счетов. Например, адрес выглядит как `(префикс шарда, адрес)`. Таким образом, все аккаунты в шард-цепочке будут иметь абсолютно одинаковый двоичный префикс (например, все адреса будут начинаться с `0b00101`). +::: + +## Блокчейн + +Совокупность всех шардов, содержащая все аккаунты, ведущие себя в соответствии с одним набором правил, называется **Блокчейн**. + +В TON может быть множество наборов правил и, соответственно, множество блокчейнов, которые работают одновременно и могут взаимодействовать друг с другом, отправляя сообщения кросс-чейн таким же образом, как счета одной цепи могут взаимодействовать друг с другом. + +### Workchain: Блокчейн с вашими собственными правилами + +Если Вы хотите настроить правила группы шардчейнов, Вы можете создать **Workchain**. Хороший пример - создать воркчейн, работающий на базе EVM, чтобы запускать на нем смарт-контракты Solidity. + +Теоретически, каждый член сообщества может создать свой собственный воркчейн. На самом деле, это довольно сложная задача - создать его, затем заплатить (дорогую) цену за его создание и получить 2/3 голосов от валидаторов, чтобы одобрить создание Вашего Workchain. + +TON позволяет создавать до `2^32` рабочих цепочек, каждая из которых подразделяется на до `2^60` шардов. + +В настоящее время в TON существует только 2 рабочих цепочки: MasterChain и BaseChain. + +BaseChain используется для повседневных транзакций между участниками, потому что он довольно дешевый, а MasterChain выполняет важнейшую функцию для TON, так что давайте рассмотрим, что он делает! + +### Мастерчейн: Блокчейн из блокчейнов + +Существует необходимость в синхронизации маршрутизации сообщений и выполнения транзакций. Другими словами, узлам сети нужен способ зафиксировать некоторую "точку" в состоянии мультицепочки и прийти к консенсусу относительно этого состояния. В TON для этой цели используется специальная цепочка, называемая **MasterChain**. Блоки *masterchain* содержат дополнительную информацию (последние хэши блоков) обо всех остальных цепочках в системе, поэтому любой наблюдатель однозначно определяет состояние всех мультичейн-систем по одному блоку masterchain. diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/learn/tvm-instructions/tvm-overview.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/learn/tvm-instructions/tvm-overview.mdx new file mode 100644 index 0000000000..662c2ff96c --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/learn/tvm-instructions/tvm-overview.mdx @@ -0,0 +1,133 @@ +import Button from '@site/src/components/button' + +# Обзор TVM + +Все смарт-контракты TON выполняются на собственной виртуальной машине TON (TVM). TVM построена по принципу _стека_, что делает ее эффективной и простой в реализации. + +Этот документ дает представление о том, как TVM выполняет транзакции с высоты птичьего полета. + +:::tip + +- TVM Source - [**TVM C++ implementation**](https://github.com/ton-blockchain/ton/tree/master/crypto/vm) + ::: + +## Курс TON: TVM + +:::tip +Прежде чем приступить к изучению курса, убедитесь, что Вы хорошо понимаете основы технологии блокчейн. Если у Вас есть пробелы в знаниях, мы рекомендуем пройти курс [Основы блокчейна с TON](https://stepik.org/course/201294/promo) ([RU версия](https://stepik.org/course/202221/), [CHN версия](https://stepik.org/course/200976/)). +::: + +Курс [TON Blockchain Course](https://stepik.org/course/176754/) - это полное руководство по разработке TON Blockchain. + +Модуль 2 полностью охватывает **TVM**, транзакции, масштабируемость и бизнес-кейсы. + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Транзакции и фазы + +Когда на счете в одной из цепочек TON происходит какое-то событие, оно вызывает **транзакцию**. Наиболее распространенным событием является "прибытие какого-либо сообщения", но в общем случае это могут быть `tick-tock`, `merge`, `plit` и другие события. + +Каждая транзакция состоит из 5 этапов: + +1. **Фаза хранения** - на этой фазе рассчитывается плата за хранение, накопленная контрактом за занятие некоторого пространства в состоянии цепочки. Подробнее читайте в разделе [Плата за хранение] (/develop/smart-contracts/fees#storage-fee). +2. **Фаза кредитования** - на этой фазе рассчитывается баланс контракта в отношении (возможного) значения входящего сообщения и собранной платы за хранение. +3. **Фаза вычисления** - на этой фазе TVM выполняет контракт (см. ниже), и результатом выполнения контракта является агрегирование `exit_code`, `actions` (сериализованный список действий), `gas_details`, `new_storage` и некоторых других. +4. **Фаза действий** - если фаза вычислений прошла успешно, на этой фазе обрабатываются `действия`, полученные на фазе вычислений. В частности, действия могут включать отправку сообщений, обновление кода смарт-контракта, обновление библиотек и т.д. Обратите внимание, что некоторые действия могут быть неудачными во время обработки (например, если мы попытаемся отправить сообщение с большим количеством TON, чем есть у контракта), в этом случае вся транзакция может быть отменена или это действие может быть пропущено (это зависит от режима действий, другими словами, контракт может отправить сообщение типа `send-or-revert или `try-send-if-no-ignore\`). +5. **Фаза отскока** - если фаза вычисления завершилась неудачно (вернула `exit_code >= 2`), в этой фазе формируется _отскок сообщения_ для транзакций, инициированных входящим сообщением. + +## Вычислите фазу + +В этой фазе происходит выполнение TVM. + +### Состояние TVM + +В любой момент времени состояние TVM полностью определяется 6 свойствами: + +- Стек (см. ниже) +- Управляющие регистры - (см. ниже), проще говоря, это до 16 переменных, которые можно напрямую устанавливать и считывать во время выполнения. +- Текущее продолжение - объект, описывающий выполняемую в данный момент последовательность инструкций +- Текущая кодовая страница - простыми словами, это означает версию TVM, которая запущена в данный момент +- Лимиты газа - набор из 4 целых значений; текущий лимит газаgl, максимальный лимит газа gm, остаток газаgr и кредит газа gc +- Библиотечный контекст - хэшмап библиотек, которые могут быть вызваны TVM + +### TVM - это стековая машина + +TVM - это стековая машина с последним входом и первым выходом. Всего существует 7 типов переменных, которые могут храниться в стеке - три неклеточных типа: + +- Integer - подписанные 257-битные целые числа +- Кортеж - упорядоченная коллекция, включающая до 255 элементов с произвольными типами значений, возможно, различных. +- Null + +И четыре разных вкуса клеток: + +- Ячейка - базовая (возможно, вложенная) непрозрачная структура, используемая блокчейном TON для хранения всех данных +- Slice - специальный объект, который позволяет Вам читать из ячейки +- Конструктор - специальный объект, который позволяет Вам создавать новые ячейки +- Продолжение - специальный объект, который позволяет Вам использовать ячейку в качестве источника инструкций TVM + +### Регистры управления + +- `c0` - Содержит следующее продолжение или продолжение возврата (аналогично адресу возврата подпрограммы в обычных конструкциях). Это значение должно быть продолжением. +- `c1` - Содержит альтернативное (возвратное) продолжение; это значение должно быть продолжением. +- `c2` - Содержит обработчик исключений. Это значение представляет собой Продолжение, вызываемое всякий раз, когда срабатывает исключение. +- `c3` - Поддерживающий регистр, содержит текущий словарь, по сути, хэшмап, содержащий код всех функций, используемых в программе. Это значение должно быть продолжением. +- `c4` - Содержит корень постоянных данных, или просто раздел `data` контракта. Это значение представляет собой ячейку. +- `c5` - Содержит выходные действия. Это значение представляет собой ячейку. +- `c7` - Содержит корень временных данных. Это кортеж. + +### Инициализация TVM + +TVM инициализируется, когда транзакция переходит в фазу Вычисления, и затем выполняет команды (опкоды) из _Текущего продолжения_ до тех пор, пока не останется команд для выполнения (и продолжения для возвратных переходов). + +Подробное описание процесса инициализации можно найти здесь: [Инициализация TVM](/learn/tvm-instructions/tvm-initialization.md) + +## Инструкции TVM + +Список инструкций TVM можно найти здесь: [Инструкции TVM](/learn/tvm-instructions/instructions). + +### Результат выполнения TVM + +Помимо кода выхода (exit_code) и данных о потребленном газе, TVM косвенно выводит следующие данные: + +- c4 регистр - ячейка, которая будет сохранена как новые `данные` смарт-контракта (если выполнение не будет отменено на этой или последующих фазах) +- c5 register - (список действий на выходе) ячейка с последним действием в списке и ссылка на ячейку с предыдущим действием (рекурсивно) + +Все остальные значения регистров будут игнорироваться. + +Обратите внимание, что поскольку существует ограничение на максимальную глубину ячеек `<1024`, и особенно ограничение на глубину c4 и c5 `<=512`, будет существовать ограничение на количество выходных действий в одной tx `<=255`. Если контракту нужно отправить больше, он может послать сообщение с запросом `continue_sending` самому себе и отправить все необходимые сообщения в последующих транзакциях. + +## См. также + +- [Инструкции TVM](/learn/tvm-instructions/instructions) +- [TON TVM](https://ton.org/tvm.pdf) Концепции TVM (может содержать устаревшую информацию) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/participate/README.md b/i18n/ru/docusaurus-plugin-content-docs/current/participate/README.md new file mode 100644 index 0000000000..ce6f728345 --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/participate/README.md @@ -0,0 +1,38 @@ +# Обзор + +Раздел "Участвовать" нашей документации предназначен для того, чтобы пользователи могли открыть для себя возможности работы с TON +Он также призван предложить основные механизмы (explorers, wallets, TEPs), которые необходимы для участия в экосистеме TON и создании концепции TON для TON World Wide Web (TWWW). + +## Участвуйте в экосистеме TON + +- [TON Explorers](/participate/explorers) +- [Приложения для кошельков (для разработчиков)](/participate/wallets/apps) +- [Типы контрактов кошелька](/participate/wallets/contracts) + +### Присоединяйтесь к сообществу TON + +- [TON Enhancement Proposals (TEPs)](https://github.com/ton-blockchain/TEPs) +- [Откройте для себя инновации TON на сайте TON Research](https://tonresear.ch/) +- [Ставка с номинантами TON](/participate/network-maintenance/nominators) + +### Мосты + +- [Обзор мостов](/participate/crosschain/overview) +- [Адреса мостов] (/participate/crosschain/bridge-addresses) + +### Запустите узел + +- [Узнайте о типах узлов в TON] (/participate/nodes/node-types) +- [Запустите свой полный узел или валидатор] (/participate/run-nodes/full-node) +- [Обслуживание и безопасность валидатора TON] (/participate/nodes/node-maintenance-and-security) + +## Участвуйте в TON Web3 + +- [TON Web3 Overview](/participate/web3/overview) +- [Используйте TON DNS для своих доменов](/participate/web3/dns) +- [Управление сайтами и доменами](/participate/web3/site-management) +- [\[Tutorial\] Как запустить свой собственный TON-сайт?](/develop/dapps/tutorials/how-to-run-ton-site) + +### TON Proxy + +- [Как открыть любой сайт TON?] (/participate/web3/how-to-open-any-ton-site) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/participate/crosschain/overview.md b/i18n/ru/docusaurus-plugin-content-docs/current/participate/crosschain/overview.md new file mode 100644 index 0000000000..e6ed75df04 --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/participate/crosschain/overview.md @@ -0,0 +1,57 @@ +# Межцепочечные мостики + +Децентрализованные межцепочечные мосты работают на блокчейне TON Blockchain, позволяя Вам переводить активы с блокчейна TON Blockchain на другие блокчейны и наоборот. + +## Тонкоинский мост + +Мост Toncoin позволяет Вам переводить Toncoin между блокчейном TON и блокчейном Ethereum, а также между блокчейном TON и смарт-цепочкой BNB. + +Мост управляется [децентрализованными оракулами](/participate/crosschain/bridge-addresses). + +### Как его использовать? + +Фронтенд Bridge размещен на сайте https://ton.org/bridge. + +:::info +[Исходный код фронтенда Bridge](https://github.com/ton-blockchain/bridge) +::: + +### Исходные коды смарт-контрактов TON-Ethereum + +- [FunC (сторона TON)](https://github.com/ton-blockchain/bridge-func) +- [Solidity (сторона Ethereum)](https://github.com/ton-blockchain/bridge-solidity/tree/eth_mainnet) + +### Исходные коды смарт-контрактов TON-BNB Smart Chain + +- [FunC (сторона TON)](https://github.com/ton-blockchain/bridge-func/tree/bsc) +- [Solidity (BSC side)](https://github.com/ton-blockchain/bridge-solidity/tree/bsc_mainnet) + +### Конфиги блокчейна + +Вы можете получить фактические адреса смарт-контрактов моста и адреса оракулов, просмотрев соответствующий конфиг: + +TON-Ethereum: [#71](https://github.com/ton-blockchain/ton/blob/35d17249e6b54d67a5781ebf26e4ee98e56c1e50/crypto/block/block.tlb#L738). + +TON-BSC: [#72](https://github.com/ton-blockchain/ton/blob/35d17249e6b54d67a5781ebf26e4ee98e56c1e50/crypto/block/block.tlb#L739). + +TON-Polygon: [#73](https://github.com/ton-blockchain/ton/blob/35d17249e6b54d67a5781ebf26e4ee98e56c1e50/crypto/block/block.tlb#L740). + +### Документация + +- [Как работает мост](https://github.com/ton-blockchain/TIPs/issues/24) + +### Дорожная карта межцепочечного взаимодействия + +- https://t.me/tonblockchain/146 + +## Мост Тонана + +### Как принять участие? + +:::caution проект\ +Это концептуальная статья. Мы все еще ищем кого-то опытного для ее написания. +::: + +Вы можете найти фронт-энд здесь: https://tonana.org/. + +Исходный код находится здесь: https://github.com/tonanadao diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/participate/web3/overview.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/participate/web3/overview.mdx new file mode 100644 index 0000000000..e774ee00b5 --- /dev/null +++ b/i18n/ru/docusaurus-plugin-content-docs/current/participate/web3/overview.mdx @@ -0,0 +1,17 @@ +# Обзор + +## Концепции + +Подробнее об идеях читайте в: + +- [Выплаты на TON](https://blog.ton.org/ton-payments) +- [TON DNS & Domains](/participate/web3/dns) +- [Сайты TON, TON WWW и TON Proxy](https://blog.ton.org/ton-sites) + +## Примеры использования + +- [\*.ton удобные домены для любого смарт-контракта](/participate/web3/dns) +- [Подключение к сайтам TON с помощью прокси-сервера TON] (/participate/web3/setting-proxy) +- [Запустите собственный TON-прокси для подключения к сайтам TON] (/participate/web3/sites-and-proxy) +- [Привяжите Ваш кошелек TON или сайт TON к домену](/participate/web3/site-management) +- [Как создать поддомен с помощью смарт-контрактов TON DNS](/participate/web3/site-management#how-to-set-up-subdomains) diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md b/i18n/uk/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md new file mode 100644 index 0000000000..e70c35b5e9 --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/contribute/localization-program/overview.md @@ -0,0 +1,39 @@ +# Програма локалізації + +Програма перекладу - це спільна робота над перекладом різних документів, пов'язаних з ТОН, на різні мови, що робить веб-сайт більш доступним для мільярдів неангломовних людей у всьому світі. + +## Філософія системного дизайну + +![як це працює](/img/localizationProgramGuideline/localization-program.png) + +Програму локалізації започаткувала та активно підтримує [**TownSquare Labs**] (https://github.com/TownSquareXYZ), один з найближчих партнерів **TON**. + +Ми прагнемо створити відкриту інфраструктуру для співпраці багатомовних спільнот, щоб **просунути TON до кращої фази**, що включає в себе + +1. **Підходить для багатомовних спільнот**\ + Програма підтримує кілька мов, забезпечуючи інклюзивність та легкий доступ для користувачів з різним мовним досвідом. + +2. **Автоматизуйте розробку, інтеграцію та розгортання**\ + Завдяки використанню інструментів автоматизації програма впорядковує процеси розробки, інтеграції та розгортання, зменшуючи ручну працю та підвищуючи ефективність і узгодженість усіх зусиль з локалізації. + +3. **Розмежування ролей розробника, перекладача та верифікатора**\ + Наш підхід розмежовує обов'язки розробників, перекладачів і верифікаторів, дозволяючи кожній ролі зосередитися на своїх конкретних завданнях. Це забезпечує високу якість перекладів і злагоджену співпрацю без дублювання або конфлікту обов'язків. + +4. **Заохочення за внесок громади**\ + Ми надаємо заохочення членам громади, які роблять внесок у процес локалізації. Це заохочує активну участь і винагороджує тих, хто допомагає покращити програму, сприяючи формуванню почуття причетності та духу спільноти. + +5. **Інтеграція передових систем штучного інтелекту**\ + Передові системи штучного інтелекту підвищують точність і ефективність перекладу, надаючи інтелектуальні пропозиції й автоматизуючи повторювані завдання, забезпечуючи якісні результати з меншими зусиллями. + +Цей проект не лише для носіїв однієї мови; наша мета - служити глобальній екосистемі розробників. + +## Подяки + +Ми дуже вдячні тисячам членів спільноти, які є ключовою частиною Перекладацької програми. Ми хочемо відзначити наших перекладачів і підтримати їх на їхньому кар'єрному шляху. Найближчим часом ми відзначимо наших найкращих перекладачів, створивши таблиці лідерів і список усіх, хто долучився до перекладацької програми. + +## Посібники та ресурси + +Якщо ви робите свій внесок у Програму перекладу або плануєте долучитися до неї, будь ласка, ознайомтеся з настановами для перекладачів, наведеними нижче: + +- [**Посібник зі стилю перекладу**](/contribute/localization-program/translation-style-guide) - Інструкції та поради для перекладачів. +- [**Посібник з онлайн-редактора Crowdin**](https://support.crowdin.com/online-editor/) - детальний посібник з використання онлайн-редактора Crowdin та деяких додаткових можливостей Crowdin. diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/README.md b/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/README.md new file mode 100644 index 0000000000..64d7d9a063 --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/README.md @@ -0,0 +1,587 @@ +import Button from '@site/src/components/button' +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Обробка платежів + +Ця сторінка пояснює, як обробляти\*\* (відправляти і приймати) "цифрові активи" в блокчейні TON. +В основному тут описано, як працювати з монетами TON, але теоретична частина важлива, навіть якщо ви хочете обробляти тільки джеттони. + +## Смарт-контракт гаманця + +Смарт-контракти гаманців - це контракти в мережі TON, які слугують для того, щоб дозволити суб'єктам за межами блокчейну взаємодіяти з об'єктами блокчейну. Загалом, вони вирішують три завдання: + +- аутентифікує власника: Відмовляється обробляти та сплачувати збори за запити невласників. +- захист від повторів: Забороняє повторне виконання одного запиту, наприклад, надсилання активів іншому смарт-контракту. +- ініціює довільну взаємодію з іншими смарт-контрактами. + +Стандартним рішенням для першої проблеми є криптографія з відкритим ключем: "гаманець" зберігає відкритий ключ і перевіряє, що вхідне повідомлення із запитом підписане відповідним закритим ключем, який відомий лише власнику. + +Вирішення третьої проблеми також є поширеним: зазвичай запит містить повністю сформоване внутрішнє повідомлення, яке "гаманець" надсилає в мережу. Однак, для захисту від повторного відтворення існує декілька різних підходів. + +### Гаманці на основі Seqno + +Гаманці на основі Seqno використовують найпростіший підхід до впорядкування повідомлень. Кожне повідомлення має спеціальне ціле число `seqno`, яке повинно збігатися з лічильником, що зберігається в смарт-контракті `гаманця`. Гаманець оновлює свій лічильник при кожному запиті, таким чином гарантуючи, що один запит не буде оброблений двічі. Існує кілька версій "гаманця", які відрізняються загальнодоступними методами: можливість обмежувати запити за часом дії та можливість мати кілька гаманців з одним і тим же публічним ключем. Однак, невід'ємною вимогою такого підходу є надсилання запитів по одному, оскільки будь-яка прогалина в послідовності `seqno` призведе до неможливості обробки всіх наступних запитів. + +### Гаманці з високим навантаженням + +Цей тип "гаманця" використовує підхід, заснований на зберіганні ідентифікатора оброблених запитів, термін дії яких не закінчився, у сховищі смарт-контрактів. У цьому підході будь-який запит перевіряється на наявність дублікату вже обробленого запиту і, якщо виявлено повторення, відхиляється. Через закінчення терміну дії контракт не може зберігати всі запити вічно, але він буде видаляти ті, які не можуть бути оброблені через обмеження терміну дії. Запити до цього "гаманця" можуть надсилатися паралельно, не заважаючи один одному, але такий підхід вимагає більш складного моніторингу обробки запитів. + +### Розгортання гаманця + +Для розгортання гаманця через TonLib потрібно зробити наступне: + +1. Згенеруйте пару приватний/відкритий ключ за допомогою [createNewKey](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L244) або його функцій-обгорток (приклад у [tonlib-go](https://github.com/mercuryoio/tonlib-go/tree/master/v2#create-new-private-key)). Зверніть увагу, що приватний ключ генерується локально і не залишає хост-машину. +2. Сформуйте структуру [InitialAccountWallet](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L62), що відповідає одному з увімкнених `гаманців`. Наразі доступні `wallet.v3`, `wallet.v4`, `wallet.highload.v1`, `wallet.highload.v2`. +3. Обчисліть адресу нового смарт-контракту `гаманця` за допомогою методу [getAccountAddress](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L283). Ми рекомендуємо використовувати ревізію за замовчуванням `0`, а також розгортати гаманці в базовому ланцюжку `workchain=0` для зниження витрат на обробку та зберігання. +4. Надішліть трохи Toncoin на розраховану адресу. Зверніть увагу, що ви повинні відправити їх в режимі `non-bounce`, оскільки ця адреса ще не має коду і не може обробляти вхідні повідомлення. Прапорець `non-bounce` вказує на те, що навіть у разі невдалої обробки, гроші не повинні повертатися з повідомленням про відмову. Ми не рекомендуємо використовувати прапорець `non-bounce` для інших транзакцій, особливо при переказі великих сум, оскільки механізм відмов забезпечує певний захист від помилок. +5. Сформуйте потрібну [action](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L154), наприклад, `actionNoop` тільки для розгортання. Потім використовуйте [createQuery](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L292) і [sendQuery](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L300), щоб ініціювати взаємодію з блокчейном. +6. Перевірте контракт за кілька секунд за допомогою методу [getAccountState](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L288). + +:::tip +Дізнайтеся більше в [Навчальному посібнику з гаманця] (/develop/smart-contracts/tutorials/wallet#-deploying-a-wallet) +::: + +### Перевірте дійсність адреси гаманця + +Більшість SDK вимагають верифікації адреси (більшість перевіряє її під час створення гаманця або підготовки транзакції), тому, як правило, це не вимагає від вас ніяких додаткових складних кроків. + + + + + +```js + const TonWeb = require("tonweb") + TonWeb.utils.Address.isValid('...') +``` + + + + +```python +package main + +import ( + "fmt" + "github.com/xssnick/tonutils-go/address" +) + +if _, err := address.ParseAddr("EQCD39VS5j...HUn4bpAOg8xqB2N"); err != nil { + return errors.New("invalid address") +} +``` + + + + +```javascript +try { + Address.of("..."); + } catch (e) { + // not valid address +} +``` + + + + +```javascript + try { + AddrStd("...") + } catch(e: IllegalArgumentException) { + // not valid address + } +``` + + + + +:::tip +Повний опис адрес на сторінці [Адреси смарт-контрактів](/learn/overviews/addresses). +::: + +## Робота з переказами + +### Перевірте транзакції за контрактом + +Транзакції контракту можна отримати за допомогою [getTransactions](https://toncenter.com/api/v2/#/accounts/get_transactions_getTransactions_get). Цей метод дозволяє отримати 10 транзакцій, починаючи з деякого `last_transaction_id` і раніше. Щоб обробити всі отримані транзакції, слід виконати наступні кроки: + +1. Останній `last_transaction_id` можна отримати за допомогою [getAddressInformation](https://toncenter.com/api/v2/#/accounts/get_address_information_getAddressInformation_get) +2. Список з 10 транзакцій повинен бути завантажений за допомогою методу `getTransactions`. +3. Обробляти транзакції з не порожнім джерелом у вхідному повідомленні та призначенням, що дорівнює адресі акаунта. +4. Завантажте наступні 10 транзакцій і повторіть кроки 2,3,4,5, поки не обробите всі вхідні транзакції. + +### Отримуйте вхідні/вихідні транзакції + +Під час обробки транзакцій можна відстежувати потік повідомлень. Оскільки потік повідомлень є DAG, достатньо отримати поточну транзакцію методом [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get) і знайти вхідну транзакцію за `out_msg` за допомогою [tryLocateResultTx](https://testnet.toncenter.com/api/v2/#/transactions/get_try_locate_result_tx_tryLocateResultTx_get) або вихідну за `in_msg` за допомогою [tryLocateSourceTx](https://testnet.toncenter.com/api/v2/#/transactions/get_try_locate_source_tx_tryLocateSourceTx_get). + + + + +```ts +import { TonClient, Transaction } from '@ton/ton'; +import { getHttpEndpoint } from '@orbs-network/ton-access'; +import { CommonMessageInfoInternal } from '@ton/core'; + +async function findIncomingTransaction(client: TonClient, transaction: Transaction): Promise { + const inMessage = transaction.inMessage?.info; + if (inMessage?.type !== 'internal') return null; + return client.tryLocateSourceTx(inMessage.src, inMessage.dest, inMessage.createdLt.toString()); +} + +async function findOutgoingTransactions(client: TonClient, transaction: Transaction): Promise { + const outMessagesInfos = transaction.outMessages.values() + .map(message => message.info) + .filter((info): info is CommonMessageInfoInternal => info.type === 'internal'); + + return Promise.all( + outMessagesInfos.map((info) => client.tryLocateResultTx(info.src, info.dest, info.createdLt.toString())), + ); +} + +async function traverseIncomingTransactions(client: TonClient, transaction: Transaction): Promise { + const inTx = await findIncomingTransaction(client, transaction); + // now you can traverse this transaction graph backwards + if (!inTx) return; + await traverseIncomingTransactions(client, inTx); +} + +async function traverseOutgoingTransactions(client: TonClient, transaction: Transaction): Promise { + const outTxs = await findOutgoingTransactions(client, transaction); + // do smth with out txs + for (const out of outTxs) { + await traverseOutgoingTransactions(client, out); + } +} + +async function main() { + const endpoint = await getHttpEndpoint({ network: 'testnet' }); + const client = new TonClient({ + endpoint, + apiKey: '[API-KEY]', + }); + + const transaction: Transaction = ...; // Obtain first transaction to start traversing + await traverseIncomingTransactions(client, transaction); + await traverseOutgoingTransactions(client, transaction); +} + +main(); +``` + + + + +### Надсилайте платежі + +1. Сервіс повинен розгорнути "гаманець" і підтримувати його фінансування, щоб запобігти розірванню контракту через плату за зберігання. Зауважте, що плата за зберігання зазвичай становить менше 1 тонкоїна на рік. +2. Сервіс повинен отримувати від користувача `адреса_призначення` та необов'язковий `коментар`. Зауважте, що поки що ми рекомендуємо або заборонити незавершені вихідні платежі з однаковим набором (`адреса_призначення`, `вартість`, `коментар`), або правильно розпланувати ці платежі - так, щоб наступний платіж ініціювався лише після підтвердження попереднього. +3. Сформуйте [msg.dataText](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L103) з `comment` як текстом. +4. Сформуйте [msg.message](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L113), що містить `адресу_одержувача`, порожній `публічний_ключ`, `суму` та `msg.dataText`. +5. Форма [Дія](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L154), яка містить набір вихідних повідомлень. +6. Для відправки вихідних платежів використовуйте запити [createQuery](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L292) та [sendQuery](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L300). +7. Сервіс повинен регулярно опитувати метод [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get) для контракту `гаманця`. Зіставлення підтверджених транзакцій з вихідними платежами за (`адреса_призначення`, `вартість`, `коментар`) дозволяє позначати платежі як завершені; визначати та показувати користувачеві відповідний хеш транзакції та lt (логічний час). +8. Запити до `v3` гаманців з високим навантаженням за замовчуванням мають термін дії, що дорівнює 60 секундам. Після закінчення цього часу необроблені запити можуть бути безпечно відправлені в мережу (див. кроки 3-6). + +### Отримати ідентифікатор транзакції + +Може бути незрозуміло, що для отримання додаткової інформації про транзакцію користувач повинен просканувати блокчейн за допомогою функції [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get). +Неможливо отримати ідентифікатор транзакції одразу після відправлення повідомлення, оскільки транзакція повинна бути підтверджена мережею блокчейн. +Щоб зрозуміти необхідний конвеєр, уважно прочитайте [Send payments](https://docs.ton.org/develop/dapps/asset-processing/#send-payments), особливо 7-й пункт. + +## Підхід на основі рахунків-фактур + +Щоб приймати платежі на основі прикріплених коментарів, сервіс повинен + +1. Розгорніть контракт "гаманця". +2. Згенеруйте унікальний `invoice` для кожного користувача. Рядкового представлення uuid32 буде достатньо. +3. Користувачам слід проінструктувати, щоб вони надсилали Toncoin на контракт "гаманця" сервісу з прикріпленим "рахунком-фактурою" в якості коментаря. +4. Сервіс повинен регулярно опитувати метод [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get) для контракту `гаманця`. +5. Для нових транзакцій вхідне повідомлення має бути витягнуто, `коментар` перевірено за базою даних, а **значення вхідного повідомлення** занесено до облікового запису користувача. + +Щоб обчислити **значення вхідного повідомлення**, яке повідомлення приносить контракту, потрібно розібрати транзакцію. Це відбувається, коли повідомлення потрапляє в контракт. Транзакцію можна отримати за допомогою [getTransactions](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L268). Для вхідної транзакції гаманця правильні дані складаються з одного вхідного повідомлення і нуля вихідних повідомлень. В іншому випадку, або на гаманець надсилається зовнішнє повідомлення, і тоді власник витрачає Toncoin, або гаманець не розгортається і вхідна транзакція повертається назад. + +Так чи інакше, в загальному випадку суму, яку приносить повідомлення в контракт, можна розрахувати як вартість вхідного повідомлення мінус сума вартостей вихідних повідомлень мінус комісія: `value_{in_msg} - SUM(value_{out_msg}) - fee`. Технічно представлення транзакції містить три різних поля з `fee` в назві: `fee`, `storage_fee` та `other_fee`, тобто загальну комісію, частину комісії, пов'язану з витратами на зберігання, та частину комісії, пов'язану з обробкою транзакції. Використовувати слід тільки першу з них. + +### Інвойси з TON Connect + +Найкраще підходить для dApps, яким потрібно підписувати кілька платежів/транзакцій протягом сесії або підтримувати з'єднання з гаманцем протягом певного часу. + +- ✅ Є постійний канал зв'язку з гаманцем, інформація про адресу користувача + +- ✅ Користувачам потрібно відсканувати QR-код лише один раз + +- ✅ Можна дізнатися, чи підтвердив користувач транзакцію в гаманці, відстежити транзакцію за поверненою BOC + +- ✅ Готові SDK та набори інтерфейсів доступні для різних платформ + +- ❌ Якщо потрібно відправити лише один платіж, користувачеві потрібно виконати дві дії: підключити гаманець і підтвердити транзакцію + +- ❌ Інтеграція складніша, ніж посилання ton:// + +```mdx-code-block + +``` + +### Інвойси з посиланням ton:// + +:::warning +Посилання Ton застаріле, не використовуйте його +::: + +Якщо вам потрібна легка інтеграція для простого потоку користувачів, підійде посилання ton://. +Найкраще підходить для одноразових платежів та інвойсів. + +```bash +ton://transfer/? + [nft=&] + [fee-amount=&] + [forward-amount=] +``` + +- ✅ Легка інтеграція + +- ✅ Не потрібно підключати гаманець + +- ❌ Користувачі повинні сканувати новий QR-код для кожного платежу + +- ❌ Неможливо відстежити, чи підписав користувач транзакцію чи ні + +- ❌ Немає інформації про адресу користувача + +- ❌ Обхідні шляхи потрібні на платформах, де такі посилання не можна натискати (наприклад, повідомлення від ботів для десктопних клієнтів Telegram) + +[Дізнайтеся більше про тонни посилань тут] (https://github.com/tonkeeper/wallet-api#payment-urls) + +## Дослідники + +Дослідник блокчейну - https://tonscan.org. + +Щоб згенерувати посилання на транзакцію в провіднику, сервіс має отримати lt (логічний час), хеш транзакції та адресу акаунта (адресу акаунта, для якого lt і txhash було отримано за допомогою методу [getTransactions](https://toncenter.com/api/v2/#/transactions/get_transactions_getTransactions_get)). https://tonscan.org і https://explorer.toncoin.org/ можуть показати сторінку для цього tx у наступному форматі: + +`https://tonviewer.com/transaction/{txhash as base64url}` + +`https://tonscan.org/tx/{lt as int}:{txhash as base64url}:{account address}` + +`https://explorer.toncoin.org/transaction?account={account address}<={lt as int}&hash={txhash as base64url}`. + +## Найкращі практики + +### Створення гаманця + + + + +- **toncenter:** + - [Створення гаманця + отримання адреси гаманця](https://github.com/toncenter/examples/blob/main/common.js) + +- **тон-спільнота/тон:**. + - [Створення гаманця + отримання балансу](https://github.com/ton-community/ton#usage) + + + + + +- **xssnick/tonutils-go:** + - [Створення гаманця + отримання балансу](https://github.com/xssnick/tonutils-go?tab=readme-ov-file#wallet) + + + + + +- **psylopunk/pythonlib:** + - [Створення гаманця + отримання адреси гаманця](https://github.com/psylopunk/pytonlib/blob/main/examples/generate_wallet.py) +- **юнгвин/пітонік:** + +```py +import asyncio + +from pytoniq.contract.wallets.wallet import WalletV4R2 +from pytoniq.liteclient.balancer import LiteBalancer + + +async def main(): + provider = LiteBalancer.from_mainnet_config(2) + await provider.start_up() + + mnemonics, wallet = await WalletV4R2.create(provider) + print(f"{wallet.address=} and {mnemonics=}") + + await provider.close_all() + + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + + +### Депозити в тонкоїнах (отримати тонкоїни) + + + + +- **toncenter:** + - [Обробка депозиту Toncoins](https://github.com/toncenter/examples/blob/main/deposits.js) + - [Процес поповнення мультигаманців Toncoins](https://github.com/toncenter/examples/blob/main/deposits-multi-wallets.js) + + + + + +- **xssnick/tonutils-go:** + +
+Перевірка депозитів + +```go +package main + +import ( + "context" + "encoding/base64" + "log" + + "github.com/xssnick/tonutils-go/address" + "github.com/xssnick/tonutils-go/liteclient" + "github.com/xssnick/tonutils-go/ton" +) + +const ( + num = 10 +) + +func main() { + client := liteclient.NewConnectionPool() + err := client.AddConnectionsFromConfigUrl(context.Background(), "https://ton.org/global.config.json") + if err != nil { + panic(err) + } + + api := ton.NewAPIClient(client, ton.ProofCheckPolicyFast).WithRetry() + + accountAddr := address.MustParseAddr("0QA__NJI1SLHyIaG7lQ6OFpAe9kp85fwPr66YwZwFc0p5wIu") + + // we need fresh block info to run get methods + b, err := api.CurrentMasterchainInfo(context.Background()) + if err != nil { + log.Fatal(err) + } + + // we use WaitForBlock to make sure block is ready, + // it is optional but escapes us from liteserver block not ready errors + res, err := api.WaitForBlock(b.SeqNo).GetAccount(context.Background(), b, accountAddr) + if err != nil { + log.Fatal(err) + } + + lastTransactionId := res.LastTxHash + lastTransactionLT := res.LastTxLT + + headSeen := false + + for { + trxs, err := api.ListTransactions(context.Background(), accountAddr, num, lastTransactionLT, lastTransactionId) + if err != nil { + log.Fatal(err) + } + + for i, tx := range trxs { + // should include only first time lastTransactionLT + if !headSeen { + headSeen = true + } else if i == 0 { + continue + } + + if tx.IO.In == nil || tx.IO.In.Msg.SenderAddr().IsAddrNone() { + // external message should be omitted + continue + } + + if tx.IO.Out != nil { + // no outgoing messages - this is incoming Toncoins + continue + } + + // process trx + log.Printf("found in transaction hash %s", base64.StdEncoding.EncodeToString(tx.Hash)) + } + + if len(trxs) == 0 || (headSeen && len(trxs) == 1) { + break + } + + lastTransactionId = trxs[0].Hash + lastTransactionLT = trxs[0].LT + } +} +``` + +
+
+ + + +- **юнгвин/пітонік:** + +Перевірка депозитів + +```python +import asyncio + +from pytoniq_core import Transaction + +from pytoniq import LiteClient, Address + +MY_ADDRESS = Address("kf8zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM_BP") + + +async def main(): + client = LiteClient.from_mainnet_config(ls_i=0, trust_level=2) + + await client.connect() + + last_block = await client.get_trusted_last_mc_block() + + _account, shard_account = await client.raw_get_account_state(MY_ADDRESS, last_block) + assert shard_account + + last_trans_lt, last_trans_hash = ( + shard_account.last_trans_lt, + shard_account.last_trans_hash, + ) + + while True: + print(f"Waiting for{last_block=}") + + transactions = await client.get_transactions( + MY_ADDRESS, 1024, last_trans_lt, last_trans_hash + ) + toncoin_deposits = [tx for tx in transactions if filter_toncoin_deposit(tx)] + print(f"Got {len(transactions)=} with {len(toncoin_deposits)=}") + + for deposit_tx in toncoin_deposits: + # Process toncoin deposit transaction + print(deposit_tx.cell.hash.hex()) + + last_trans_lt = transactions[0].lt + last_trans_hash = transactions[0].cell.hash + + +def filter_toncoin_deposit(tx: Transaction): + if tx.out_msgs: + return False + + if tx.in_msg: + return False + + return True + + +if __name__ == "__main__": + asyncio.run(main()) +``` + + +
+ +### Виведення токенів (надсилання токенів) + + + + +- **toncenter:** + - [Виводьте тонкоїни з гаманця партіями](https://github.com/toncenter/examples/blob/main/withdrawals-highload-batch.js) + - [Вивести тонкоїни з гаманця](https://github.com/toncenter/examples/blob/main/withdrawals-highload.js) + +- **тон-спільнота/тон:**. + - [Вивести тонкоїни з гаманця](https://github.com/ton-community/ton#usage) + + + + + +- **xssnick/tonutils-go:** + - [Вивести тонкоїни з гаманця](https://github.com/xssnick/tonutils-go?tab=readme-ov-file#wallet) + + + + + +- **psylopunk/pythonlib:** + - [Вивести тонкоїни з гаманця](https://github.com/psylopunk/pytonlib/blob/main/examples/transactions.py) + +- **юнгвин/пітонік:** + +```python +import asyncio + +from pytoniq_core import Address +from pytoniq.contract.wallets.wallet import WalletV4R2 +from pytoniq.liteclient.balancer import LiteBalancer + + +MY_MNEMONICS = "one two tree ..." +DESTINATION_WALLET = Address("Destination wallet address") + + +async def main(): + provider = LiteBalancer.from_mainnet_config() + await provider.start_up() + + wallet = await WalletV4R2.from_mnemonic(provider, MY_MNEMONICS) + + await wallet.transfer(DESTINATION_WALLET, 5) + + await provider.close_all() + + +if __name__ == "__main__": + asyncio.run(main()) +``` + + + + + +### Отримуйте транзакції за контрактом + + + + +- **тон-спільнота/тон:**. + - [Клієнт з методом getTransaction](https://github.com/ton-community/ton/blob/master/src/client/TonClient.ts) + + + + + +- **xssnick/tonutils-go:** + - [Отримати транзакції](https://github.com/xssnick/tonutils-go?tab=readme-ov-file#account-info-and-transactions) + + + + + +- **psylopunk/pythonlib:** + - [Отримати транзакції](https://github.com/psylopunk/pytonlib/blob/main/examples/transactions.py) +- **юнгвин/пітонік:** + - [Отримати транзакції](https://github.com/yungwine/pytoniq/blob/master/examples/transactions.py) + + + + + +## SDK + +Список SDK для різних мов (JS, Python, Golang, C#, Rust і т.д.) можна знайти [тут](/develop/dapps/apis/sdk). diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md b/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md new file mode 100644 index 0000000000..4a1dbc400d --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md @@ -0,0 +1,1205 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import Button from '@site/src/components/utton'; + +# Переробка TON Jetton + +:::info +Для чіткого розуміння читач повинен бути знайомий з основними принципами обробки активів, описаними в [розділі обробки платежів] (/develop/dapps/asset-processing/) нашої документації. +::: + +Джеттони - це токени в блокчейні TON - їх можна розглядати аналогічно токенам ERC-20 в Ethereum. + +У цьому аналізі ми заглиблюємося у формальні стандарти, що детально описують поведінку джеттонів (https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md) та їхні метадані (https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md). +Менш формальний огляд архітектури джеттонів, зосереджений на шардингу, можна знайти у нашому блозі +[анатомія джеттонів](https://blog.ton.org/how-to-shard-your-ton-smart-contract-and-why-studying-the-anatomy-of-tons-jettons). + +Також слід пам'ятати, що існує два підходи до роботи з джеттон-виводами: + +- [Memo Deposits] (https://github.com/toncenter/examples/blob/main/deposits-jettons.js) - дозволяє вести один депозитний гаманець, а користувачі додають записку, щоб бути ідентифікованими вашою системою. Це означає, що вам не потрібно сканувати весь блокчейн, але це трохи менш зручно для користувачів. +- [Депозити без авізо] (https://github.com/gobicycle/bicycle) - Це рішення також існує, але його складніше інтегрувати. Однак ми можемо допомогти вам з цим, якщо ви віддаєте перевагу цьому шляху. Будь ласка, повідомте нас перед тим, як прийняти рішення про застосування цього підходу. + +## Jetton Architecture + +Стандартизовані токени на TON реалізуються за допомогою набору смарт-контрактів, в тому числі: + +- [Jetton master](https://github.com/ton-blockchain/token-contract/blob/main/ft/jetton-minter.fc) смарт-контракт +- [Гаманець Jetton](https://github.com/ton-blockchain/token-contract/blob/main/ft/jetton-wallet.fc) смарт-контракти + +

+
+ contracts scheme +
+

+ +## Головний смарт-контракт Jetton + +Головний смарт-контракт джеттона зберігає загальну інформацію про джеттон (включаючи загальну пропозицію, посилання на метадані або самі метадані). + +:::warning Остерігайтеся шахрайства з Jetton + +Джеттони з символом `==`TON\`\` або ті, що містять системні повідомлення, такі як: +`ERROR`, `SYSTEM` та інші. Переконайтеся, що джеттони відображаються у вашому інтерфейсі таким чином, щоб їх не можна було +змішати з TON-передачами, системними повідомленнями тощо. Іноді навіть `символ`, `ім'я` та `зображення` +створюються майже ідентичними до оригіналу з надією ввести користувачів в оману. + +Щоб виключити можливість шахрайства для користувачів TON, будь ласка, шукайте **оригінальну адресу джеттона** (основний договір на джеттон) для конкретних типів джеттонів або **перейдіть на офіційний канал проекту в соціальних мережах** чи веб-сайт, щоб знайти **правильну інформацію**. Перевірте активи, щоб виключити можливість шахрайства за допомогою [Tonkeeper ton-assets list] (https://github.com/tonkeeper/ton-assets). +::: + +### Отримання даних Jetton + +Для отримання більш конкретних даних Jetton використовуйте метод *get* контракту `get_jetton_data()`. + +Цей метод повертає наступні дані: + +| Ім'я | Тип | Опис | +| ------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `total_supply` | `int` | загальна кількість випущених джеттонів, виміряна в неподільних одиницях. | +| "монетний двір". | `int` | деталізує, чи можна карбувати нові джеттони чи ні. Це значення дорівнює -1 (можна карбувати) або 0 (не можна карбувати). | +| `адреса_адміністратора` | "шматочок | | +| \`jetton_content | "Cell | дані відповідно до [TEP-64](https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md), див. [сторінку розбору метаданих jetton](/develop/dapps/asset-processing/metadata) для отримання додаткової інформації. | +| `jetton_wallet_code` | "Cell | | + +Ви можете викликати його за допомогою [Toncenter API](https://toncenter.com/api/v3/#/default/get_jetton_masters_api_v3_jetton_masters_get) або одного з [SDK](https://docs.ton.org/develop/dapps/apis/sdk). + + + + +> Запустіть метод `jetton/masters` з [Toncenter API](https://toncenter.com/api/v3/#/default/get_jetton_masters_api_v3_jetton_masters_get) + + + + +```js +import TonWeb from "tonweb"; +const tonweb = new TonWeb(); +const jettonMinter = new TonWeb.token.jetton.JettonMinter(tonweb.provider, {address: ""}); +const data = await jettonMinter.getJettonData(); +console.log('Total supply:', data.totalSupply.toString()); +console.log('URI to off-chain metadata:', data.jettonContentUri); +``` + + + + +### Jetton minter + +Як згадувалося раніше, джеттони можуть бути як "карбованими", так і "некарбованими". + +Якщо вони не карбуються, логіка стає простою - немає можливості карбувати додаткові токени. Для того, щоб вперше покарбувати джеттони, зверніться до сторінки [Покарбуйте свій перший джеттон](/develop/dapps/tutorials/jetton-minter). + +Якщо джеттони можна карбувати, в [контракті з майнером] (https://github.com/ton-blockchain/minter-contract/blob/main/contracts/jetton-minter.fc) є спеціальна функція для карбування додаткових джеттонів. Цю функцію можна викликати, відправивши `внутрішнє повідомлення` з вказаним опкодом з адреси адміністратора. + +Якщо адміністратор джеттона хоче обмежити створення джеттонів, є три способи зробити це: + +1. Якщо ви не можете або не хочете оновлювати код контракту, адміністратор повинен передати право власності від поточного адміністратора на нульову адресу. Це призведе до того, що контракт залишиться без дійсного адміністратора, і ніхто не зможе карбувати джеттони. Однак, це також унеможливить будь-які зміни в метаданих джеттона. +2. Якщо у вас є доступ до вихідного коду і ви можете його змінити, ви можете створити в контракті метод, який встановлює прапорець для переривання будь-якого процесу карбування після його виклику, і додати оператор для перевірки цього прапорця в функцію карбування. +3. Якщо ви можете оновити код контракту, ви можете додати обмеження, оновивши код вже розгорнутого контракту. + +## Смарт-контракт гаманця Jetton + +Контракти `гаманця Джеттона` використовуються для **відправлення**, **отримання** та **спалювання** джеттонів. Кожен *контракт гаманця джеттона* зберігає інформацію про баланс гаманця для конкретних користувачів. +В окремих випадках джеттон-гаманці використовуються для окремих власників джеттонів для кожного типу джеттонів. + +"Гаманці джеттонів" **не слід плутати з гаманцями**, призначеними для взаємодії з блокчейном і зберігання +тільки активу Toncoin (наприклад, гаманці v3R2, гаманці з високим навантаженням та інші), +які відповідають за підтримку і управління **тільки певним типом джеттона**. + +### Розгортання гаманця Jetton + +При `передачі джеттонів` між гаманцями транзакції (повідомлення) вимагають певної суми TON +в якості оплати мережевих **платежів** і виконання дій відповідно до коду контракту гаманця Jetton. +Це означає, що **одержувачу не потрібно розгортати джеттон-гаманець перед отриманням джеттонів**. +Гаманець одержувача буде розгорнутий автоматично, якщо відправник має на гаманці достатню кількість TON +для сплати необхідних зборів за газ. + +### Отримання адрес гаманців Jetton для певного користувача + +Щоб отримати `адресу `гаманця Jetton`за допомогою`адреси власника`(адреси гаманця TON), +в`магістерському контракті Jetton`передбачено метод get`get_wallet_address(slice_address_власника)\`. + + + + +> Запустіть `get_wallet_address(slice owner_address)` за допомогою методу `/runGetMethod` з [Toncenter API](https://toncenter.com/api/v3/#/default/run_get_method_api_v3_runGetMethod_post). + + + + +```js +import TonWeb from "tonweb"; +const tonweb = new TonWeb(); +const jettonMinter = new TonWeb.token.jetton.JettonMinter(tonweb.provider, {address: ""}); +const address = await jettonMinter.getJettonWalletAddress(new TonWeb.utils.Address("")); +// It is important to always check that wallet indeed is attributed to desired Jetton Master: +const jettonWallet = new TonWeb.token.jetton.JettonWallet(tonweb.provider, { + address: jettonWalletAddress +}); +const jettonData = await jettonWallet.getData(); +if (jettonData.jettonMinterAddress.toString(false) !== new TonWeb.utils.Address(info.address).toString(false)) { + throw new Error('jetton minter address from jetton wallet doesnt match config'); +} + +console.log('Jetton wallet address:', address.toString(true, true, true)); +``` + + + + +### Отримання даних для конкретного гаманця Jetton + +Щоб отримати баланс рахунку гаманця, ідентифікаційну інформацію про власника та іншу інформацію, пов'язану з конкретним контрактом джеттон-гаманця, використовуйте метод get `get_wallet_data()` в контракті джеттон-гаманця. + +Цей метод повертає наступні дані: + +| Ім'я | Тип | +| -------------------- | -------- | +| "Баланс | int | +| "власник | шматочок | +| "Джеттон | шматочок | +| `jetton_wallet_code` | клітина | + + + + +> Використовуйте метод `/jetton/wallets` get з [Toncenter API](https://toncenter.com/api/v3/#/default/get_jetton_wallets_api_v3_jetton_wallets_get), щоб отримати раніше декодовані дані jetton-гаманців. + + + + + +```js +import TonWeb from "tonweb"; +const tonweb = new TonWeb(); +const walletAddress = "EQBYc3DSi36qur7-DLDYd-AmRRb4-zk6VkzX0etv5Pa-Bq4Y"; +const jettonWallet = new TonWeb.token.jetton.JettonWallet(tonweb.provider,{address: walletAddress}); +const data = await jettonWallet.getData(); +console.log('Jetton balance:', data.balance.toString()); +console.log('Jetton owner address:', data.ownerAddress.toString(true, true, true)); +// It is important to always check that Jetton Master indeed recognize wallet +const jettonMinter = new TonWeb.token.jetton.JettonMinter(tonweb.provider, {address: data.jettonMinterAddress.toString(false)}); +const expectedJettonWalletAddress = await jettonMinter.getJettonWalletAddress(data.ownerAddress.toString(false)); +if (expectedJettonWalletAddress.toString(false) !== new TonWeb.utils.Address(walletAddress).toString(false)) { + throw new Error('jetton minter does not recognize the wallet'); +} + +console.log('Jetton master address:', data.jettonMinterAddress.toString(true, true, true)); +``` + + + + +## Огляд комунікації гаманців Jetton + +Зв'язок між гаманцями Jetton і TON відбувається в наступній послідовності: + +![](/img/docs/asset-processing/jetton_transfer.svg) + +#### Повідомлення 0 + +`Відправник -> джеттон-гаманець відправника`. Повідомлення *Transfer* містить наступні дані: + +| Ім'я | Тип | Опис | +| ----------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `query_id` | uint64 | Дозволяє програмам зв'язувати між собою три типи повідомлень `Передача`, `Повідомлення про передачу` і `Перевищення`. Для коректного виконання цього процесу рекомендується **завжди використовувати унікальний ідентифікатор запиту**. | +| "сума | монети | Загальна сума "тонни монет", яка буде надіслана у повідомленні. | +| "місце призначення | адреса | Адреса нового власника джеттонів | +| `відповідь_призначення` | адреса | Адреса гаманця для повернення монет з повідомленням про надлишок. | +| `custom_payload` | можливо, в камері. | Розмір завжди >= 1 біт. Користувацькі дані (які використовуються джеттон-гаманцем відправника або одержувача для внутрішньої логіки). | +| `forward_ton_amount` | монети | Повинно бути > 0, якщо ви хочете надіслати `повідомлення про передачу` з `переадресованим корисним навантаженням`. Це \*\*частина значення `mount` і **повинна бути меншою за `mount`**. | +| `forward_payload` | можливо, в камері. | Розмір завжди >= 1 біт. Якщо перші 32 біти = 0x0, то це просте повідомлення. | + +#### Послання 2''. + +`Jetton гаманець одержувача -> одержувач`. Повідомлення про переказ. **Відправляється тільки якщо** `сума_переказу_тонн` **не нульова**. Містить наступні дані: + +| Ім'я | Тип | +| ----------------- | ------- | +| `query_id` | uint64 | +| "сума | монети | +| "Відправник | адреса | +| `forward_payload` | клітина | + +Тут адреса відправника - це адреса "джеттон-гаманця" Аліси. + +#### Послання 2''. + +`Jetton гаманець одержувача -> Відправник`. Надлишкове тіло повідомлення. **Відправляється лише у випадку, якщо після сплати комісій залишилися монети тонни**. Містить наступні дані: + +| Ім'я | Тип | +| ---------- | ------ | +| `query_id` | uint64 | + +:::tip Джеттони стандартні +Детальний опис полів контрактів джеттон-гаманця можна знайти в [TEP-74](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md) `Jetton standard` опис інтерфейсу. +::: + +## Надсилайте джеттони з коментарями + +Для цього переказу потрібно кілька тонних монет для сплати **комісії** і, за бажанням, **повідомлення про переказ** (поставте галочку в полі "Сума переказу"). + +Щоб надіслати **коментар**, вам потрібно налаштувати `переднє корисне навантаження`. Встановіть **перші 32 біти в 0x0** і додайте **ваш текст**. + +Внутрішнє повідомлення `forward payload` надсилається у внутрішньому повідомленні `transfer notification`. Воно буде згенероване тільки якщо `сума переказу` > 0. + +Нарешті, щоб отримати повідомлення `Excess`, ви повинні налаштувати `призначення відповіді`. + +:::tip +Перевірте [кращі практики](/develop/dapps/asset-processing/jettons#best-practices) для прикладу *"надсилати jettons з коментарями"*. +::: + +## Позачергова обробка Jetton + +:::info Підтвердження транзакції +Транзакції TON є незворотними після одного підтвердження. Для кращого користувацького досвіду рекомендується уникати очікування додаткових блоків після завершення транзакцій в блокчейні TON. Детальніше читайте в [Catchain.pdf] (https://docs.ton.org/catchain.pdf#page=3). +::: + +Існує два способи прийняття джеттонів: + +- в рамках **централізованого гарячого гаманця**. +- використання гаманця з **окремою адресою** для **кожного окремого користувача**. + +З міркувань безпеки бажано мати **окремі гарячі гаманці** для **окремих джеттонів** (багато гаманців для кожного типу активів). + +При обробці коштів також рекомендується передбачити "холодний гаманець" для зберігання надлишкових коштів, які не беруть участі в автоматичних процесах поповнення та зняття коштів. + +### Додавання нових джеттонів для обробки активів та первинної верифікації + +1. Знайдіть правильну [адресу смарт-контракту] (/develop/dapps/asset-processing/jettons#jetton-master-smart-contract). +2. Отримати [метадані](/develop/dapps/asset-processing/jettons#retrieving-jetton-data). +3. Перевірте, чи немає [шахрайства] (/develop/dapps/asset-processing/jettons#jetton-master-smart-contract). + +### Ідентифікація невідомого Jetton при отриманні повідомлення про переказ + +Якщо на ваш гаманець надійшло повідомлення про переказ на невідомий Jetton, це означає, що ваш гаманець +було створено для зберігання конкретного Jetton. + +Адреса відправника внутрішнього повідомлення, що містить тіло `Transfer notification` - це адреса нового гаманця Jetton. +Її не слід плутати з полем "відправник" у тілі "Повідомлення про переказ" (/develop/dapps/asset-processing/jettons#jetton-wallets-communication-oview). + +1. Отримайте головну адресу Jetton для нового гаманця Jetton за допомогою [отримання даних гаманця](/develop/dapps/asset-processing/jettons#retrieving-data-for-a-specific-jetton-wallet). +2. Отримайте адресу гаманця Jetton для вашої адреси гаманця (як власника) за допомогою генерального договору Jetton: [Як отримати адресу гаманця Jetton для даного користувача] (#retrieving-jetton-wallet-addresses-for-a-given-user) +3. Порівняйте адресу, повернуту головним контрактом, і фактичну адресу токена гаманця. + Якщо вони збігаються, це ідеально. Якщо ні, то, швидше за все, ви отримали шахрайський токен, який є підробкою. +4. Отримати метадані Jetton: [Як отримати метадані Jetton](#retrieving-jetton-data). +5. Перевірте поля "символ" та "ім'я" на наявність ознак шахрайства. За необхідності попередьте користувача. [Додавання нового джеттона для обробки та початкової перевірки] (#adding-new-jettons-for-asset-processing-and-initial-verification). + +### Прийом джеттонів від користувачів через централізований гаманець + +:::info +Для того, щоб запобігти вузькому місцю у вхідних транзакціях на один гаманець, пропонується приймати депозити на декілька гаманців і розширювати кількість цих гаманців за потреби. +::: + +У цьому сценарії платіжний сервіс створює унікальний ідентифікатор мемо для кожного відправника, який розкриває +адресу централізованого гаманця та суми, що надсилаються. Відправник надсилає токени +на вказану централізовану адресу з обов'язковим мемо в коментарі. + +**Плюси цього методу:** цей метод дуже простий, оскільки немає додаткових комісій при прийомі токенів, і вони отримуються безпосередньо в гарячому гаманці. + +**Недоліки цього методу:** цей метод вимагає, щоб усі користувачі додавали коментар до переказу, що може призвести до більшої кількості помилок при переказі (забуті примітки, неправильні примітки тощо), а отже, до більшого навантаження на працівників служби підтримки. + +Приклади з Tonweb: + +1. [Прийом депозитів Jetton на індивідуальний гаманець HOT з коментарями (пам'ятка)] (https://github.com/toncenter/examples/blob/main/deposits-jettons.js) +2. [Приклад виведення коштів з Jettons](https://github.com/toncenter/examples/blob/main/withdrawals-jettons.js) + +#### Підготовка + +1. [Підготуйте список прийнятих джеттонів](/develop/dapps/asset-processing/jettons#adding-new-jettons-for-asset-processing-and-initial-verification) (основні адреси джеттонів). +2. Розгорніть гарячий гаманець (використовуючи v3R2, якщо не очікується виведення коштів через Jetton; highload v3 - якщо очікується виведення коштів через Jetton). [Розгортання гаманця](/develop/dapps/asset-processing/#wallet-deployment). +3. Виконайте тестовий переказ Jetton, використовуючи адресу гарячого гаманця для ініціалізації гаманця. + +#### Обробка вхідних джеттонів + +1. Завантажте список прийнятих джеттонів. +2. [Отримати адресу гаманця Jetton] (#retrieving-jetton-wallet-addresses-for-a-given-user) для вашого розгорнутого гарячого гаманця. +3. Отримайте головну адресу Jetton для кожного гаманця Jetton за допомогою [отримання даних гаманця](/develop/dapps/asset-processing/jettons#retrieving-data-for-a-specific-jetton-wallet). +4. Порівняйте адреси генеральних контрактів Jetton з кроку 1 та кроку 3 (безпосередньо вище). + Якщо адреси не збігаються, необхідно повідомити про помилку перевірки адреси Jetton. +5. Отримайте список останніх необроблених транзакцій за допомогою облікового запису гарячого гаманця та + ітераційно перегляньте його (сортуючи кожну транзакцію по черзі). Див: [Перевірка транзакцій за контрактом] (https://docs.ton.org/develop/dapps/asset-processing/#checking-contracts-transactions). +6. Перевірити вхідне повідомлення (in_msg) на наявність транзакцій і отримати адресу джерела з вхідного повідомлення. [Приклад Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-jettons-single-wallet.js#L84) +7. Якщо адреса джерела збігається з адресою в гаманці Jetton, то необхідно продовжити обробку транзакції. + Якщо ні, то пропустіть обробку транзакції і перевірте наступну транзакцію. +8. Переконайтеся, що тіло повідомлення не порожнє і що перші 32 біти повідомлення збігаються з оперативним кодом `transfer notification` `0x7362d09c`. + [Приклад Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-jettons-single-wallet.js#L91) + Якщо тіло повідомлення порожнє або операційний код невірний - пропустіть транзакцію. +9. Прочитайте інші дані тіла повідомлення, зокрема `query_id`, `amount`, `sender`, `forward_payload`. + [Макети повідомлень Jetton контрактів](#jetton-contract-message-layouts), [Приклад Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-jettons-single-wallet.js#L105) +10. Спробуйте отримати текстові коментарі з даних `forward_payload`. Перші 32 біти мають збігатися з + опкодом текстового коментаря `0x00000000`, а решта - з текстом у кодуванні UTF-8. + [Приклад Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-jettons-single-wallet.js#L110) +11. Якщо дані `forward_payload` порожні або код операції невірний - пропустити транзакцію. +12. Порівняйте отриманий коментар зі збереженими нотатками. Якщо вони збігаються (ідентифікація користувача завжди можлива) - відправляйте переказ. +13. Почніть з кроку 5 і повторюйте процес, поки не пройдете весь список транзакцій. + +### Прийом джеттонів з депозитних адрес користувачів + +Для прийому джеттонів з депозитних адрес користувачів необхідно, щоб платіжний сервіс створив +власну індивідуальну адресу (депозит) для кожного учасника, який надсилає кошти. Надання послуги в цьому випадку передбачає +виконання декількох паралельних процесів, включаючи створення нових депозитів, сканування блоків на предмет транзакцій, +виведення коштів з депозитів на гарячий гаманець і так далі. + +Оскільки гарячий гаманець може використовувати один гаманець Jetton для кожного типу Jetton, необхідно створити декілька +гаманців для ініціювання депозитів. Для того, щоб створити велику кількість гаманців, але при цьому керувати ними за допомогою +однієї ключової фрази (або приватного ключа), необхідно при створенні гаманця вказувати різний "subwallet_id". +На TON функціонал, необхідний для створення субгаманця, підтримується гаманцями версії v3 і вище. + +#### Створення субгаманця в Tonweb + +```js +const WalletClass = tonweb.wallet.all['v3R2']; +const wallet = new WalletClass(tonweb.provider, { + publicKey: keyPair.publicKey, + wc: 0, + walletId: , +}); +``` + +#### Підготовка + +1. [Підготувати список прийнятих джеттонів] (#додавання нових джеттонів для обробки активів та початкової перевірки). +2. Розгорніть гарячий гаманець (використовуючи v3R2, якщо не очікується виведення коштів через Jetton; highload v3 - якщо очікується виведення коштів через Jetton). [Розгортання гаманця](/develop/dapps/asset-processing/#wallet-deployment). + +#### Створення депозитів + +1. Прийняти запит на створення нового депозиту для користувача. +2. Згенеруйте адресу нового субгаманця (v3R2) на основі seed'а гарячого гаманця. [Створення субгаманця в Tonweb] (#creating-a-subwallet-in-tonweb) +3. Адреса отримання може бути надана користувачеві як адреса, що використовується для депозитів Jetton (це адреса + власника депозитного гаманця Jetton). Ініціалізація гаманця не потрібна, це можна зробити + при знятті Джеттонів з депозиту. +4. Для цієї адреси необхідно обчислити адресу гаманця Jetton через майстер-контракт Jetton. + [Як отримати адресу гаманця Jetton для заданого користувача] (#retrieving-jetton-wallet-addresses-for-a-given-user). +5. Додайте адресу гаманця Jetton до пулу адрес для моніторингу транзакцій і збережіть адресу субгаманця. + +#### Обробка транзакцій + +:::info Підтвердження транзакції +Транзакції TON є незворотними після одного підтвердження. Для кращого користувацького досвіду рекомендується уникати очікування додаткових блоків після завершення транзакцій в блокчейні TON. Детальніше читайте в [Catchain.pdf] (https://docs.ton.org/catchain.pdf#page=3). +::: + +Не завжди можна визначити точну кількість отриманих джеттонів з повідомлення, оскільки гаманці Jetton +можуть не надсилати повідомлення про "повідомлення про переказ", "надлишки" та "внутрішній переказ". Вони не стандартизовані. Це означає, +що немає гарантії, що повідомлення про внутрішній переказ можна буде розшифрувати. + +Тому для визначення суми, що надійшла на гаманець, необхідно запитувати баланси за допомогою методу get. +Для отримання ключових даних при запиті балансів використовуються блоки відповідно до стану рахунку для конкретного блоку в ланцюжку. +[Підготовка до прийому блоків за допомогою Tonweb] (https://github.com/toncenter/tonweb/blob/master/src/test-block-subscribe.js). + +Цей процес відбувається наступним чином: + +1. Підготовка до приймання блоків (підготовка системи до приймання нових блоків). +2. Отримати новий блок і зберегти ідентифікатор попереднього блоку. +3. Отримуйте транзакції з блоків. +4. Фільтр транзакцій, що використовуються тільки з адресами з пулу депозитних гаманців Jetton. +5. Декодуйте повідомлення за допомогою тіла `transfer notification`, щоб отримати детальнішу інформацію, зокрема адресу + відправника, кількість джеттонів та коментар. (Дивіться: [Обробка вхідних джеттонів](#processing-incoming-jettons)) +6. Якщо на рахунку + є хоча б одна транзакція з нерозшифрованими вихідними повідомленнями (тіло повідомлення не містить операційних кодів для + `transfer notification` та операційних кодів для `excesses`) або без вихідних повідомлень, то баланс Jetton повинен бути запитаний методом get для поточного блоку, а для розрахунку різниці балансів використовується попередній блок + . Тепер загальна зміна балансу на рахунку відображається за допомогою + транзакцій, що проводяться в межах блоку. +7. Як ідентифікатор для неідентифікованої передачі джеттонів (без "повідомлення про передачу") можна використовувати дані транзакції + , якщо є одна така транзакція, або дані блоку (якщо в блоці присутні декілька). +8. Тепер необхідно перевірити, чи правильний баланс депозиту. Якщо баланс депозиту достатній для ініціювання переказу між гарячим гаманцем та існуючим гаманцем Jetton, необхідно зняти джеттони, щоб переконатися, що баланс гаманця зменшився. +9. Почніть з кроку 2 і повторіть весь процес. + +#### Зняття коштів з депозитів + +Не слід здійснювати перекази з депозиту на гарячий гаманець при кожному поповненні депозиту +, оскільки за операцію переказу стягується комісія в ТОНах (сплачується в тарифах на газ у мережі). +Важливо визначити певну мінімальну суму джеттонів, яка необхідна для того, щоб переказ на +був виправданим (і, відповідно, поповнення депозиту). + +За замовчуванням власники депозитних гаманців Jetton не ініціалізуються. Це пов'язано з тим, що не існує заздалегідь визначеної +вимоги сплачувати комісію за зберігання. Депозитні гаманці Jetton можуть бути розгорнуті при відправці повідомлень з тілом +`transfer`, яке потім може бути негайно знищене. Для цього інженер повинен використовувати спеціальний +механізм відправки повідомлень: [128 + 32](/develop/smart-contracts/messages#message-modes). + +1. Отримати список депозитів, позначених для виведення на гарячий гаманець +2. Отримати збережені адреси власників для кожного депозиту +3. Потім повідомлення надсилаються на адресу кожного власника (шляхом об'єднання декількох таких повідомлень в пакет) з високонавантаженого гаманця + з прикріпленою сумою TON Jetton. Вона визначається шляхом додавання комісій за ініціалізацію гаманця v3R2* комісій за відправку повідомлення з тілом `transfer` + довільної суми TON, пов'язаної з `forward_ton_amount` + (якщо необхідно). Приєднана сума TON визначається шляхом додавання комісії за ініціалізацію гаманця v3R2 (значення) + + комісії за відправлення повідомлення з тілом `transfer` (значення) + довільна сума TON + для `forward_ton_amount` (значення) (за необхідності). +4. Коли баланс за адресою стає ненульовим, статус акаунта змінюється. Зачекайте кілька секунд і перевірте статус + акаунта, незабаром він зміниться зі стану `nonexists` на `uninit`. +5. Для кожної адреси власника (зі статусом `uninit`) необхідно відправити зовнішнє повідомлення з гаманцем v3R2 + init і тіло з повідомленням `transfer` для поповнення гаманця Jetton = 128 + 32. Для `transfer`, + користувач повинен вказати адресу гарячого гаманця в якості `призначення` і `призначення відповіді`. + Для спрощення ідентифікації переказу можна додати текстовий коментар. +6. Перевірити доставку Джеттона можна за допомогою адреси депозиту на адресу гарячого гаманця за посиланням + , враховуючи [інформацію про обробку вхідних Джеттонів, яку можна знайти тут] (#processing-incoming-jettons). + +### Виведення коштів з Jetton + +:::info Важливо + +Нижче ви знайдете покрокову інструкцію, як обробляти виведення коштів з джеттона. +::: + +Щоб вивести джеттони, гаманець надсилає повідомлення з тілом "переказу" на відповідний гаманець Jetton. +Потім гаманець Jetton відправляє джеттони одержувачу. Для того, щоб сповіщення про переказ надійшло, важливо додати деяку кількість TON +в якості `forward_ton_amount` (і необов'язковий коментар до `forward_payload`). +Див: [Макети повідомлень джеттон-контрактів](#jetton-contract-message-layouts) + +#### Підготовка + +1. Підготуйте список джеттонів для виведення коштів: [Додавання нових джеттонів для обробки та початкової верифікації] (#adding-new-jettons-for-asset-processing-and-initial-verification) +2. Розгортання гарячого гаманця розпочато. Рекомендується Highload v3. [Розгортання гаманця](/develop/dapps/asset-processing/#wallet-deployment) +3. Здійсніть переказ Jetton, використовуючи адресу гарячого гаманця, щоб ініціалізувати гаманець Jetton і поповнити його баланс. + +#### Обробка зняття коштів + +1. Завантажити список оброблених джеттонів +2. Отримати адреси гаманців Jetton для розгорнутого гарячого гаманця: [Як отримати адреси гаманців Jetton для даного користувача] (#retrieving-jetton-wallet-addresses-for-a-given-user) +3. Отримати головні адреси Jetton для кожного гаманця Jetton: [Як отримати дані для гаманців Jetton](#retrieving-data-for-a-specific-jetton-wallet). + Необхідно ввести параметр `jetton` (який фактично є адресою головного контракту Jetton). +4. Порівняйте адреси з генеральних контрактів Jetton з кроку 1 та кроку 3. Якщо адреси не збігаються, слід повідомити про помилку перевірки адреси Jetton. +5. Отримуються запити на виведення коштів, в яких фактично вказується тип Jetton, сума, що переказується, та адреса гаманця отримувача. +6. Перевірте баланс гаманця Jetton, щоб переконатися, що на ньому достатньо коштів для виведення коштів. +7. Згенеруйте [повідомлення](/develop/dapps/asset-processing/jettons#message-0). +8. При використанні гаманця з високим навантаженням рекомендується збирати пакети повідомлень і відправляти їх по одному за раз для оптимізації комісійної винагороди. +9. Збережіть час закінчення терміну дії для вихідних зовнішніх повідомлень (це час, доки гаманець успішно + обробить повідомлення, після цього гаманець більше не буде приймати повідомлення) +10. Надішліть одне або кілька повідомлень (пакетна розсилка). +11. Отримайте список останніх необроблених транзакцій в обліковому записі гарячого гаманця та повторіть його. + Дізнайтеся більше тут: [Перевірка транзакцій контракту](/develop/dapps/asset-processing/#checking-contracts-transactions), + [Приклад Tonweb](https://github.com/toncenter/examples/blob/9f20f7104411771793dfbbdf07f0ca4860f12de2/deposits-single-wallet.js#L43) або + використовуйте метод API Toncenter `/getTransactions`. +12. Подивіться вихідні повідомлення в акаунті. +13. Якщо існує повідомлення з операторним кодом `transfer`, то його слід декодувати, щоб отримати значення `query_id`. + Отриманий `query_id` потрібно позначити як успішно відправлений. +14. Якщо час, необхідний для обробки поточної відсканованої транзакції, перевищує + час закінчення терміну дії, а вихідне повідомлення з заданим `query_id` + не знайдено, то запит слід (це необов'язково) позначити як прострочений і безпечно відправити його повторно. +15. Шукайте вхідні повідомлення в акаунті. +16. Якщо існує повідомлення, яке використовує операційний код `excesses`, його слід розшифрувати і отримати значення `query_id` + . Знайдений `query_id` слід позначити як успішно доставлений. +17. Перейдіть до кроку 5. Прострочені запити, які не були успішно відправлені, слід повернути до списку відкликання. + +## Обробка в ланцюжку Jetton + +Зазвичай, щоб приймати та обробляти джеттони, обробник повідомлень, відповідальний за внутрішні повідомлення, використовує операційний код `op=0x7362d09c`. + +:::info Підтвердження транзакції +Транзакції TON є незворотними після одного підтвердження. Для кращого користувацького досвіду рекомендується уникати очікування додаткових блоків після завершення транзакцій в блокчейні TON. Детальніше читайте в [Catchain.pdf] (https://docs.ton.org/catchain.pdf#page=3). +::: + +### Рекомендації щодо обробки в ланцюжку + +Нижче наведено "список рекомендацій", які необхідно враховувати при **проведенні обробки джеттону в ланцюжку**: + +1. **Ідентифікувати вхідні джеттони** за типом гаманця, а не за основним контрактом Jetton. Іншими словами, ваш контракт повинен взаємодіяти (отримувати і відправляти повідомлення) з конкретним гаманцем джеттона (а не з якимось невідомим гаманцем, що використовує конкретний основний контракт Jetton). +2. Під час зв'язування гаманця Jetton та головного контракту Jetton переконайтеся, що цей зв'язок є двонаправленим, тобто гаманець розпізнає головний контракт і навпаки. Наприклад, якщо ваша контрактна система отримує повідомлення від гаманця Jetton (який вважає свій MySuperJetton головним контрактом), інформація про переказ повинна відображатися користувачеві, перш ніж показати символ, ім'я та зображення + контракту MySuperJetton, переконайтеся, що гаманець MySuperJetton використовує правильну контрактну систему. У свою чергу, якщо ваша контрактна система з якихось причин повинна відправляти джеттони з використанням майстер-контрактів MySuperJetton або MySuperJetton, перевірте, що гаманець X використовує ті ж параметри контракту, що і гаманець MySuperJetton. + Крім того, перед тим, як надсилати запит на переказ на X, переконайтеся, що він визнає MySuperJetton своїм головним. +3. Справжня сила децентралізованих фінансів (DeFi) базується на можливості накладати протоколи один на одного, як кубики лего. Наприклад, скажімо, джеттон А обмінюється на джеттон Б, який, в свою чергу, використовується як кредитне плече в рамках протоколу кредитування (коли користувач надає ліквідність), який потім використовується для купівлі NFT .... і так далі. Таким чином, розглянемо, як контракт може обслуговувати не тільки позамережевих користувачів, але й мережевих суб'єктів, прикріплюючи токенізовану вартість до повідомлення про переказ, додаючи користувацьке корисне навантаження, яке може бути надіслане разом із повідомленням про переказ. +4. \*\*Майте на увазі, що не всі контракти дотримуються однакових стандартів. На жаль, деякі джеттони можуть бути ворожими (з використанням векторів атак) і створюватися з єдиною метою - атакувати користувачів, які нічого не підозрюють. З метою безпеки, якщо протокол, про який йде мова, складається з багатьох контрактів, не створюйте велику кількість однотипних джеттон-гаманців. Зокрема, не надсилайте джеттони всередині протоколу між депозитним контрактом, контрактом на зберігання, контрактом на обліковий запис користувача тощо. Зловмисники можуть навмисно втрутитися в логіку контракту, підробивши повідомлення про переказ, суми джеттонів або параметри корисного навантаження. Зменшіть ймовірність атак, використовуючи лише один гаманець у системі на один джеттон (для всіх депозитів і зняття коштів). +5. Також **часто корисно** створювати субконтракти для кожного окремого джеттона, щоб зменшити ймовірність підміни адреси (наприклад, коли повідомлення про переказ надсилається на джеттон B з використанням контракту, призначеного для джеттона A). +6. Наполегливо рекомендується працювати з неподільними одиницями джеттон на рівні контрактів. Логіка, пов'язана з десятковою системою числення, зазвичай використовується для покращення користувацького інтерфейсу (UI) diplay і не пов'язана з числовим веденням записів у ланцюжку. + +Щоб дізнатися більше про [Безпечне програмування смарт-контрактів у FunC від CertiK] (https://blog.ton.org/secure-smart-contract-programming-in-func), ознайомтеся з цим ресурсом. Рекомендується, щоб розробники **обробляли всі винятки смарт-контрактів**, щоб вони ніколи не були пропущені під час розробки програми. + +## Рекомендації щодо обробки гаманця Jetton + +Як правило, всі процедури верифікації, що використовуються для обробки джеттонів, підходять і для гаманців. Для обробки джеттон-гаманців наші найважливіші рекомендації наступні: + +1. Коли гаманець отримує повідомлення про переказ з невідомого джеттон-гаманця, дуже важливо довіряти джеттон-гаманцю та його головній адресі, оскільки він може бути зловмисною підробкою. Щоб захистити себе, перевірте Jetton Master (основний договір), використовуючи надану адресу, щоб переконатися, що ваші процеси верифікації визнають джеттон-гаманець легітимним. Після того, як ви довіритеся гаманцю і він буде підтверджений як легітимний, ви можете дозволити йому доступ до залишків на ваших рахунках та інших даних у гаманці. Якщо Jetton Master не розпізнає цей гаманець, рекомендується взагалі не ініціювати і не розкривати свої джеттон-перекази, а показувати тільки вхідні перекази TON (Toncoin, прикріплені до повідомлень про перекази). +2. На практиці, якщо користувач хоче взаємодіяти з джеттоном, а не з джеттон-гаманцем. Іншими словами, користувачі відправляють wTON/oUSDT/jUSDT, jUSDC, jDAI замість `EQAjN...`/`EQBLE...` + тощо. Часто це означає, що коли користувач ініціює джеттон-переказ, гаманець запитує відповідного джеттон-майстра, який джеттон-гаманець (що належить користувачеві) повинен ініціювати запит на переказ. Важливо ніколи не довіряти сліпо\*\* цим даним від майстра (майстер-контракту). Перш ніж надсилати запит на переказ на джеттон-гаманець, завжди переконайтеся, що джеттон-гаманець дійсно належить тому майстру джеттонів, на якого він посилається. +3. \*\*Майте на увазі, що ворожі Jetton-майстри/jetton-гаманці з часом можуть змінювати свої гаманці/майстри. Тому вкрай важливо, щоб користувачі проявляли належну обачність і перевіряли легітимність будь-яких гаманців, з якими вони взаємодіють, перед кожним використанням. +4. \*\*Завжди переконайтеся, що ви відображаєте джеттони в інтерфейсі таким чином, щоб вони не змішувалися з TON-переказами, системними сповіщеннями тощо. Навіть параметри "символ", "ім'я" та "зображення" + можуть бути створені таким чином, щоб вводити в оману користувачів, роблячи їх потенційними жертвами шахрайства. Було зафіксовано кілька випадків, коли шкідливі джеттони використовувалися для імітації TON-переказів, помилок у сповіщеннях, нарахування винагороди або оголошень про заморожування активів. +5. **Завжди слідкуйте за потенційними зловмисниками**, які створюють підроблені джеттони, тому завжди корисно надати користувачам функціонал, необхідний для усунення небажаних джеттонів в їхньому основному інтерфейсі користувача. + +Автори: [kosrk](https://github.com/kosrk), [krigga](https://github.com/krigga), [EmelyanenkoK](https://github.com/EmelyanenkoK/) та [tolya-yanot](https://github.com/tolya-yanot/). + +## Найкращі практики + +Якщо вам потрібні готові приклади для тестування, перевірте [SDKs](/develop/dapps/asset-processing/jettons#sdks) і спробуйте їх запустити. Нижче наведено фрагменти коду, які допоможуть вам зрозуміти обробку джеттонів на прикладах коду. + +### Надсилайте джеттони з коментарями + + + + +
+ +Вихідний код + + +```js +// first 4 bytes are tag of text comment +const comment = new Uint8Array([... new Uint8Array(4), ... new TextEncoder().encode('text comment')]); + +await wallet.methods.transfer({ + secretKey: keyPair.secretKey, + toAddress: JETTON_WALLET_ADDRESS, // address of Jetton wallet of Jetton sender + amount: TonWeb.utils.toNano('0.05'), // total amount of TONs attached to the transfer message + seqno: seqno, + payload: await jettonWallet.createTransferBody({ + jettonAmount: TonWeb.utils.toNano('500'), // Jetton amount (in basic indivisible units) + toAddress: new TonWeb.utils.Address(WALLET2_ADDRESS), // recepient user's wallet address (not Jetton wallet) + forwardAmount: TonWeb.utils.toNano('0.01'), // some amount of TONs to invoke Transfer notification message + forwardPayload: comment, // text comment for Transfer notification message + responseAddress: walletAddress // return the TONs after deducting commissions back to the sender's wallet address + }), + sendMode: 3, +}).send() +``` + +
+ +
+ + +
+ +Вихідний код + + +```go +client := liteclient.NewConnectionPool() + +// connect to testnet lite server +err := client.AddConnectionsFromConfigUrl(context.Background(), "https://ton.org/global.config.json") +if err != nil { + panic(err) +} + +ctx := client.StickyContext(context.Background()) + +// initialize ton api lite connection wrapper +api := ton.NewAPIClient(client) + +// seed words of account, you can generate them with any wallet or using wallet.NewSeed() method +words := strings.Split("birth pattern then forest walnut then phrase walnut fan pumpkin pattern then cluster blossom verify then forest velvet pond fiction pattern collect then then", " ") + +w, err := wallet.FromSeed(api, words, wallet.V3R2) +if err != nil { + log.Fatalln("FromSeed err:", err.Error()) + return +} + +token := jetton.NewJettonMasterClient(api, address.MustParseAddr("EQD0vdSA_NedR9uvbgN9EikRX-suesDxGeFg69XQMavfLqIw")) + +// find our jetton wallet +tokenWallet, err := token.GetJettonWallet(ctx, w.WalletAddress()) +if err != nil { + log.Fatal(err) +} + +amountTokens := tlb.MustFromDecimal("0.1", 9) + +comment, err := wallet.CreateCommentCell("Hello from tonutils-go!") +if err != nil { + log.Fatal(err) +} + +// address of receiver's wallet (not token wallet, just usual) +to := address.MustParseAddr("EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N") +transferPayload, err := tokenWallet.BuildTransferPayload(to, amountTokens, tlb.ZeroCoins, comment) +if err != nil { + log.Fatal(err) +} + +// your TON balance must be > 0.05 to send +msg := wallet.SimpleMessage(tokenWallet.Address(), tlb.MustFromTON("0.05"), transferPayload) + +log.Println("sending transaction...") +tx, _, err := w.SendWaitTransaction(ctx, msg) +if err != nil { + panic(err) +} +log.Println("transaction confirmed, hash:", base64.StdEncoding.EncodeToString(tx.Hash)) +``` + +
+ +
+ + +
+ +Вихідний код + + +```py +my_wallet = Wallet(provider=client, mnemonics=my_wallet_mnemonics, version='v4r2') + +# for TonCenterClient and LsClient +await my_wallet.transfer_jetton(destination_address='address', jetton_master_address=jetton.address, jettons_amount=1000, fee=0.15) + +# for all clients +await my_wallet.transfer_jetton_by_jetton_wallet(destination_address='address', jetton_wallet='your jetton wallet address', jettons_amount=1000, fee=0.1) +``` + +
+ +
+ + + +
+ +Вихідний код + + +```py +from pytoniq import LiteBalancer, WalletV4R2, begin_cell +import asyncio + +mnemonics = ["your", "mnemonics", "here"] + +async def main(): + provider = LiteBalancer.from_mainnet_config(1) + await provider.start_up() + + wallet = await WalletV4R2.from_mnemonic(provider=provider, mnemonics=mnemonics) + USER_ADDRESS = wallet.address + JETTON_MASTER_ADDRESS = "EQBlqsm144Dq6SjbPI4jjZvA1hqTIP3CvHovbIfW_t-SCALE" + DESTINATION_ADDRESS = "EQAsl59qOy9C2XL5452lGbHU9bI3l4lhRaopeNZ82NRK8nlA" + + USER_JETTON_WALLET = (await provider.run_get_method(address=JETTON_MASTER_ADDRESS, + method="get_wallet_address", + stack=[begin_cell().store_address(USER_ADDRESS).end_cell().begin_parse()]))[0].load_address() + forward_payload = (begin_cell() + .store_uint(0, 32) # TextComment op-code + .store_snake_string("Comment") + .end_cell()) + transfer_cell = (begin_cell() + .store_uint(0xf8a7ea5, 32) # Jetton Transfer op-code + .store_uint(0, 64) # query_id + .store_coins(1 * 10**9) # Jetton amount to transfer in nanojetton + .store_address(DESTINATION_ADDRESS) # Destination address + .store_address(USER_ADDRESS) # Response address + .store_bit(0) # Custom payload is None + .store_coins(1) # Ton forward amount in nanoton + .store_bit(1) # Store forward_payload as a reference + .store_ref(forward_payload) # Forward payload + .end_cell()) + + await wallet.transfer(destination=USER_JETTON_WALLET, amount=int(0.05*1e9), body=transfer_cell) + await provider.close_all() + +asyncio.run(main()) +``` + +
+ +
+
+ +### Прийняти Jetton Transfer з розбором коментарів + + + + +
+ +Вихідний код + + +```ts +import { + Address, + TonClient, + Cell, + beginCell, + storeMessage, + JettonMaster, + OpenedContract, + JettonWallet, + Transaction +} from '@ton/ton'; + + +export async function retry(fn: () => Promise, options: { retries: number, delay: number }): Promise { + let lastError: Error | undefined; + for (let i = 0; i < options.retries; i++) { + try { + return await fn(); + } catch (e) { + if (e instanceof Error) { + lastError = e; + } + await new Promise(resolve => setTimeout(resolve, options.delay)); + } + } + throw lastError; +} + +export async function tryProcessJetton(orderId: string) : Promise { + + const client = new TonClient({ + endpoint: 'https://toncenter.com/api/v2/jsonRPC', + apiKey: 'TONCENTER-API-KEY', // https://t.me/tonapibot + }); + + interface JettonInfo { + address: string; + decimals: number; + } + + interface Jettons { + jettonMinter : OpenedContract, + jettonWalletAddress: Address, + jettonWallet: OpenedContract + } + + const MY_WALLET_ADDRESS = 'INSERT-YOUR-HOT-WALLET-ADDRESS'; // your HOT wallet + + const JETTONS_INFO : Record = { + 'jUSDC': { + address: 'EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728', // + decimals: 6 + }, + 'jUSDT': { + address: 'EQBynBO23ywHy_CgarY9NK9FTz0yDsG82PtcbSTQgGoXwiuA', + decimals: 6 + }, + } + const jettons: Record = {}; + + const prepare = async () => { + for (const name in JETTONS_INFO) { + const info = JETTONS_INFO[name]; + const jettonMaster = client.open(JettonMaster.create(Address.parse(info.address))); + const userAddress = Address.parse(MY_WALLET_ADDRESS); + + const jettonUserAddress = await jettonMaster.getWalletAddress(userAddress); + + console.log('My jetton wallet for ' + name + ' is ' + jettonUserAddress.toString()); + + const jettonWallet = client.open(JettonWallet.create(jettonUserAddress)); + + //const jettonData = await jettonWallet; + const jettonData = await client.runMethod(jettonUserAddress, "get_wallet_data") + + jettonData.stack.pop(); //skip balance + jettonData.stack.pop(); //skip owneer address + const adminAddress = jettonData.stack.readAddress(); + + + if (adminAddress.toString() !== (Address.parse(info.address)).toString()) { + throw new Error('jetton minter address from jetton wallet doesnt match config'); + } + + jettons[name] = { + jettonMinter: jettonMaster, + jettonWalletAddress: jettonUserAddress, + jettonWallet: jettonWallet + }; + } + } + + const jettonWalletAddressToJettonName = (jettonWalletAddress : Address) => { + const jettonWalletAddressString = jettonWalletAddress.toString(); + for (const name in jettons) { + const jetton = jettons[name]; + + if (jetton.jettonWallet.address.toString() === jettonWalletAddressString) { + return name; + } + } + return null; + } + + // Subscribe + const Subscription = async ():Promise =>{ + + const client = new TonClient({ + endpoint: 'https://toncenter.com/api/v2/jsonRPC', + apiKey: 'TONCENTER-API-KEY', // https://t.me/tonapibot + }); + + const myAddress = Address.parse('INSERT-YOUR-HOT-WALLET'); // Address of receiver TON wallet + const transactions = await client.getTransactions(myAddress, { + limit: 5, + }); + return transactions; + } + + return retry(async () => { + + await prepare(); + const Transactions = await Subscription(); + + for (const tx of Transactions) { + + const sourceAddress = tx.inMessage?.info.src; + if (!sourceAddress) { + // external message - not related to jettons + continue; + } + + if (!(sourceAddress instanceof Address)) { + continue; + } + + const in_msg = tx.inMessage; + + if (in_msg?.info.type !== 'internal') { + // external message - not related to jettons + continue; + } + + // jetton master contract address check + const jettonName = jettonWalletAddressToJettonName(sourceAddress); + if (!jettonName) { + // unknown or fake jetton transfer + continue; + } + + if (tx.inMessage === undefined || tx.inMessage?.body.hash().equals(new Cell().hash())) { + // no in_msg or in_msg body + continue; + } + + const msgBody = tx.inMessage; + const sender = tx.inMessage?.info.src; + const originalBody = tx.inMessage?.body.beginParse(); + let body = originalBody?.clone(); + const op = body?.loadUint(32); + if (!(op == 0x7362d09c)) { + continue; // op != transfer_notification + } + + console.log('op code check passed', tx.hash().toString('hex')); + + const queryId = body?.loadUint(64); + const amount = body?.loadCoins(); + const from = body?.loadAddress(); + const maybeRef = body?.loadBit(); + const payload = maybeRef ? body?.loadRef().beginParse() : body; + const payloadOp = payload?.loadUint(32); + if (!(payloadOp == 0)) { + console.log('no text comment in transfer_notification'); + continue; + } + + const comment = payload?.loadStringTail(); + if (!(comment == orderId)) { + continue; + } + + console.log('Got ' + jettonName + ' jetton deposit ' + amount?.toString() + ' units with text comment "' + comment + '"'); + const txHash = tx.hash().toString('hex'); + return (txHash); + } + throw new Error('Transaction not found'); + }, {retries: 30, delay: 1000}); +} +``` + +
+ +
+ + +
+ +Вихідний код + + +```go +import ( + "context" + "fmt" + "log" + + "github.com/xssnick/tonutils-go/address" + "github.com/xssnick/tonutils-go/liteclient" + "github.com/xssnick/tonutils-go/tlb" + "github.com/xssnick/tonutils-go/ton" + "github.com/xssnick/tonutils-go/ton/jetton" + "github.com/xssnick/tonutils-go/tvm/cell" +) + +const ( + MainnetConfig = "https://ton.org/global.config.json" + TestnetConfig = "https://ton.org/global.config.json" + MyWalletAddress = "INSERT-YOUR-HOT-WALLET-ADDRESS" +) + +type JettonInfo struct { + address string + decimals int +} + +type Jettons struct { + jettonMinter *jetton.Client + jettonWalletAddress string + jettonWallet *jetton.WalletClient +} + +func prepare(api ton.APIClientWrapped, jettonsInfo map[string]JettonInfo) (map[string]Jettons, error) { + userAddress := address.MustParseAddr(MyWalletAddress) + block, err := api.CurrentMasterchainInfo(context.Background()) + if err != nil { + return nil, err + } + + jettons := make(map[string]Jettons) + + for name, info := range jettonsInfo { + jettonMaster := jetton.NewJettonMasterClient(api, address.MustParseAddr(info.address)) + jettonWallet, err := jettonMaster.GetJettonWallet(context.Background(), userAddress) + if err != nil { + return nil, err + } + + jettonUserAddress := jettonWallet.Address() + + jettonData, err := api.RunGetMethod(context.Background(), block, jettonUserAddress, "get_wallet_data") + if err != nil { + return nil, err + } + + slice := jettonData.MustCell(0).BeginParse() + slice.MustLoadCoins() // skip balance + slice.MustLoadAddr() // skip owneer address + adminAddress := slice.MustLoadAddr() + + if adminAddress.String() != info.address { + return nil, fmt.Errorf("jetton minter address from jetton wallet doesnt match config") + } + + jettons[name] = Jettons{ + jettonMinter: jettonMaster, + jettonWalletAddress: jettonUserAddress.String(), + jettonWallet: jettonWallet, + } + } + + return jettons, nil +} + +func jettonWalletAddressToJettonName(jettons map[string]Jettons, jettonWalletAddress string) string { + for name, info := range jettons { + if info.jettonWallet.Address().String() == jettonWalletAddress { + return name + } + } + return "" +} + +func GetTransferTransactions(orderId string, foundTransfer chan<- *tlb.Transaction) { + jettonsInfo := map[string]JettonInfo{ + "jUSDC": {address: "EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728", decimals: 6}, + "jUSDT": {address: "EQBynBO23ywHy_CgarY9NK9FTz0yDsG82PtcbSTQgGoXwiuA", decimals: 6}, + } + + client := liteclient.NewConnectionPool() + + cfg, err := liteclient.GetConfigFromUrl(context.Background(), MainnetConfig) + if err != nil { + log.Fatalln("get config err: ", err.Error()) + } + + // connect to lite servers + err = client.AddConnectionsFromConfig(context.Background(), cfg) + if err != nil { + log.Fatalln("connection err: ", err.Error()) + } + + // initialize ton api lite connection wrapper + api := ton.NewAPIClient(client, ton.ProofCheckPolicySecure).WithRetry() + master, err := api.CurrentMasterchainInfo(context.Background()) + if err != nil { + log.Fatalln("get masterchain info err: ", err.Error()) + } + + // address on which we are accepting payments + treasuryAddress := address.MustParseAddr("EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N") + + acc, err := api.GetAccount(context.Background(), master, treasuryAddress) + if err != nil { + log.Fatalln("get masterchain info err: ", err.Error()) + } + + jettons, err := prepare(api, jettonsInfo) + if err != nil { + log.Fatalln("can't prepare jettons data: ", err.Error()) + } + + lastProcessedLT := acc.LastTxLT + + transactions := make(chan *tlb.Transaction) + + go api.SubscribeOnTransactions(context.Background(), treasuryAddress, lastProcessedLT, transactions) + + log.Println("waiting for transfers...") + + // listen for new transactions from channel + for tx := range transactions { + if tx.IO.In == nil || tx.IO.In.MsgType != tlb.MsgTypeInternal { + // external message - not related to jettons + continue + } + + msg := tx.IO.In.Msg + sourceAddress := msg.SenderAddr() + + // jetton master contract address check + jettonName := jettonWalletAddressToJettonName(jettons, sourceAddress.String()) + if len(jettonName) == 0 { + // unknown or fake jetton transfer + continue + } + + if msg.Payload() == nil || msg.Payload() == cell.BeginCell().EndCell() { + // no in_msg body + continue + } + + msgBodySlice := msg.Payload().BeginParse() + + op := msgBodySlice.MustLoadUInt(32) + if op != 0x7362d09c { + continue // op != transfer_notification + } + + // just skip bits + msgBodySlice.MustLoadUInt(64) + amount := msgBodySlice.MustLoadCoins() + msgBodySlice.MustLoadAddr() + + payload := msgBodySlice.MustLoadMaybeRef() + payloadOp := payload.MustLoadUInt(32) + if payloadOp == 0 { + log.Println("no text comment in transfer_notification") + continue + } + + comment := payload.MustLoadStringSnake() + if comment != orderId { + continue + } + + // process transaction + log.Printf("Got %s jetton deposit %d units with text comment %s\n", jettonName, amount, comment) + foundTransfer <- tx + } +} +``` + +
+
+ + + +
+ +Вихідний код + + +```py +import asyncio + +from pytoniq import LiteBalancer, begin_cell + +MY_WALLET_ADDRESS = "EQAsl59qOy9C2XL5452lGbHU9bI3l4lhRaopeNZ82NRK8nlA" + + +async def parse_transactions(provider: LiteBalancer, transactions): + for transaction in transactions: + if not transaction.in_msg.is_internal: + continue + if transaction.in_msg.info.dest.to_str(1, 1, 1) != MY_WALLET_ADDRESS: + continue + + sender = transaction.in_msg.info.src.to_str(1, 1, 1) + value = transaction.in_msg.info.value_coins + if value != 0: + value = value / 1e9 + + if len(transaction.in_msg.body.bits) < 32: + print(f"TON transfer from {sender} with value {value} TON") + continue + + body_slice = transaction.in_msg.body.begin_parse() + op_code = body_slice.load_uint(32) + if op_code != 0x7362D09C: + continue + + body_slice.load_bits(64) # skip query_id + jetton_amount = body_slice.load_coins() / 1e9 + jetton_sender = body_slice.load_address().to_str(1, 1, 1) + if body_slice.load_bit(): + forward_payload = body_slice.load_ref().begin_parse() + else: + forward_payload = body_slice + + jetton_master = ( + await provider.run_get_method( + address=sender, method="get_wallet_data", stack=[] + ) + )[2].load_address() + jetton_wallet = ( + ( + await provider.run_get_method( + address=jetton_master, + method="get_wallet_address", + stack=[ + begin_cell() + .store_address(MY_WALLET_ADDRESS) + .end_cell() + .begin_parse() + ], + ) + )[0] + .load_address() + .to_str(1, 1, 1) + ) + + if jetton_wallet != sender: + print("FAKE Jetton Transfer") + continue + + if len(forward_payload.bits) < 32: + print( + f"Jetton transfer from {jetton_sender} with value {jetton_amount} Jetton" + ) + else: + forward_payload_op_code = forward_payload.load_uint(32) + if forward_payload_op_code == 0: + print( + f"Jetton transfer from {jetton_sender} with value {jetton_amount} Jetton and comment: {forward_payload.load_snake_string()}" + ) + else: + print( + f"Jetton transfer from {jetton_sender} with value {jetton_amount} Jetton and unknown payload: {forward_payload} " + ) + + print(f"Transaction hash: {transaction.cell.hash.hex()}") + print(f"Transaction lt: {transaction.lt}") + + +async def main(): + provider = LiteBalancer.from_mainnet_config(1) + await provider.start_up() + transactions = await provider.get_transactions(address=MY_WALLET_ADDRESS, count=5) + await parse_transactions(provider, transactions) + await provider.close_all() + + +if __name__ == "__main__": + asyncio.run(main()) +``` + +
+
+
+ +## SDK + +Список SDK для різних мов (js, python, golang, C#, Rust і т.д.) можна знайти [тут](/develop/dapps/apis/sdk). + +## Дивіться також + +- [Обробка платежів](/develop/dapps/asset-processing/) +- [Обробка NFT на TON](/develop/dapps/asset-processing/nfts) +- [Парсинг метаданих на TON](/develop/dapps/asset-processing/metadata) diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md b/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md new file mode 100644 index 0000000000..1ed365f656 --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md @@ -0,0 +1,62 @@ +import Button from '@site/src/components/button' +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Огляд процесу обробки активів + +Тут ви можете знайти **короткий огляд** про те, [як працюють перекази TON] (/develop/dapps/asset-processing/overview#overview-on-messages-and-transactions), які [типи активів](/develop/dapps/asset-processing/overview#digital-asset-types-on-ton) можна знайти в TON (і про що ви прочитаєте [далі](/develop/dapps/asset-processing/overview#read-next)) і як [взаємодіяти з ton](/develop/dapps/asset-processing/overview#interaction-with-ton-blockchain) за допомогою вашої мови програмування, рекомендується зрозуміти всю інформацію, викладену нижче, перш ніж переходити до наступних сторінок. + +## Огляд повідомлень і транзакцій + +Втілюючи повністю асинхронний підхід, TON Blockchain включає в себе кілька концепцій, які є незвичними для традиційних блокчейнів. Зокрема, кожна взаємодія будь-якого актора з блокчейном складається з графа асинхронно переданих [повідомлень] (/develop/smart-contracts/guidelines/message-delivery-guarantees) між смарт-контрактами та/або зовнішнім світом. Кожна транзакція складається з одного вхідного повідомлення і до 512 вихідних повідомлень. + +Існує 3 типи повідомлень, які повністю описані [тут] (/develop/smart-contracts/messages#типи повідомлень). Якщо говорити коротко: + +- [зовнішнє повідомлення](/develop/smart-contracts/guidelines/external-messages): + - "Зовнішнє повідомлення" (іноді його називають просто "зовнішнє повідомлення") - це повідомлення, яке надсилається з *зовні* блокчейну до смарт-контракту *всередині* блокчейну. + - "Зовнішнє вихідне повідомлення" (зазвичай його називають "повідомленням журналу") надсилається від *суб'єкта блокчейну* до *зовнішнього світу*. +- [внутрішнє повідомлення] (/develop/smart-contracts/guidelines/internal-messages) надсилається від одного *суб'єкта блокчейну* до *іншого*, може містити певну кількість цифрових активів і довільну частину даних. + +Загальний шлях будь-якої взаємодії починається із зовнішнього повідомлення, надісланого до смарт-контракту "гаманця", який аутентифікує відправника повідомлення за допомогою криптографії з відкритим ключем, бере на себе оплату комісії та надсилає внутрішні блокчейн-повідомлення. Ця черга повідомлень утворює орієнтований ациклічний граф, або дерево. + +Наприклад: + +![](/img/docs/asset-processing/alicemsgDAG.svg) + +- "Аліса" використовує, наприклад, [Tonkeeper] (https://tonkeeper.com/), щоб відправити "зовнішнє повідомлення" на свій гаманець. +- зовнішнє повідомлення" - вхідне повідомлення для контракту "гаманець A v4" з порожнім судом (повідомлення з нізвідки, наприклад, [Tonkeeper](https://tonkeeper.com/)). +- вихідне повідомлення" - це вихідне повідомлення для контракту "гаманець A v4" і вхідне повідомлення для контракту "гаманець B v4" з джерелом "гаманець A v4" і призначенням "гаманець B v4". + +В результаті маємо 2 транзакції з їх набором вхідних та вихідних повідомлень. + +Кожна дія, коли контракт отримує повідомлення на вхід (запускається ним), обробляє його і генерує або не генерує вихідні повідомлення на виході, називається "транзакцією". Дізнайтеся більше про транзакції [тут] (/develop/smart-contracts/guidelines/message-delivery-guarantees#what-is-transaction). + +Ці "транзакції" можуть охоплювати **тривалий період часу**. Технічно, транзакції з чергами повідомлень агрегуються в блоки, які обробляються валідаторами. Асинхронна природа TON Blockchain **не дозволяє передбачити хеш і lt (логічний час) транзакції** на етапі відправлення повідомлення. + +Прийнята до блоку "транзакція" є остаточною і не може бути змінена. + +:::info Підтвердження транзакції +Транзакції TON є незворотними після одного підтвердження. Для кращого користувацького досвіду рекомендується уникати очікування додаткових блоків після завершення транзакцій в блокчейні TON. Детальніше читайте в [Catchain.pdf] (https://docs.ton.org/catchain.pdf#page=3). +::: + +Смарт-контракти сплачують кілька типів [комісій](/develop/smart-contracts/fees) за транзакції (зазвичай від балансу вхідного повідомлення, поведінка залежить від [режиму повідомлення](/develop/smart-contracts/messages#message-modes)). Розмір комісії залежить від конфігурації робочого ланцюга: максимальна комісія на `masterchain` і значно нижча на `basechain`. + +## Типи цифрових активів на TON + +ТОН має три типи цифрових активів. + +- Toncoin, основний токен мережі. Він використовується для всіх базових операцій в блокчейні, наприклад, для оплати за газ або стейкінгу для валідації. +- Контрактні активи, такі як токени і NFT, які є аналогом стандартів ERC-20/ERC-721 і управляються довільними контрактами, а тому можуть вимагати кастомних правил для обробки. Ви можете знайти більше інформації про їх обробку в статтях [обробка NFT](/develop/dapps/asset-processing/nfts) і [обробка джеттонів](/develop/dapps/asset-processing/jettons). +- Нативні токени (Native token) - особливий вид активів, які можуть бути прикріплені до будь-якого повідомлення в мережі. Але наразі ці активи не використовуються, оскільки функціонал для випуску нових нативних токенів закритий. + +## Взаємодія з блокчейном TON + +Базові операції з блокчейном TON можна здійснювати за допомогою TonLib. Це спільна бібліотека, яка може бути скомпільована разом з вузлом TON і надавати API для взаємодії з блокчейном через так звані lite-сервери (сервери для lite-клієнтів). TonLib дотримується підходу без довіри, перевіряючи докази для всіх вхідних даних; таким чином, немає необхідності в надійному постачальнику даних. Методи, доступні для TonLib, перелічено [у схемі TL](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L234). Вони можуть бути використані як спільна бібліотека за допомогою [wrappers](/develop/dapps/asset-processing/#repositories). + +## Читати далі + +Прочитавши цю статтю, ви зможете перевірити: + +1. [Обробка платежів](/develop/dapps/asset-processing/), щоб дізнатися, як працювати з `TON coins`. +2. [Обробка джеттонів](/develop/dapps/asset-processing/jettons), щоб дізнатися, як працювати з `джеттонами` (іноді їх називають `токенами`) +3. [Обробка NFT](/develop/dapps/asset-processing/nfts), щоб дізнатися, як працювати з `NFT` (це спеціальний тип `jetton`) diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx b/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx new file mode 100644 index 0000000000..0c4ba0c9ce --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx @@ -0,0 +1,113 @@ +import Button from '@site/src/components/button' + +# Про TON Connect + +TON Connect - це потужний інструментарій з відкритим вихідним кодом, який слугує універсальним стандартом авторизації додатків в екосистемі [TON](/learn/introduction), дозволяючи користувачам безпечно та зручно входити в додатки та сервіси за допомогою своїх гаманців TON замість традиційних логінів та паролів. + +![](/img/docs/ton-connect/ton-connect-overview.png?raw=true) + +Не соромтеся використовувати один з наступних потоків для інтеграції вашого додатку: + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Варіанти використання для вашого DApp + +Ознайомтеся з цими результатами, які надає екосистема TON для чудової DApplication-інтеграції. + +- **Трафік**. Залучайте додаткові відвідування користувачів через криптогаманці, які підтримують TON Connect. +- **Автентичність**. Використовуйте гаманці користувачів TON як готові акаунти, усуваючи необхідність додаткових кроків автентифікації і, таким чином, покращуючи користувацький досвід. +- **Платежі**. Обробляйте транзакції швидко і безпечно через TON Blockchain, використовуючи Toncoin або загорнуті стабільні монети (jUSDC/jUSDT). +- **Утримання**. Покращуйте утримання користувачів за допомогою функції збереження списків у додатку, яка дозволяє користувачам відстежувати нещодавно відкриті та улюблені програми. + +## Для розробників гаманців + +Якщо ви розробник гаманців, ви можете підключити свій гаманець до TON Connect і надати своїм користувачам можливість взаємодіяти з додатками TON у безпечний та зручний спосіб, прочитайте, як [інтегрувати TON Connect у ваш гаманець](/develop/dapps/ton-connect/wallet/). + +## Історії успіху + +- [GetGems - Відкритий мережевий ринок] (https://getgems.io/) +- [STON.fi - AMM DEX для блокчейну TON] (https://ston.fi/) +- [Tonstarter](http://tonstarter.com/) + +
+ Показати весь список + +- [getgems.io](https://getgems.io/) +- [fragment.com](https://fragment.com/) (Ton Connect v.1) +- [ston.fi](https://ston.fi/) +- [ton.diamonds](https://ton.diamonds/) +- [beta.disintar.io](https://beta.disintar.io/) +- [tegro.finance](https://tegro.finance/liquidity) +- [minter.ton.org](https://minter.ton.org/) +- [libermall.com](https://libermall.com/) +- [dedust.io](https://dedust.io/swap) +- [toncap.net](https://toncap.net/) +- [cryptomus.com](https://cryptomus.com/) +- [avanchange.com](https://avanchange.com/) +- [wton.dev](https://wton.dev/) +- [mint.spiroverse.io/shop](https://mint.spiroverse.io/shop) +- [vk.com/vk_nft_hub](https://vk.com/vk_nft_hub) +- [tonverifier.live](https://verifier.ton.org/) +- [stickerface.io/member](https://stickerface.io/member) +- [tonstarter.com](https://tonstarter.com/) +- [cryptogas.shop/ton](https://cryptogas.shop/ton) +- [megaton.fi](https://megaton.fi/) +- [dns.ton.org](https://dns.ton.org/) +- [coinpaymaster.com](https://coinpaymaster.com/) +- [ton.gagarin.world/app/](https://ton.gagarin.world/app) +- [daolama.co](https://daolama.co/) +- [marketplace.playmuse.org](http://marketplace.playmuse.org/) +- [ton.vote](https://ton.vote/) +- [plane.tonfancy.io](https://plane.tonfancy.io/) +- [pi.oberton.io](https://pi.oberton.io/) +- [business.thetonpay.app](https://business.thetonpay.app/) +- [bridge.orbitchain.io](https://bridge.orbitchain.io/) +- [connecton-web-new.vercel.app](https://connecton-web-new.vercel.app/) +- [app.fanz.ee/staking](https://app.fanz.ee/staking) +- [testnet.pton.fi](https://testnet.pton.fi/) +- [tonft.app](https://tonft.app/) +- [cardify.casino](https://cardify.casino/) +- [4riends.org](https://4riends.org/#/) +- [tonflex.fi](https://tonflex.fi/swap) +- [soquest.xyz](https://soquest.xyz/) +- [app.evaa.finance](https://app.evaa.finance/) + +
+ +## Приєднуйтесь до екосистеми ТОН + +Щоб підключити свій сервіс до екосистеми TON, вам потрібно виконати наступне: + +- \*\*TON Connect. Включіть протокол TON Connect у свій додаток. +- **Транзакції**. Створюйте визначені повідомлення транзакцій за допомогою бібліотек TON. Пориньте у процес [надсилання повідомлень] (/develop/dapps/ton-connect/message-builders) за допомогою нашого вичерпного керівництва. +- **Платежі**. Обробляйте платежі через публічний API ([tonapi](https://tonapi.io/)) або власний індексатор, наприклад, [gobycicle](http://github.com/gobicycle/bicycle). Дізнайтеся більше з нашого докладного посібника з [обробки активів] (/develop/dapps/asset-processing). diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/develop/fift/overview.mdx b/i18n/uk/docusaurus-plugin-content-docs/current/develop/fift/overview.mdx new file mode 100644 index 0000000000..411d1a4949 --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/develop/fift/overview.mdx @@ -0,0 +1,57 @@ +import Button from '@site/src/components/button' + +# Огляд + +Fift - це стекова мова програмування загального призначення, оптимізована для створення, налагодження та управління смарт-контрактами TON Blockchain. +Fift була спеціально розроблена для взаємодії з віртуальною машиною TON (TON VM або TVM) та блокчейном TON. + +```fift +{ ."hello " } execute ."world" +hello world ok +``` + +:::info +Зазвичай використання Fift не є обов'язковим для програмування смарт-контрактів в TON. Однак, іноді вам може знадобитися використання мови Fift для вирішення нестандартних технічних проблем в рамках вашого завдання. +::: + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +



+ +## Документація + +- [П'ятірка: короткий вступ] (https://ton.org/fiftbase.pdf) +- [Віртуальна машина TON](/learn/tvm-instructions/tvm-overview) + +## Приклади + +- [Приклади п'яти смарт-контрактів](/develop/smart-contracts/examples#fift-smart-contracts) + +## Навчальні посібники + +- [Вступ до Fift] (https://blog.ton.org/introduction-to-fift) +- [\[YouTube\]Його величність П'ятірка](https://www.youtube.com/watch?v=HVsveTmVowc&list=PLtUBO1QNEKwttRsAs9eacL2oCMOhWaOZs) \[[RU версія](https://www.youtube.com/playlist?list=PLyDBPwv9EPsCYG-hR4N5FRTKUkfM8POgh)] by **@MarcoDaTr0p0je** & **@Wikimar**. + +## Джерела + +- [П'ять скриптів для стандартних смарт-контрактів] (https://github.com/ton-blockchain/ton/tree/master/crypto/smartcont) diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/develop/func/overview.mdx b/i18n/uk/docusaurus-plugin-content-docs/current/develop/func/overview.mdx new file mode 100644 index 0000000000..2be052ec27 --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/develop/func/overview.mdx @@ -0,0 +1,157 @@ +import Button from '@site/src/components/button' + +# Огляд + +Для програмування смарт-контрактів на TON використовується мова високого рівня FunC. + +FunC - це специфічна для домену C-подібна мова зі статичною типізацією. +Ось простий приклад методу для переказу грошей, написаний на FunC: + +```func +() send_money(slice address, int amount) impure inline { + var msg = begin_cell() + .store_uint(0x10, 6) ;; nobounce + .store_slice(address) + .store_coins(amount) + .end_cell(); + + send_raw_message(msg, 64); +} +``` + +FunC програми компілюються в асемблерний код Fift, який генерує відповідний байт-код для [TON Virtual Machine] (/learn/tvm-instructions/tvm-overview). + +Далі цей байт-код (фактично [дерево комірок] (/learn/overviews/cells), як і будь-які інші дані в TON Blockchain) може бути використаний для створення смарт-контрактів в блокчейні або може бути запущений на локальному екземплярі TVM. + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Компілятор + +### Компіляція з JS + +Найзручніший і найшвидший спосіб почати розробляти і компілювати смарт-контракти - це використовувати фреймворк Blueprint. Детальніше читайте в розділі [Blueprint](/develop/smart-contracts/sdk/javascript). + +```bash +npm create ton@latest +``` + +### Компіляція з оригінальними двійковими файлами + +Якщо ви хочете використовувати рідний TON-компілятор FunC локально, вам потрібно встановити двійкові файли на вашому комп'ютері. Двійкові файли компілятора FunC для Windows, MacOS (Intel/M1) та Ubuntu можна завантажити за посиланням: + +- [Сторінка налаштування середовища](/develop/smart-contracts/environment/installation) + +:::info +У той же час, ви завжди можете створити двійкові файли з таких джерел, як:\ +[Вихідний код компілятора FunC](https://github.com/ton-blockchain/ton/tree/master/crypto/func) (читайте [як скомпілювати](/develop/howto/compile#func) компілятор FunC з вихідних текстів). +::: + +## Курс TON: FunC + +Курс [TON Blockchain Course] (https://stepik.org/course/176754/) - це вичерпний посібник з розробки TON Blockchain. + +Модуль 4 повністю присвячений мові FunC та розробці смарт-контрактів. + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Навчальні посібники + +:::tip наконечник стартера +Найкраще почати розробку з використанням FunC: [ВСТУП](/develop/smart-contracts/) +::: + +Інші матеріали люб'язно надані експертами спільноти: + +- [Серія TON Speed Run](https://tonspeedrun.com/) + - [🚩 Виклик 1: Просте розгортання NFT] (https://github.com/romanovichim/TONQuest1) + - [🚩 Виклик 2: Контракт з чат-ботом] (https://github.com/romanovichim/TONQuest2) + - [🚩 Виклик 3: Торговий автомат Jetton] (https://github.com/romanovichim/TONQuest3) + - [🚩 Виклик 4: Лотерея/розіграш] (https://github.com/romanovichim/TONQuest4) + - [🚩 Виклик 5: Створіть UI для взаємодії з договором за 5 хвилин] (https://github.com/romanovichim/TONQuest5) + - [🚩 Виклик 6: Аналіз продажів NFT на маркетплейсі Getgems] (https://github.com/romanovichim/TONQuest6) + + + +- [Func & Blueprint](https://www.youtube.com/watch?v=7omBDfSqGfA&list=PLtUBO1QNEKwtO_zSyLj-axPzc9O9rkmYa) by **@MarcoDaTr0p0je** +- [Learn FunC in Y Minutes](https://learnxinyminutes.com/docs/func/) by **@romanovichim** +- [TON Hello World: Покрокове керівництво для написання вашого першого смарт-контракту] (https://ton-community.github.io/tutorials/02-contract/) +- [TON Hello World: Покрокове керівництво для тестування вашого першого смарт-контракту] (https://ton-community.github.io/tutorials/04-testing/) +- [10 FunC уроків](https://github.com/romanovichim/TonFunClessons_Eng) від **@romanovichim**, з використанням blueprint +- [10 уроків FunC (RU)](https://github.com/romanovichim/TonFunClessons_ru) by **@romanovichim**, using blueprint +- [FunC Quiz](https://t.me/toncontests/60) від **Vadim** - добре підходить для самоперевірки. Займе 10-15 хвилин. Питання переважно про FunС з кількома загальними питаннями про TON +- [FunC Quiz (RU)](https://t.me/toncontests/58?comment=14888) by **Vadim**-FunC Quiz російською мовою + +## Конкурси + +Участь у [конкурсах](https://t.me/toncontests) - чудовий спосіб вивчити FunC. + +Ви також можете вивчити попередні конкурси з навчальною метою. + +#### Конкурси Спадщина + +| Опис конкурсу | Завдання | Рішення | +| ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | +| TSC #5 (грудень, 2023) | [Завдання](https://github.com/ton-community/tsc5) | | +| TSC #4 (вересень, 2023) | [Завдання](https://github.com/ton-community/tsc4) | [Рішення](/develop/smart-contracts/examples#ton-smart-challenge-4) | +| TSC #3 (грудень, 2022) | [Завдання](https://github.com/ton-blockchain/func-contest3) | [Рішення] (https://github.com/nns2009/TON-FunC-contest-3) | +| TSC #2 (липень, 2022) | [Завдання](https://github.com/ton-blockchain/func-contest2) | [Рішення] (https://github.com/ton-blockchain/func-contest2-solutions) | +| TSC #1 (березень, 2022) | [Завдання](https://github.com/ton-blockchain/func-contest1) | [Рішення] (https://github.com/ton-blockchain/func-contest1-solutions) | + +## Приклади смарт-контрактів + +Стандартні базові смарт-контракти, такі як гаманці, електорат (управляє валідацією на TON), гаманці з декількома підписами і т.д., можуть бути орієнтиром при вивченні. + +- [Приклади смарт-контрактів](/develop/smart-contracts/examples) + +## Журнал змін + +[Історія оновлень funC](/develop/func/changelog). diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/develop/overview.mdx b/i18n/uk/docusaurus-plugin-content-docs/current/develop/overview.mdx new file mode 100644 index 0000000000..f0268944bb --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/develop/overview.mdx @@ -0,0 +1,207 @@ +import Button from '@site/src/components/button' +import Player from '@site/src/components/player' + +# Документація TON + +Ласкаво просимо до офіційної документації з розробки TON Blockchain! + +Цей ресурс має на меті надати вам всю необхідну інформацію, яка знадобиться вам для створення, тестування та розгортання додатків на блокчейні TON. + +Це спільна ініціатива з відкритим вихідним кодом, і внески завжди вітаються. Вся документація може бути відредагована через GitHub, просто [дотримуйтесь цих інструкцій](/contribute). + +- Серія _TON Hello World_ містить детальні покрокові інструкції щодо гаманців, смарт-контрактів, міні-додатків, а також тестування та налагодження смарт-контрактів на TON. +- Початок роботи з TON - це покрокове керівництво по взаємодії з блокчейном TON. (відеоурок додається) + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +### Основи блокчейну з TON + +Цей курс знайомить з основами блокчейну, з особливим акцентом на практичні навички роботи в екосистемі TON. Ви зрозумієте, як функціонує блокчейн та його різноманітні застосування. + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +### Курс TON + +Ми з гордістю представляємо курс **TON Blockchain Course**, який є вичерпним посібником з блокчейну TON. Курс призначений для розробників, які хочуть навчитися створювати смарт-контракти та децентралізовані додатки на блокчейні TON в цікавій та інтерактивній формі. + +Він складається з **9 модулів** і охоплює основи блокчейну TON, мови програмування FunC та віртуальної машини TON (TVM). + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Модулі розробки + +Якщо ви новачок у розробці TON Blockchain, рекомендується почати з самого початку і пропрацювати ці теми. + +### Фундаментальні концепції + +- [The Open Network] (/learn/introduction) - Огляд блокчейну TON на високому рівні. +- [Блокчейн з блокчейнів] (/learn/overviews/ton-blockchain) - доступне пояснення TON Blockchain. +- [Адреси смарт-контрактів](/learn/overviews/addresses) - детальне пояснення адрес. +- [Клітинки як структура даних](/learn/overviews/cells) - високорівневе пояснення структур даних. +- [TON Networking](/learn/networking/oview) - огляд високорівневих однорангових протоколів TON. +- [TON Virtual Machine (TVM)](/learn/tvm-instructions/tvm-oview) - Огляд віртуальної машини TON високого рівня. +- [Транзакції та фази](/learn/tvm-instructions/tvm-overview#transactions-and-phases) - Детальне пояснення транзакцій та фаз. +- [Транзакційні збори](/develop/smart-contracts/fees) - Пояснення на високому рівні щодо транзакційних зборів. + +### Інфраструктура + +- [Типи вузлів](/participate/nodes/node-types) - Детальне пояснення типів вузлів. +- [Запустити повний вузол](/participate/run-nodes/full-node) - детальне пояснення, як запустити вузол. +- [TON DNS & Sites](/participate/web3/dns) - детальне пояснення TON DNS & Sites. +- [TON Storage](/participate/ton-storage/storage-daemon) - Детальне пояснення про TON Storage. + +### Додаткові ресурси + +- [**FAQ**](/develop/howto/faq) - Часті запитання +- [Документація FunC](/develop/func/overview) +- [Документація Fift](/develop/fift/overview) + +## Розробка смарт-контрактів + +Смарт-контракти - це будівельні блоки децентралізованих додатків (DApps) на блокчейні TON. Якщо ви хочете розробити власний DApp, важливо розуміти, як працюють смарт-контракти. + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +



+ +Наступні ресурси надають цінну інформацію для розробки смарт-контрактів TON: + +- [TON Hello World: Покрокове керівництво для написання вашого першого смарт-контракту] (https://ton-community.github.io/tutorials/02-contract/) - Доступне і стисле пояснення основ роботи з JS. +- [Як працювати зі смарт-контрактами гаманця](/develop/smart-contracts/tutorials/wallet) - Детальне та ретельне пояснення основ смарт-контрактів з використанням JS та GO. +- [Вивчаємо смарт-контракти на прикладах](/develop/smart-contracts/examples) (FunC, Fift) +- [Speed Run TON](/develop/smart-contracts/examples) - 6 інтерактивних завдань та покрокових інструкцій для навчання розробці смарт-контрактів. + +## Розробка DApp + +Децентралізовані додатки (DApps) - це додатки, які працюють на одноранговій мережі комп'ютерів, а не на одному комп'ютері (TON Blockchain). Вони схожі на традиційні веб-додатки, але побудовані поверх мережі блокчейн. Це означає, що DApps децентралізовані, тобто жодна організація не контролює їх. + +```mdx-code-block + +``` + +### Розробка DeFi + +- [TON Connect](/develop/dapps/ton-connect/overview) - інтеграція та автентифікація для DApps. +- [Off-chain Payments Processing](/develop/dapps/asset-processing) - приклади та концепції обробки платежів. +- [TON обробка джеттонів](/develop/dapps/asset-processing/jettons) - приклади та концепції для обробки джеттонів. +- [Взаємозамінні (crwd)lbracket/dwrc(FT) Не взаємозамінні crwdlbracketdwrcNFT токени] (/develop/dapps/defi/tokens) - смарт-контракти, приклади, інструменти + +Зробіть перші кроки у розробці DApps за допомогою вичерпного посібника зі створення DApps: + +- [TON Hello World: Покрокове керівництво для створення вашого першого веб-клієнта] (https://ton-community.github.io/tutorials/03-client/) +- [Інтеграція Telegram-бота через TON Connect](/develop/dapps/ton-connect/tg-bot-integration) + +### API та SDK + +- [API](/develop/dapps/apis) +- [SDK](/develop/dapps/apis/sdk) + +## Поширені запитання + +Перейдіть до розділу [Часті запитання] (/develop/howto/faq). diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/develop/smart-contracts/testing/overview.mdx b/i18n/uk/docusaurus-plugin-content-docs/current/develop/smart-contracts/testing/overview.mdx new file mode 100644 index 0000000000..e77b991b73 --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/develop/smart-contracts/testing/overview.mdx @@ -0,0 +1,141 @@ +# Написання тестів за допомогою Blueprint + +## Огляд + +Інструментарій для тестування (зазвичай пісочниця) вже включено до TypeScript SDK під назвою [Blueprint](/develop/smart-contracts/sdk/javascript). Ви можете створити демонстраційний проект і запустити тест за замовчуванням у два кроки: + +1. Створіть новий проєкт Blueprint: + +```bash +npm create ton@latest MyProject +``` + +2. Проведіть тест: + +```bash +cd MyProject +npx blueprint test +``` + +В результаті ви побачите відповідний вивід у вікні терміналу: + +```bash +% npx blueprint test + +> MyProject@0.0.1 test +> jest + + PASS tests/Main.spec.ts + Main + ✓ should deploy (127 ms) + +Test Suites: 1 passed, 1 total +Tests: 1 passed, 1 total +Snapshots: 0 total +Time: 1.224 s, estimated 2 s +Ran all test suites. +``` + +## Основне використання + +Тестування смарт-контрактів дозволяє перевірити безпеку, оптимізувати витрати газу та дослідити крайні випадки. +Написання тестів у Blueprint (на основі [Sandbox](https://github.com/ton-org/sandbox)) працює через визначення довільних дій з контрактом і порівняння результатів тесту з очікуваним результатом, наприклад: + +```typescript +it('should execute with success', async () => { // description of the test case + const res = await main.sendMessage(sender.getSender(), toNano('0.05')); // performing an action with contract main and saving result in res + + expect(res.transactions).toHaveTransaction({ // configure the expected result with expect() function + from: main.address, // set expected sender for transaction we want to test matcher properties from + success: true // set the desirable result using matcher property success + }); + + printTransactionFees(res.transactions); // print table with details on spent fees +}); +``` + +### Написання тестів на складне твердження + +Основний робочий процес створення тесту виглядає наступним чином: + +1. Створіть спеціальну обгорнуту сутність `Contract` за допомогою `blockchain.openContract()`. +2. Опишіть дії, які повинен виконати ваш `Contract`, і збережіть результат виконання у змінній `res`. +3. Перевірте властивості за допомогою функції `expect()` та відповідника `toHaveTransaction()`. + +Відповідник `toHaveTransaction` очікує об'єкт з будь-якою комбінацією полів типу `FlatTransaction`, визначених з наступними властивостями + +| Ім'я | Тип | Опис | +| -------------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| від | Адреса? | Контрактна адреса відправника повідомлення | +| на | Адреса | Контрактна адреса призначення повідомлення (Альтернативна назва властивості `to`). | +| значення | Біґінт? | Кількість Toncoins у повідомленні в нанотонах | +| тіло | Cell | Тіло повідомлення визначено як комірка | +| op | номер? | Код операції - це номер ідентифікатора операції (зазвичай crc32 у TL-B). Очікується у перших 32 бітах тіла повідомлення. | +| успіх | булевий? | Прапорець користувацької пісочниці, який визначає результуючий статус певної транзакції. True - якщо і обчислення, і фаза дії пройшли успішно. В іншому випадку - False. | + +Ви можете опустити поля, які вас не цікавлять, і передати функції, які приймають типи, що повертають булеві значення ("істина" означає "добре") для перевірки, наприклад, діапазонів чисел, опкодів повідомлень тощо. Зверніть увагу, що якщо поле є необов'язковим (наприклад, `from?: Address`), то функція також повинна приймати необов'язковий тип. + +:::tip +Повний список полів-відповідників ви можете знайти в [Документації пісочниці](https://github.com/ton-org/sandbox#test-a-transaction-with-matcher). +::: + +### Спеціальний набір тестів + +#### Витягнути SendMode + +Щоб витягти режим відправлення надісланого повідомлення, ви можете скористатися наступним кодом: + +```ts + +const smc = await blockchain.getContract(addr); + +const re = blockchain.executor.runTransaction({ + config: blockchain.configBase64, libs: null, verbosity: 'full', + now: Math. floor (Date.now) / 1000), + lt: BigInt(Date.now()), + randomSeed: null, + ignoreChksig: false, + debugEnabled: true, + shardAccount: beginCell() + .store (storeShardAccount (smc.account)) + .endCell() + .toBoc() + .toString('base64'), + message: beginCell() + .store (storeMessageRelaxed (...)) + .endCell(), +}); + +if (!re.result. success || !re.result.actions) { + throw new Error('fail'); +} +const actions = loadoutList(Cell.fromBase64(re.result.actions).beginParse()); +actions[0].type === 'sendMsg' && actions[0].mode; + +``` + +## Навчальні посібники + +Дізнайтеся більше про тестування з найцінніших підручників спільноти на TON: + +- [Урок 2: Тестування FunC для смарт-контракту] (https://github.com/romanovichim/TonFunClessons_Eng/blob/main/lessons/smartcontract/2lesson/secondlesson.md) +- [TON Hello World частина 4: Покрокове керівництво для тестування вашого першого смарт-контракту] (https://ton-community.github.io/tutorials/04-testing/) +- [TON Smart Contract Pipeline](https://dev.to/roma_i_m/ton-smart-contract-pipeline-write-simple-contract-and-compile-it-4pnh) +- \[[YouTube]Шостий урок FunC & Blueprint. Газ, збори, тести]] (https://youtu.be/3XIpKZ6wNcg) + +## Приклади + +Ознайомтеся з наборами тестів, які використовуються для контрактів TON Ecosystem, і навчіться на прикладах. + +- [випробування в пісочниці з рідинно-контрактним підрядом](https://github.com/ton-blockchain/liquid-staking-contract/tree/main/tests) +- [governance_tests](https://github.com/Trinketer22/governance_tests/blob/master/config_tests/tests/) +- [JettonWallet.spec.ts](https://github.com/EmelyanenkoK/modern_jetton/blob/master/tests/JettonWallet.spec.ts) +- [governance_tests](https://github.com/Trinketer22/governance_tests/blob/master/elector_tests/tests/complaint-test.fc) +- [MassSender.spec.ts](https://github.com/Gusarich/ton-mass-sender/blob/main/tests/MassSender.spec.ts) +- [TonForwarder.spec.ts](https://github.com/TrueCarry/ton-contract-forwarder/blob/main/src/contracts/ton-forwarder/TonForwarder.spec.ts) +- [Assurer.spec.ts](https://github.com/aSpite/dominant-assurance-contract/blob/main/tests/Assurer.spec.ts) + +## Дивіться також + +- [Blueprint](/develop/smart-contracts/sdk/javascript) +- [toncli](/develop/smart-contracts/testing/toncli) diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/learn/academy/academy-overview.md b/i18n/uk/docusaurus-plugin-content-docs/current/learn/academy/academy-overview.md new file mode 100644 index 0000000000..3c8a893907 --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/learn/academy/academy-overview.md @@ -0,0 +1,16 @@ +# Освітні ресурси + +### TON Speedrun + +- [TON Speedrun](https://tonspeedrun.com/) - спеціалізована платформа, призначена для практичного підходу до навчання в розробці TON. + +### Курси + +- [Blockchain Basics with TON](https://stepik.org/course/201294/promo) ([RU версія](https://stepik.org/course/202221/), [CHN версія](https://stepik.org/course/200976/)) - + Цей курс знайомить з основами блокчейну, з особливим акцентом на практичні навички в екосистемі TON. Ви зрозумієте, як функціонує блокчейн та його різноманітні застосування. + +## Дивіться також + +- [Speedrun TON](https://tonspeedrun.com/) +- [TON Hello World] (https://tonhelloworld.com/01-wallet/) +- [[YouTube] TON Dev Study EN] (https://www.youtube.com/@TONDevStudy) [[RU]] (https://www.youtube.com/results?search_query=tondevstudy) diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/learn/introduction.mdx b/i18n/uk/docusaurus-plugin-content-docs/current/learn/introduction.mdx new file mode 100644 index 0000000000..e1f842e25b --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/learn/introduction.mdx @@ -0,0 +1,81 @@ +import Player from '@site/src/components/player' +import Button from '@site/src/components/button' + +# Відкрита мережа + +Відкрита мережа (TON) - це децентралізована і відкрита інтернет-платформа, що складається з декількох компонентів. До них відносяться: Блокчейн TON, DNS TON, сховище TON і сайти TON. Блокчейн TON - це основний протокол, який з'єднує базову інфраструктуру TON разом, щоб сформувати велику екосистему TON. + +TON орієнтований на досягнення широкої міжмережевої інтероперабельності, працюючи у високомасштабованій безпечній платформі. TON призначена для обробки мільйонів транзакцій в секунду (TPS), з метою охоплення сотень мільйонів користувачів, які рухаються вперед. + +Блокчейн розроблений як розподілений суперкомп'ютер, або "суперсервер", призначений для надання різноманітних продуктів і послуг, що сприятимуть розвитку децентралізованого бачення нового інтернету. + +- Дізнайтеся, які послуги ТОН надає своїм користувачам, переглянувши цей розділ: [Взяти участь у TON] (/участі/) +- Щоб дізнатися більше про технічні аспекти TON Blockchain, перегляньте [Блокчейн з блокчейнів] (/learn/overviews/ton-blockchain) +- Дізнайтеся більше про розробку всього, що стосується TON, переглянувши цей розділ: [Початок роботи] (/develop/oview) + +## Огляд з висоти пташиного польоту + +Щоб зрозуміти справжнє бачення децентралізованого інтернету і те, як TON сприяє цій неминучості, подивіться відео нижче: + + + +## Основи блокчейну з TON + +Цей курс знайомить з основами блокчейну, з особливим акцентом на практичні навички роботи в екосистемі TON. Ви зрозумієте, як функціонує блокчейн та його різноманітні застосування. Ви також отримаєте важливі навички, пов'язані з TON, включаючи налаштування гаманця, торгівлю NFT, створення Jetton і транзакції з монетами TON на децентралізованих біржах (DEX). Курс також забезпечить вас критично важливими знаннями про криптовалютні загрози та шахрайство і дасть практичні поради, як захистити свої криптовалютні активи. + +- [Blockchain Basics with TON](https://stepik.org/course/201294/) ([RU версія](https://stepik.org/course/202221/), [CHN версія](https://stepik.org/course/200976/)) + +## Курс TON Blockchain + +Ми з гордістю представляємо вам курс **TON Blockchain Course**, який є вичерпним посібником з блокчейну TON. Курс призначений для розробників, які хочуть навчитися створювати смарт-контракти та децентралізовані додатки на блокчейні TON. + +Він складається з **9 модулів** і охоплює основи блокчейну TON, мови програмування FunC та віртуальної машини TON (TVM). + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Новачок в блокчейні? + +Якщо ви не знайомі з блокчейном і не розумієте, що робить цю технологію такою революційною, подумайте про те, щоб глибоко зануритися в ці важливі ресурси: + +- [Що таке блокчейн? Що таке смарт-контракт? Що таке газ?] (https://blog.ton.org/what_is_blockchain) +- [Як блокчейн може допомогти вам на безлюдному острові] (https://talkol.medium.com/why-decentralized-consensus-blockchain-is-good-for-business-5ff263468210) +- [\[YouTube\] Криптографічні мережі і чому вони важливі] (https://youtu.be/2wxtiNgXBaU) + +## Відносини TON з Ethereum + +Для тих, хто знайомий з розробкою Ethereum, ми написали дві вступні статті, які допоможуть вам зрозуміти, що відрізняє TON в цьому відношенні: + +- [Шість унікальних аспектів блокчейну TON, які здивують розробників Solidity] (https://blog.ton.org/six-unique-aspects-of-ton-blockchain-that-will-surprise-solidity-developers) +- [Час спробувати щось нове: Асинхронні смарт-контракти] (https://telegra.ph/Its-time-to-try-something-new-Asynchronous-smart-contracts-03-25) +- [Порівняння блокчейнів] (https://ton.org/comparison_of_blockchains.pdf) diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/learn/networking/overview.md b/i18n/uk/docusaurus-plugin-content-docs/current/learn/networking/overview.md new file mode 100644 index 0000000000..0b8b537b61 --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/learn/networking/overview.md @@ -0,0 +1,19 @@ +# TON Networking + +Проект TON використовує власні пірингові мережеві протоколи. + +- **Блокчейн використовує ці протоколи** для розповсюдження нових блоків, надсилання та отримання кандидатів на транзакції тощо. + + У той час як мережеві вимоги одноблочних проектів, таких як Bitcoin або Ethereum, можна задовольнити досить легко (потрібно лише побудувати + однорангову оверлейну мережу, а потім поширювати всі нові блоки і + кандидатів на транзакції за допомогою протоколу [gossip](https://en.wikipedia.org/wiki/Gossip_protocol)), багатоблочні проекти, такі + як TON, набагато вимогливіші (наприклад, потрібно мати можливість + підписатися на оновлення лише деяких шардчейнів, а не обов'язково на всі). + +- **Екосистемні послуги TON (наприклад, TON Proxy, TON Sites, TON Storage) працюють на основі цих протоколів.**. + + Як тільки більш складні мережеві протоколи, необхідні + для підтримки блокчейну TON, будуть створені, виявиться, що їх можна легко + використовувати для цілей, не обов'язково пов'язаних з безпосередніми потребами самого + блокчейну, таким чином надаючи більше можливостей і гнучкості для створення + нових послуг в екосистемі TON. diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/learn/overviews/addresses.md b/i18n/uk/docusaurus-plugin-content-docs/current/learn/overviews/addresses.md new file mode 100644 index 0000000000..946eb904d7 --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/learn/overviews/addresses.md @@ -0,0 +1,220 @@ +# Адреси смарт-контрактів + +У цьому розділі буде описано специфіку адрес смарт-контрактів у блокчейні TON. Він також пояснить, як актори є синонімами смарт-контрактів на TON. + +## Все - це смарт-контракт + +На TON смарт-контракти будуються за допомогою [моделі актора] (/learn/overviews/ton-blockchain#single-actor). Фактично, актори в TON технічно представлені як смарт-контракти. Це означає, що навіть ваш гаманець є простим актором (і смарт-контрактом). + +Зазвичай актори обробляють вхідні повідомлення, змінюють свій внутрішній стан і в результаті генерують вихідні повідомлення. Ось чому кожен актор (тобто смарт-контракт) в блокчейні TON повинен мати адресу, щоб мати можливість отримувати повідомлення від інших акторів. + +:::info ДОСВІД EVM +У віртуальній машині Ethereum (EVM) адреси повністю відокремлені від смарт-контрактів. Ви можете дізнатися більше про відмінності, прочитавши нашу статтю ["Шість унікальних аспектів TON Blockchain, які здивують розробників Solidity"] (https://blog.ton.org/six-unique-aspects-of-ton-blockchain-that-will-surprise-solidity-developers), автор - Тал Кол. +::: + +## Адреса смарт-контракту + +Адреси смарт-контрактів, що працюють на TON, зазвичай складаються з двох основних компонентів: + +- **(workchain_id)**: позначає ідентифікатор робочого ланцюжка (знакове 32-бітне ціле число) + +- **(account_id)** позначає адресу облікового запису (64-512 біт, залежно від ланцюжка) + +У розділі огляду сирих адрес цієї документації ми обговоримо, як виглядають пари **(workchain_id, account_id)**. + +### Ідентифікатор ланцюжка та ідентифікатор облікового запису + +#### Ідентифікатор ланцюжка + +[Як ми бачили раніше (/learn/overviews/ton-blockchain#workchain-blockchain-with-your-own-rules), можна створити цілих `2^32` робочих ланцюжків, що працюють на TON Blockchain. Ми також звернули увагу на те, як 32-розрядні префіксні адреси смарт-контрактів ідентифікуються і пов'язуються з адресами смарт-контрактів в різних ланцюжках. Це дозволяє смарт-контрактам відправляти і отримувати повідомлення до і від різних ланцюжків в TON Blockchain. + +На сьогоднішній день в блокчейні TON працює лише майстер-ланцюг (workchain_id=-1) та іноді основний ланцюг (workchain_id=0). + +Обидва вони мають 256-бітові адреси, тому ми припускаємо, що ідентифікатор workchain_id дорівнює або 0, або -1, а адреса всередині ланцюжка має точно 256 біт. + +#### Ідентифікатор облікового запису + +Всі ідентифікатори облікових записів на TON використовують 256-бітові адреси в Masterchain і Basechain (або базовому ланцюжку). + +Фактично, ідентифікатор облікового запису **(account_id)** визначається як хеш-функція для об'єктів смарт-контракту (зокрема, SHA-256). Кожен смарт-контракт, що працює на блокчейні TON, зберігає два основних компоненти. До них відносяться: + +1. Скомпільований код. Логіка смарт-контракту, скомпільована у вигляді байт-коду. +2. Початковий стан. Значення контракту на момент його розгортання в ланцюжку. + +Нарешті, щоб точно отримати адресу контракту, необхідно обчислити хеш, що відповідає парі **(Початковий код, Початковий стан)** об'єкта. Наразі ми не будемо заглиблюватися в те, як працює [TVM](/learn/tvm-instructions/tvm-overview), але важливо розуміти, що ідентифікатори облікових записів на TON визначаються за такою формулою: +: +**account_id = hash(початковий код, початковий стан)**. + +Згодом, в цій документації, ми зануримося глибше в технічні характеристики і огляд схеми TVM і TL-B. Тепер, коли ми ознайомилися з генерацією **account_id** і їх взаємодією з адресами смарт-контрактів на TON, давайте пояснимо, що таке Raw і User-Friendly адреси. + +## Стан адреси + +Кожна адреса може перебувати в одному з можливих станів: + +- `неіснуючий` - за цією адресою не було жодної прийнятої транзакції, тому вона не має жодних даних (або договір було видалено). Можна сказати, що спочатку всі2256 адрес знаходяться в цьому стані. +- `uninit` - адреса має деякі дані, які містять баланс і метаінформацію. У цьому стані адреса ще не має коду смарт-контракту/постійних даних. Адреса переходить в цей стан, наприклад, коли її не існувало, а якась інша адреса надіслала на неї токени. +- `активний` - адреса має код смарт-контракту, постійні дані та баланс. У цьому стані вона може виконувати певну логіку під час транзакції та змінювати свої постійні дані. Адреса переходить в цей стан, коли вона була `uninit` і було вхідне повідомлення з параметром state_init (зверніть увагу, що для розгортання цієї адреси хеш `state_init` і `code` повинен бути рівним адресі). +- `frozen` - адреса не може виконувати жодних операцій, цей стан містить лише два хеші попереднього стану (комірку коду та комірку стану відповідно). Коли витрати на зберігання адреси перевищують її баланс, вона переходить у цей стан. Щоб розморозити його, ви можете відправити внутрішнє повідомлення з `state_init` і `code`, які зберігають хеші, описані раніше, і трохи Toncoin. Відновити його може бути складно, тому не варто допускати такої ситуації. Існує проект для розморожування адреси, який ви можете знайти [тут] (https://unfreezer.ton.org/). + +## Сирі та зручні для користувача адреси + +Після короткого огляду того, як адреси смарт-контрактів в ланцюжках ланцюжків і ідентифікаторів облікових записів TON (зокрема, для Masterchain і Basechain), важливо розуміти, що ці адреси виражаються в двох основних форматах: + +- **Сирі адреси**: Оригінальне повне представлення адрес смарт-контрактів. +- **Зручні адреси**: Зручні для користувача адреси - це покращений формат сирої адреси, який забезпечує кращу безпеку та простоту використання. + +Нижче ми пояснимо відмінності між цими двома типами адрес і зануримося глибше в те, чому в TON використовуються зручні для користувача адреси. + +### Сира адреса + +Сирі адреси смарт-контрактів складаються з ідентифікатора ланцюжка і ідентифікатора облікового запису *(workchain_id, account_id)* і відображаються в наступному форматі: + +- [десятковий ідентифікатор_ланцюга\]:[64 шістнадцяткових цифри з ідентифікатором_рахунку\] + +Нижче наведено приклад необробленої адреси смарт-контракту з використанням ідентифікатора ланцюжка і ідентифікатора облікового запису разом (у вигляді **workchain_id** і **account_id**): + +`-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260` + +Зверніть увагу на `-1` на початку адресного рядка, який позначає ідентифікатор *workchain_id*, що належить до майстер-ланцюга. + +:::note +В адресних рядках можна використовувати великі літери (наприклад, 'A', 'B', 'C', 'D' і т.д.) замість малих (наприклад, 'a', 'b', 'c', 'd' і т.д.). +::: + +#### Проблеми з необробленими адресами + +Використання форми Raw Address пов'язане з двома основними проблемами: + +1. При використанні формату "сирої" адреси неможливо перевірити адреси для усунення помилок перед відправленням транзакції. + Це означає, що якщо ви випадково додасте або видалите символи в адресному рядку перед відправленням транзакції, ваша транзакція буде відправлена не за адресою призначення, що призведе до втрати коштів. +2. При використанні формату сирої адреси неможливо додати спеціальні прапори, подібні до тих, що використовуються при надсиланні транзакцій, які використовують зручні для користувача адреси. + Щоб допомогти вам краще зрозуміти цю концепцію, нижче ми пояснимо, які прапори можна використовувати. + +### Зручна для користувача адреса + +Зручні адреси були розроблені для того, щоб убезпечити і спростити роботу користувачів TON, які обмінюються адресами в Інтернеті (наприклад, на платформах обміну повідомленнями або через своїх постачальників послуг електронної пошти), а також в реальному світі. + +#### Зручна для користувача адресна структура + +Зручні для користувача адреси складаються загалом з 36 байт і отримуються шляхом генерації наступних компонентів по порядку: + +1. *[прапори - 1 байт]* - Прапори, які прив'язуються до адрес, змінюють спосіб реагування смарт-контрактів на отримане повідомлення. + Типи прапорів, які використовують зручний для користувача формат адреси, включають наступні: + + - isBounceable. Позначає тип адреси, що підлягає або не підлягає поверненню. (*0x11* для "bounceable", *0x51* для "non-bounceable") + - isTestnetOnly. Позначає тип адреси, який використовується лише для цілей тестової мережі. Адреси, що починаються з *0x80*, не повинні прийматися програмним забезпеченням, що працює у виробничій мережі + - isUrlSafe. Позначає застарілий прапорець, який визначає адресу як URL-безпечну. Після цього всі адреси вважаються URL-безпечними. +2. *\[workchain_id - 1 байт]* - Ідентифікатор ланцюжка (*workchain_id*) визначається знаковим 8-бітним цілим числом *workchain_id*.\ + (*0x00* для BaseChain, *0xff* для MasterChain) +3. *\[account_id - 32 byte]* - Ідентифікатор облікового запису складається з ([big-endian](https://www.freecodecamp.org/news/what-is-endianness-big-endian-vs-little-endian/)) 256-бітної адреси в робочому ланцюжку. +4. *\[перевірка адреси - 2 байти]* - У зручних для користувача адресах перевірка адреси складається з підпису CRC16-CCITT з попередніх 34 байт. ([Приклад](https://github.com/andreypfau/ton-kotlin/blob/ce9595ec9e2ad0eb311351c8a270ef1bd2f4363e/ton-kotlin-crypto/common/src/crc32.kt)) + Насправді, ідея перевірки для зручних для користувача адрес дуже схожа на [алгоритм Луна](https://en.wikipedia.org/wiki/Luhn_algorithm), який використовується на всіх кредитних картках, щоб запобігти помилковому введенню користувачами неіснуючих номерів карток. + +Додавання цих 4 основних компонентів означає, що `1 + 1 + 32 + 2 = 36` байт загалом (на одну зручну для користувача адресу). + +Щоб згенерувати зручну для користувача адресу, розробник повинен закодувати всі 36 байт, використовуючи будь-яку з них: + +- *base64* (тобто з цифрами, великими та малими латинськими літерами, символами '/' та '+') +- *base64url* (з '_' та '-' замість '/' та '+') + +Після завершення цього процесу завершується генерація зручної для користувача адреси довжиною 48 символів без пробілів. + +:::info ПРАПОРИ DNS-АДРЕС +У домені TON DNS-адреси, такі як mywallet.ton, іноді використовуються замість сирих і зручних для користувача адрес. Насправді DNS-адреси складаються зі зручних для користувача адрес і включають всі необхідні прапори, які дозволяють розробникам отримати доступ до всіх прапорів з DNS-запису в домені TON. +::: + +#### Зручні для користувача приклади кодування адрес + +Наприклад, смарт-контракт "test giver" (спеціальний смарт-контракт, що знаходиться в майстер-ланцюжку testnet і надсилає 2 тестових токени кожному, хто їх запитує) використовує наступну сиру адресу: + +`-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260` + +Наведена вище сира адреса "постачальника тесту" має бути перетворена у зручну для користувача адресну форму. Це можна зробити за допомогою форм base64 або base64url (які ми розглядали раніше) наступним чином: + +- `kf/8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15+KsQHFLbKSMiYIny` (base64) +- `kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny` (base64url) + +:::info +Зверніть увагу, що обидві форми (*base64* і *base64url*) є дійсними і повинні бути прийняті! +::: + +#### Відновлювані та невідновлювані адреси + +Основна ідея прапорця bounceable address - це безпека коштів відправника. + +Наприклад, якщо смарт-контракт призначення не існує, або якщо під час транзакції виникне якась проблема, повідомлення буде "повернуто" відправнику і становитиме залишок початкової вартості транзакції (за вирахуванням всіх комісій за переказ і газ). Це гарантує, що відправник не втратить свої кошти, які були випадково надіслані на адресу, яка не може прийняти транзакцію. + +Зокрема, це стосується адрес, які можуть бути ретрансльованими: + +1. Прапор **bounceable=false** зазвичай означає, що отримувач є гаманцем. +2. Прапорець **bounceable=true** зазвичай позначає кастомний смарт-контракт з власною прикладною логікою (наприклад, DEX). У цьому прикладі з міркувань безпеки не слід надсилати повідомлення, що не відбиваються. + +Не соромтеся читати більше на цю тему в нашій документації, щоб краще зрозуміти [повідомлення, що не відскакують] (/develop/smart-contracts/guidelines/non-bouncable-messages). + +#### Броньовані представлення base64 + +Додаткові двійкові дані, пов'язані з блокчейном TON, використовують подібні "броньовані" зручні для користувача представлення адрес у форматі Base64. Вони відрізняються один від одного в залежності від перших 4 символів їх байтового тегу. Наприклад, 256-бітові публічні ключі Ed25519 представляються шляхом створення 36-байтової послідовності, використовуючи описаний нижче процес: + +- Однобайтовий тег у форматі *0x3E* позначає відкритий ключ +- Однобайтовий тег у форматі *0xE6* позначає відкритий ключ Ed25519 +- 32 байти, що містять стандартне двійкове представлення відкритого ключа Ed25519 +- 2 байти, що містять представлення CRC16-CCITT у великій системі числення попередніх 34 байт + +Отримана 36-байтна послідовність перетворюється в 48-символьний рядок base64 або base64url стандартним способом. Наприклад, відкритий ключ Ed25519 `E39ECDA0A7B0C60A7107EC43967829DBE8BC356A49B9DFC6186B3EAC74B5477D` (зазвичай представлений послідовністю з 32 байт, наприклад `0xE3, 0x9E, ..., 0x7D`) через "броньоване" представлення виглядає наступним чином: + +`Pubjns2gp7DGCnEH7EOWeCnb6Lw1akm538YYaz6sdLVHfRB2`. + +### Перетворення зручних для користувача адрес і сирих адрес + +Найпростіший спосіб перетворення зручних для користувача та необроблених адрес - це використання одного з декількох API TON та інших інструментів, зокрема: + +- [ton.org/address](https://ton.org/address) +- [dton.io API method](https://dton.io/api/address/0:867ac2b47d1955de6c8e23f57994fad507ea3bcfe2a7d76ff38f29ec46729627) +- [методи API toncenter у mainnet](https://toncenter.com/api/v2/#/accounts/pack_address_packAddress_get) +- [методи API toncenter у testnet](https://testnet.toncenter.com/api/v2/#/accounts/pack_address_packAddress_get) + +Крім того, існує два способи перетворення зручних і необроблених адрес гаманців за допомогою JavaScript: + +- [Перетворення адреси з/в зручну для користувача або необроблену форму за допомогою ton.js](https://github.com/ton-org/ton-core/blob/main/src/address/Address.spec.ts) +- [Перетворення адреси з/в зручну для користувача або необроблену форму за допомогою tonweb](https://github.com/toncenter/tonweb/tree/master/src/utils#address-class) + +Також можна скористатися подібними механізмами за допомогою [SDK] (/develop/dapps/apis/sdk). + +### Приклади адрес + +Дізнайтеся більше прикладів про адреси TON у [Кулінарній книзі TON] (/develop/dapps/cookbook#working-with-contracts-addresses). + +## Можливі проблеми + +При взаємодії з блокчейном TON дуже важливо розуміти наслідки переказу монет TON на адреси гаманців "uninit". У цьому розділі описані різні сценарії та їх результати, щоб забезпечити ясність щодо того, як обробляються такі транзакції. + +### Що відбувається, коли ви переводите Toncoin на адресу юніта? + +#### Транзакція з включеним \`state_init + +Якщо ви додаєте `state_init` (який складається з коду і даних гаманця або смарт-контракту) до своєї транзакції. Смарт-контракт спочатку розгортається з використанням наданого `state_init`. Після розгортання, вхідне повідомлення обробляється, подібно до відправки на вже ініціалізований акаунт. + +#### Транзакція без встановлених прапорів `state_init` та `bounce` + +Повідомлення не може бути доставлене до смарт-контракту `uninit`, і воно буде повернуте назад відправнику. Після вирахування плати за спожитий газ сума, що залишилася, повертається на адресу відправника. + +#### Транзакція без встановлених прапорів `state_init` та `bounce` + +Повідомлення не може бути доставлене, але воно не повернеться до відправника. Замість цього відправлена сума буде зарахована на адресу одержувача, збільшуючи його баланс, навіть якщо гаманець ще не ініціалізований. Вони зберігатимуться там доти, доки власник адреси не розгорне контракт смарт-гаманця, і тоді він зможе отримати доступ до балансу. + +#### Як це зробити правильно + +Найкращий спосіб розгорнути гаманець - це надіслати на його адресу (яка ще не ініціалізована) TON зі скинутим прапорцем `bounce`. Після цього кроку власник може розгорнути та ініціалізувати гаманець, використовуючи кошти за поточною неініціалізованою адресою. Цей крок зазвичай відбувається при першій операції з гаманцем. + +### У блокчейні TON реалізовано захист від помилкових транзакцій + +У блокчейні TON стандартні гаманці та додатки автоматично керують складнощами транзакцій на неініціалізовані адреси, використовуючи bounceable і non-bounceable адреси, які описані [тут] (#bounceable-vs-non-bounceable-addresses). Загальноприйнятою практикою для гаманців при відправці монет на неініціалізовані адреси є відправка монет як на bounceable, так і на non-bounceable адреси без повернення. + +Якщо є потреба швидко отримати адресу в bounceable/non-bounceable формі, це можна зробити [тут](https://ton.org/address/). + +### Відповідальність за кастомні продукти + +Якщо ви розробляєте власний продукт на блокчейні TON, важливо реалізувати подібні перевірки та логіку: + +Переконайтеся, що ваш додаток перевіряє, чи ініціалізовано адресу одержувача перед відправленням коштів. +На основі стану адреси використовуйте адреси з можливістю повернення для користувацьких смарт-контрактів зі спеціальною логікою додатку, щоб гарантувати повернення коштів. Для гаманців використовуйте адреси, що не повертаються. diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/learn/overviews/cells.md b/i18n/uk/docusaurus-plugin-content-docs/current/learn/overviews/cells.md new file mode 100644 index 0000000000..fd0e0db909 --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/learn/overviews/cells.md @@ -0,0 +1,52 @@ +# Клітини як сховище даних + +Все в TON зберігається в комірках. Комірка - це структура даних, що містить: + +- до **1023 біт** даних (не байт!) +- до **4 посилань** на інші комірки + +Біти та посилання не змішуються (вони зберігаються окремо). Циклічні посилання заборонені: для будь-якої комірки жодна з її нащадків не може мати цю початкову комірку як посилання. + +Таким чином, всі клітинки утворюють орієнтовний ациклічний граф (ОАГ). Ось гарний малюнок для ілюстрації: + +![Спрямований ациклічний графік](/img/docs/dag.png) + +## Типи клітин + +Наразі існує 5 типів клітин: *звичайні* та 4 *екзотичні*. +До екзотичних відносяться наступні типи: + +- Обрізана комірка гілки +- Комірка посилання на бібліотеку +- Комірка Меркле, стійка до впливу вологи +- Комірка оновлення Merkle + +:::tip +Детальніше про екзотичні клітини див: [**ТВМ Whitepaper, розділ 3**] (https://ton.org/tvm.pdf). +::: + +## Клітинні ароматизатори + +Комірка - це непрозорий об'єкт, оптимізований для компактного зберігання. + +Зокрема, вона дедублює дані: якщо є кілька еквівалентних підкомірок, на які є посилання в різних гілках, їхній вміст зберігається лише один раз. Однак, непрозорість означає, що комірку не можна змінювати або читати безпосередньо. Таким чином, з'являється 2 додаткових смаки комірок: + +- *Builder* для частково сконструйованих комірок, для яких можна визначити швидкі операції додавання бітових рядків, цілих чисел, інших комірок та посилань на інші комірки. +- *Slice* для "розрізаних" комірок, що представляють або залишок частково розібраної комірки, або значення (підкомірку), що знаходиться всередині такої комірки і витягнуте з неї за допомогою інструкції синтаксичного аналізу. + +Ще один особливий клітинний аромат використовується в TVM: + +- Продовження_ для комірок, що містять операційні коди (інструкції) для віртуальної машини TON, див. [Огляд TVM з висоти пташиного польоту](/learn/tvm-instructions/tvm-oview). + +## Серіалізація даних у комірки + +Будь-який об'єкт в TON (повідомлення, черга повідомлень, блок, стан всього блокчейну, код контракту і дані) серіалізується в комірку. + +Процес серіалізації описується схемою TL-B: формальним описом того, як цей об'єкт можна серіалізувати у *Builder* або як розібрати об'єкт заданого типу з *Slice*. +TL-B для комірок - це те саме, що TL або ProtoBuf для байтових потоків. + +Якщо ви хочете дізнатися більше про (де)серіалізацію комірок, ви можете прочитати статтю [Cell & Bag of Cells](/develop/data-formats/cell-boc). + +## Дивіться також + +- [Мова TL-B](/develop/data-formats/tl-b-language) diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/learn/overviews/ton-blockchain.md b/i18n/uk/docusaurus-plugin-content-docs/current/learn/overviews/ton-blockchain.md new file mode 100644 index 0000000000..2351cace2b --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/learn/overviews/ton-blockchain.md @@ -0,0 +1,72 @@ +# Блокчейн з блокчейнів + +:::tip +Терміни "**розумний контракт**", "**рахунок**" і "**актор**" використовуються в цьому документі як взаємозамінні для опису об'єкта блокчейну. +::: + +## Один актор + +Розглянемо один смарт-контракт. + +У ТОН це *речовина* з такими властивостями, як *адреса*, *код*, *дані*, *баланс* та інші. Іншими словами, це об'єкт, який має певне *зберігання* та *поведінку*. +Ця поведінка має наступний шаблон: + +- щось трапляється (найпоширеніша ситуація - коли контракт отримує повідомлення) +- контракт обробляє цю подію відповідно до своїх властивостей, виконуючи її "код" у віртуальній машині TON. +- контракт змінює власні властивості (`код`, `дані` та інші) +- контракт опціонально генерує вихідні повідомлення +- контракт переходить у режим очікування до наступної події + +Комбінація цих кроків називається **транзакцією**. Важливо, що події обробляються одна за одною, тому *транзакції* суворо впорядковані і не можуть переривати одна одну. + +Ця модель поведінки добре відома і називається "актор". + +### Найнижчий рівень: Ланцюжок рахунків + +Послідовність *транзакцій* `Tx1 -> Tx2 -> Tx3 -> ....` можна назвати **ланцюжком**. А в розглянутому випадку вона називається **AccountChain**, щоб підкреслити, що це *ланцюжок* одного облікового запису транзакцій. + +Тепер, оскільки вузлам, які обробляють транзакції, потрібно час від часу координувати стан смарт-контракту (досягати *консенсусу* щодо стану), ці *транзакції* пакетуються: +`[Tx1 -> Tx2] -> [Tx3 -> Tx4 -> Tx5] -> [] -> [Tx6]`. +Пакетна передача не втручається у послідовність, кожна транзакція все ще має лише один 'prev tx' і максимум один 'next tx', але тепер ця послідовність розрізана на **блоки**. + +Доцільно також включити до *блоків* черги вхідних та вихідних повідомлень. В такому випадку *блок* буде містити повний набір інформації, яка визначає і описує, що відбувалося зі смарт-контрактом протягом цього блоку. + +## Багато ланцюжків акаунтів: Осколки + +Тепер розглянемо багато акаунтів. Ми можемо отримати декілька *AccountChains* і зберігати їх разом, такий набір *AccountChains* називається **ShardChain**. Так само ми можемо розрізати **ShardChain** на **ShardBlocks**, які є сукупністю окремих *AccountBlocks*. + +### Динамічне розділення та злиття ShardChains + +Зауважте, що оскільки *ShardChain* складається з *AccountChains*, які легко розрізнити, ми можемо легко його розділити. Таким чином, якщо у нас є 1 *ShardChain*, який описує події, що відбуваються з 1 мільйоном акаунтів, і кількість транзакцій в секунду занадто велика, щоб обробляти і зберігати їх в одному вузлі, ми просто розділимо (або **розщепимо**) цей ланцюжок на два менших *ShardChains*, кожен з яких відповідає за півмільйона акаунтів, і кожен ланцюжок обробляється на окремій підмножині вузлів. + +Аналогічно, якщо деякі осколки стали занадто вільними, їх можна "об'єднати" в один більший осколок. + +Очевидно, що існує два граничних випадки: коли шард містить лише один обліковий запис (і тому не може бути розділений далі) і коли шард містить всі облікові записи. + +Акаунти можуть взаємодіяти один з одним, надсилаючи повідомлення. Існує спеціальний механізм маршрутизації, який переміщує повідомлення з вихідних черг до відповідних вхідних черг і гарантує, що 1) всі повідомлення будуть доставлені 2) повідомлення будуть доставлені послідовно (повідомлення, відправлене раніше, досягне адресата раніше). + +:::info ПРИМІТКА +Щоб зробити розділення та злиття детермінованим, агрегація ланцюжків облікових записів у шарди базується на бітовому представленні адрес облікових записів. Наприклад, адреса має вигляд `(префікс шарда, адреса)`. Таким чином, всі акаунти в шардчейні матимуть однаковий двійковий префікс (наприклад, всі адреси починаються з `0b00101`). +::: + +## Блокчейн + +Сукупність всіх шардів, яка містить всі облікові записи, що діють за одним набором правил, називається **Блокчейном**. + +У TON може бути багато наборів правил і, відповідно, багато блокчейнів, які працюють одночасно і можуть взаємодіяти один з одним, надсилаючи повідомлення між ланцюжками так само, як акаунти одного ланцюжка можуть взаємодіяти один з одним. + +### Workchain: Блокчейн з власними правилами + +Якщо ви хочете налаштувати правила групи шардчейнів, ви можете створити **Workchain**. Хорошим прикладом є створення ланцюжка, який працює на базі EVM, щоб запускати на ньому смарт-контракти Solidity. + +Теоретично, кожен учасник спільноти може створити власний воркчейн. Насправді, це досить складне завдання - побудувати його, потім заплатити (дорогу) ціну за створення і отримати 2/3 голосів від валідаторів, щоб схвалити створення вашого ланцюжка. + +TON дозволяє створювати до `2^32` робочих ланцюжків, кожен з яких розбивається на `2^60` осколків. + +На сьогоднішній день в TON існує лише 2 робочі ланцюги: MasterChain та BaseChain. + +BaseChain використовується для повсякденних транзакцій між учасниками, оскільки він досить дешевий, в той час як MasterChain виконує важливу функцію для TON, тому давайте розглянемо, що він робить! + +### Masterchain: Блокчейн з блокчейнів + +Існує необхідність синхронізації маршрутизації повідомлень і виконання транзакцій. Іншими словами, вузлам мережі потрібен спосіб зафіксувати певну "точку" в багатоланцюговому стані і досягти консенсусу щодо цього стану. У TON для цього використовується спеціальний ланцюжок, який називається **MasterChain**. Блоки *masterchain* містять додаткову інформацію (останні хеші блоків) про всі інші ланцюжки в системі, таким чином, будь-який спостерігач однозначно визначає стан всіх мультиланцюжкових систем за одним блоком майстер-ланцюга. diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/learn/tvm-instructions/tvm-overview.mdx b/i18n/uk/docusaurus-plugin-content-docs/current/learn/tvm-instructions/tvm-overview.mdx new file mode 100644 index 0000000000..00d76d5b3e --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/learn/tvm-instructions/tvm-overview.mdx @@ -0,0 +1,133 @@ +import Button from '@site/src/components/button' + +# Огляд TVM + +Всі смарт-контракти TON виконуються на власній віртуальній машині TON (TVM). TVM побудована за принципом "стека", що робить її ефективною і простою в реалізації. + +Цей документ дає уявлення про те, як TVM виконує транзакції з висоти пташиного польоту. + +:::tip + +- TVM Source - [**TVM C++ реалізація**](https://github.com/ton-blockchain/ton/tree/master/crypto/vm) + ::: + +## Курс TON: TVM + +:::tip +Перед початком курсу переконайтеся, що ви добре розумієте основи технології блокчейн. Якщо у вас є прогалини в знаннях, рекомендуємо пройти курс [Blockchain Basics with TON](https://stepik.org/course/201294/promo) ([RU версія](https://stepik.org/course/202221/), [CHN версія](https://stepik.org/course/200976/)). +::: + +Курс [TON Blockchain Course] (https://stepik.org/course/176754/) - це вичерпний посібник з розробки TON Blockchain. + +Модуль 2 повністю охоплює **TVM**, транзакції, масштабування та бізнес-кейси. + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Транзакції та етапи + +Коли на акаунті в одному з ланцюжків TON відбувається якась подія, вона викликає **транзакцію**. Найпоширенішою подією є "надходження якогось повідомлення", але, взагалі кажучи, це можуть бути "тик-так", "злиття", "розщеплення" та інші події. + +Кожна транзакція складається з 5 етапів: + +1. **Фаза зберігання** - на цій фазі розраховується плата за зберігання, накопичена контрактом через зайняття певного місця в стані ланцюжка. Детальніше в [Плата за зберігання] (/develop/smart-contracts/fees#storage-fee). +2. **Фаза кредитування** - на цій фазі розраховується баланс контракту щодо (можливої) вартості вхідного повідомлення і стягнутої плати за зберігання. +3. **Фаза обчислення** - на цій фазі TVM виконує контракт (див. нижче) і результатом виконання контракту є сукупність реквізитів `exit_code`, `actions` (серіалізований список дій), `gas_details`, `new_storage` та деяких інших. +4. **Фаза дій** - якщо фаза обчислень пройшла успішно, в цій фазі обробляються "дії" з фази обчислень. Зокрема, дії можуть включати відправку повідомлень, оновлення коду смарт-контракту, оновлення бібліотек тощо. Зауважте, що деякі дії можуть зазнати невдачі під час обробки (наприклад, якщо ми спробуємо відправити повідомлення з більшим TON, ніж є в контракті), в такому випадку вся транзакція може повернутися назад або ця дія може бути пропущена (це залежить від режиму дій, іншими словами, контракт може відправити повідомлення типу "відправити або повернути" або "спробувати відправити, якщо не буде ігноруватися"). +5. **Фаза відмов** - якщо фаза обчислення завершилася невдало (повернуто `код_виходу >= 2`), у цій фазі формується _повідомлення про відмову_ для транзакцій, ініційованих вхідним повідомленням. + +## Обчислювальна фаза + +На цій фазі відбувається виконання TVM. + +### Стан ТВМ + +У будь-який момент часу стан ТВМ повністю визначається 6 властивостями: + +- Стек (див. нижче) +- Керуючі регістри - (див. нижче), простіше кажучи, це означає до 16 змінних, які можуть бути безпосередньо встановлені та прочитані під час виконання +- Поточне продовження - об'єкт, який описує поточну виконувану послідовність інструкцій +- Поточна кодова сторінка - простими словами, це означає версію TVM, яка запущена в даний момент +- Ліміти газу - набір з 4 цілих значень: поточний ліміт газуgl, максимальний ліміт газу gm, залишок газуgr та кредит газу gc +- Контекст бібліотеки - хеш-мапа бібліотек, які може викликати TVM + +### ТВМ - це штабелеукладальна машина + +TVM - це стекова машина з останнім входом і першим виходом. Всього існує 7 типів змінних, які можна зберігати в стеку, три з яких не є комірками: + +- Ціле - знакові 257-розрядні цілі числа +- Кортеж - впорядкована колекція до 255 елементів з довільними типами значень, які можуть бути різними. +- Нуль. + +І чотири різних смаки клітин: + +- Комірка - базова (можливо, вкладена) непрозора структура, що використовується TON Blockchain для зберігання всіх даних +- Зріз - спеціальний об'єкт, який дозволяє читати з комірки +- Конструктор - спеціальний об'єкт, який дозволяє створювати нові комірки +- Продовження - спеціальний об'єкт, який дозволяє використовувати комірку як джерело інструкцій TVM + +### Регістри управління + +- `c0` - Містить наступне продовження або продовження повернення (подібно до адреси повернення підпрограми у звичайному дизайні). Це значення має бути продовженням. +- `c1` - Містить альтернативне продовження (повернення); це значення має бути Продовженням. +- `c2` - Містить обробник виключення. Це значення є продовженням, яке викликається щоразу, коли виникає виняток. +- `c3` - допоміжний регістр, містить поточний словник, по суті хеш-мапу, що містить код усіх функцій, які використовуються у програмі. Це значення повинно бути продовженням. +- `c4` - Містить корінь постійних даних, або просто розділ контракту `data`. Це значення є коміркою. +- `c5` - Містить дії виведення. Це значення є коміркою. +- `c7` - Містить корінь тимчасових даних. Це кортеж. + +### Ініціалізація TVM + +TVM ініціалізується, коли виконання транзакції доходить до фази обчислень, а потім виконує команди (опкоди) з _Поточного продовження_, поки не залишиться більше команд для виконання (і не буде продовження для переходів назад). + +Детальний опис процесу ініціалізації можна знайти тут: [TVM Ініціалізація](/learn/tvm-instructions/tvm-initialization.md) + +## Інструкція з експлуатації TVM + +Список інструкцій TVM можна знайти тут: [TVM-інструкції](/learn/tvm-instructions/instructions). + +### Результат виконання TVM + +Окрім коду виходу та даних про спожитий газ, TVM опосередковано виводить наступні дані: + +- Регістр c4 - комірка, яка буде збережена як нові "дані" смарт-контракту (якщо виконання не буде повернуто на цій або наступних фазах) +- c5 register - (список вихідних дій) комірка з останньою дією у списку та посилання на комірку з попередньою дією (рекурсивно) + +Всі інші значення регістрів ігноруються. + +Зауважте, що оскільки існує обмеження на максимальну глибину комірок `<1024`, і особливо обмеження на глибину c4 і c5 `<=512`, то буде обмеження на кількість вихідних дій в одному tx `<=255`. Якщо контракту потрібно відправити більше, він може відправити повідомлення із запитом `continue_sending` самому собі і відправити всі необхідні повідомлення у наступних транзакціях. + +## Дивіться також + +- [Інструкції TVM](/learn/tvm-instructions/instructions) +- [TON TVM](https://ton.org/tvm.pdf) Концепції TVM (може містити застарілу інформацію) diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/participate/README.md b/i18n/uk/docusaurus-plugin-content-docs/current/participate/README.md new file mode 100644 index 0000000000..76435705ee --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/participate/README.md @@ -0,0 +1,38 @@ +# Огляд + +Розділ "Участь" нашої документації розроблений таким чином, щоб дозволити користувачам відкрити для себе можливості роботи з TON +Він також має на меті запропонувати основні фреймворки (дослідники, гаманці, TEP), необхідні для участі в екосистемі TON і створення бачення TON для Всесвітньої павутини TON (TWWW). + +## Долучайтеся до екосистеми ТОН + +- [TON Explorers](/учасники/дослідники) +- [Додатки для гаманців (для розробників)] (/participate/wallets/apps) +- [Типи контрактів на гаманці] (/participate/wallets/contracts) + +### Приєднуйтесь до спільноти TON + +- [Пропозиції щодо посилення ТОН (TEPs)] (https://github.com/ton-blockchain/TEPs) +- [Відкрийте для себе інновації TON на сайті TON Research] (https://tonresear.ch/) +- [Ставка з номінаторами TON](/participate/network-maintenance/nominators) + +### Мости + +- [Огляд мостів] (/participate/crosschain/oview) +- [Адреси мостів](/participate/crosschain/bridge-addresses) + +### Запустити вузол + +- [Дізнатися про типи вузлів у TON](/participate/nodes/node-types) +- [Запустити ваш повний вузол або валідатор](/participate/run-nodes/full-node) +- [TON Validator maintenance & security](/participate/nodes/node-maintenance-and-security) + +## Беріть участь у TON Web3 + +- [Огляд TON Web3](/participate/web3/oview) +- [Використовуйте TON DNS для своїх доменів](/participate/web3/dns) +- [Управління сайтом та доменом](/participate/web3/site-management) +- [\[Навчальний посібник\] Як запустити власний TON-сайт?](/develop/dapps/tutorials/how-to-run-ton-site) + +### TON Proxy + +- [Як відкрити будь-який сайт TON?] (/participate/web3/how-to-open-any-ton-site) diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/participate/crosschain/overview.md b/i18n/uk/docusaurus-plugin-content-docs/current/participate/crosschain/overview.md new file mode 100644 index 0000000000..849e77704e --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/participate/crosschain/overview.md @@ -0,0 +1,57 @@ +# Перехресні ланцюгові мости + +Децентралізовані крос-ланцюгові мости працюють на TON Blockchain, дозволяючи переносити активи з TON Blockchain в інші блокчейни і навпаки. + +## Toncoin Bridge + +Міст Toncoin дозволяє переказувати Toncoin між блокчейном TON і блокчейном Ethereum, а також між блокчейном TON і смарт-ланцюжком BNB. + +Мостом керують [децентралізовані оракули](/учасники/кросчейн/адреси мосту). + +### Як ним користуватися? + +Фронтенд мосту розміщений на https://ton.org/bridge. + +:::info +[Вихідний код інтерфейсу мосту](https://github.com/ton-blockchain/bridge) +::: + +### Вихідні коди смарт-контрактів TON-Ethereum + +- [FunC (сторона TON)](https://github.com/ton-blockchain/bridge-func) +- [Solidity (сторона Ethereum)] (https://github.com/ton-blockchain/bridge-solidity/tree/eth_mainnet) + +### Вихідні коди смарт-контрактів TON-BNB Smart Chain + +- [FunC (сторона TON)](https://github.com/ton-blockchain/bridge-func/tree/bsc) +- [Солідність (сторона BSC)] (https://github.com/ton-blockchain/bridge-solidity/tree/bsc_mainnet) + +### Налаштування блокчейну + +Ви можете отримати фактичні адреси мостових смарт-контрактів та адреси оракулів, переглянувши відповідний конфіг: + +TON-Ethereum: [#71](https://github.com/ton-blockchain/ton/blob/35d17249e6b54d67a5781ebf26e4ee98e56c1e50/crypto/block/block.tlb#L738). + +TON-BSC: [#72](https://github.com/ton-blockchain/ton/blob/35d17249e6b54d67a5781ebf26e4ee98e56c1e50/crypto/block/block.tlb#L739). + +ТОН-Полігон: [#73](https://github.com/ton-blockchain/ton/blob/35d17249e6b54d67a5781ebf26e4ee98e56c1e50/crypto/block/block.tlb#L740). + +### Документація + +- [Як працює міст] (https://github.com/ton-blockchain/TIPs/issues/24) + +### Дорожня карта перехресного ланцюга + +- https://t.me/tonblockchain/146 + +## Міст Тонана + +### Як взяти участь? + +:::caution проект\ +Це концептуальна стаття. Ми все ще шукаємо когось досвідченого для її написання. +::: + +Ви можете знайти фронтенд тут: https://tonana.org/ + +Вихідний код знаходиться тут: https://github.com/tonanadao diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/participate/web3/overview.mdx b/i18n/uk/docusaurus-plugin-content-docs/current/participate/web3/overview.mdx new file mode 100644 index 0000000000..4f644f6eef --- /dev/null +++ b/i18n/uk/docusaurus-plugin-content-docs/current/participate/web3/overview.mdx @@ -0,0 +1,17 @@ +# Огляд + +## Концепції + +Більше про ідеї читайте в статті: + +- [Платежі на ТОН] (https://blog.ton.org/ton-payments) +- [TON DNS & Domains](/participate/web3/dns) +- [Сайти TON, TON WWW та TON Proxy](https://blog.ton.org/ton-sites) + +## Варіанти використання + +- [\*.ton зручні домени для будь-якого смарт-контракту](/participate/web3/dns) +- [Підключення до сайтів TON за допомогою проксі-сервера TON](/participate/web3/setting-proxy) +- [Запустіть власний проксі-сервер TON для підключення до сайтів TON](/participate/web3/sites-and-proxy) +- [Прив'яжіть свій гаманець TON або сайт TON до домену] (/participate/web3/site-management) +- [Як створити субдомен за допомогою смарт-контрактів TON DNS](/participate/web3/site-management#how-to-setup-subdomains) From 422332715ec32479cda65cd2478320fd2ae3446e Mon Sep 17 00:00:00 2001 From: sansx Date: Wed, 31 Jul 2024 02:18:55 +0800 Subject: [PATCH 07/41] fix import --- .../current/develop/dapps/asset-processing/jettons.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md b/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md index 4a1dbc400d..dd59b371f8 100644 --- a/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md +++ b/i18n/uk/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/jettons.md @@ -1,6 +1,6 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -import Button from '@site/src/components/utton'; +import Button from '@site/src/components/button'; # Переробка TON Jetton From 3ba9f0ba86aea4f3be134e5ced0ac84a74846539 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 12 Aug 2024 19:07:09 +0800 Subject: [PATCH 08/41] New translations sdk.mdx (Korean) --- .../current/develop/dapps/apis/sdk.mdx | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx new file mode 100644 index 0000000000..34e1a7b420 --- /dev/null +++ b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx @@ -0,0 +1,79 @@ +# SDKs + +선호하는 언어로 빠르게 탐색하려면 오른쪽 사이드바를 사용하세요. + +## 개요 + +블록체인에 연결하는 방법에는 여러 가지가 있습니다: + +1. RPC 데이터 제공자 또는 기타 API: 대부분의 경우, 안정성과 보안에 _의존_해야 합니다. +2. ADNL 연결: [라이트서버](/participate/run-nodes/liteserver)에 연결합니다. 접근할 수 없는 경우도 있지만, 라이브러리에 구현된 특정 수준의 검증을 통해 거짓 정보를 제공할 수 없습니다. +3. Tonlib 바이너리: 라이트서버에 연결하여 모든 장점과 단점을 갖지만, 애플리케이션에 외부에서 컴파일된 동적 로드 라이브러리가 포함됩니다. +4. 오프체인 전용: 이러한 SDK는 셀을 생성하고 직렬화할 수 있으며, 이후 API로 전송할 수 있습니다. + +### TypeScript / JavaScript + +| 라이브러리 | 블록체인 연결 | 설명 | +| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| [ton](https://github.com/ton-org/ton) | RPC ([Orbs](https://www.orbs.com/ton-access/) / [Toncenter](https://toncenter.com/api/v2/) 등) | TON 블록체인에서 dApp 개발을 위한 지갑 래퍼가 있는 편리한 클라이언트 라이브러리 | +| [tonweb](https://github.com/toncenter/tonweb) | RPC ([Orbs](https://www.orbs.com/ton-access/) / [Toncenter](https://toncenter.com/api/v2/) 등) | 최소한의 외부 종속성이 있으며, 프로덕션에서 광범위하게 테스트된 구형 TON JS SDK | +| [tonkite/adnl](https://github.com/tonkite/adnl) | [ADNL](/develop/network/adnl-tcp) 네이티브 / WebSocket | ADNL TypeScript 구현체 | +| [tonutils](https://github.com/thekiba/tonutils) | 네이티브 [ADNL](/develop/network/adnl-tcp) | TON 생태계에서 애플리케이션을 구축하고 상호 작용하기 위한 TypeScript 기반 인터페이스. 네이티브 ADNL 종속성으로 인해 브라우저에서 블록체인 상호 작용에 사용할 수 없습니다. | +| [foton](https://foton.sh/) | RPC ([Orbs](https://www.orbs.com/ton-access/) / [Toncenter](https://toncenter.com/api/v2/) 등) | TON 지갑 및 블록체인과 상호 작용하기 위한 TypeScript 툴킷으로, 기존 솔루션(블루프린트 및 TON Connect)을 하나의 편리한 API | + +### Java + +| 라이브러리 | 블록체인 연결 | 설명 | +| ------------------------------------------ | ----------- | ------------------------------------------------------ | +| [ton4j](https://github.com/neodix42/ton4j) | Tonlib 바이너리 | The Open Network (TON)를 위한 Java SDK | + +### Python + + + +| 라이브러리 | 블록체인 연결 | 설명 | +| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | +| [pytoniq](https://github.com/yungwine/pytoniq) | 네이티브 ADNL | 네이티브 LiteClient 및 기타 ADNL 기반 프로토콜 구현이 포함된 Python SDK | +| [pytoniq-core](https://github.com/yungwine/pytoniq-core) | _오프체인 전용_ | 강력한 무료 전송 Python SDK | +| [pytonlib](https://github.com/toncenter/pytonlib) | Tonlib 바이너리 | TON 모노레포에서 가져온 바이너리 종속성을 사용하는 독립형 Python 라이브러리 | +| [mytonlib](https://github.com/igroman787/mytonlib) | 네이티브 ADNL | The Open Network를 다루기 위한 네이티브 Python SDK 라이브러리 | +| [TonTools](https://github.com/yungwine/TonTools) | RPC ([Orbs](https://www.orbs.com/ton-access/) / [Toncenter](https://toncenter.com/api/v2/) 등) | TON 블록체인과 상호 작용할 수 있는 고수준의 OOP 라이브러리 | +| [tonpy](https://github.com/disintar/tonpy) | 네이티브 ADNL | TON 블록체인과 상호 작용할 수 있는 데이터 구조 및 API를 제공하는 Python 패키지 | +| [tvm_valuetypes](https://github.com/toncenter/tvm_valuetypes) | _오프체인 전용_ | TVM 타입을 다루기 위한 유틸리티 모음 | +| [pytvm](https://github.com/yungwine/pytvm) | _오프체인_ | C++ 표준 에뮬레이터 바인딩을 사용하는 Python TVM 에뮬레이터 | + +### C# + +| 라이브러리 | 블록체인 연결 | 설명 | +| ----------------------------------------------------------------- | ---------------- | -------------------------------------- | +| [TonSdk.NET](https://github.com/continuation-team/TonSdk.NET) | 네이티브 ADNL 또는 RPC | The Open Network를 위한 네이티브 C# SDK | +| [justdmitry/TonLib.NET](https://github.com/justdmitry/TonLib.NET) | Tonlib 바이너리 | TON 모노레포에서 가져온 바이너리 종속성을 사용하는 .NET SDK | + +### Rust + +| 라이브러리 | 블록체인 연결 | 설명 | +| ------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------- | +| [tonlib-rs](https://github.com/ston-fi/tonlib-rs) | Tonlib 바이너리 | TON 모노레포에서 가져온 바이너리 종속성을 사용하는 Rust SDK | +| [getgems-io/ton-grpc](https://github.com/getgems-io/ton-grpc) | Tonlib 바이너리 | tonlibjson에 대한 Rust 바인딩(따라서 TON 모노레포의 바이너리에 종속됨) 및 이를 기반으로 구축된 서비스 | + +### Go + +| 라이브러리 | 블록체인 연결 | 설명 | +| -------------------------------------------------------- | ----------- | --------------------------------- | +| [tonutils-go](https://github.com/xssnick/tonutils-go) | 네이티브 ADNL | TON 블록체인과 상호 작용하기 위한 Golang 라이브러리 | +| [tongo](https://github.com/tonkeeper/tongo) | 네이티브 ADNL | TON 블록체인을 위한 Go 구현 라이브러리 | +| [tonlib-go](https://github.com/ton-blockchain/tonlib-go) | Tonlib 바이너리 | libtonlibjson에 대한 공식 바인딩 | + +### 기타 언어용 SDK + +| 라이브러리 | 언어 | 블록체인 연결 | 설명 | | +| --------------------------------------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | - | +| [ton-kotlin](https://github.com/ton-community/ton-kotlin) | Kotlin | 네이티브 ADNL | The Open Network를 위한 Kotlin/Multiplatform SDK | | +| [tonlib-java](https://github.com/ton-blockchain/tonlib-java) | Java | Tonlib 바이너리 | Java/Scala/Kotlin 등에서 사용할 수 있는 TonLib에 대한 JVM 래퍼 | | +| [ayrat555/ton](https://github.com/ayrat555/ton) | Elixir | _오프체인 전용_ | Elixir용 TON SDK | | +| [C++ Tonlib](https://github.com/ton-blockchain/ton/tree/master/example/cpp) | C++ | Tonlib 바이너리 | TON 모노레포에서 제공하는 스마트 계약 상호 작용에 대한 공식 예제 | . | +| [Java Tonlib](https://github.com/ton-blockchain/tonlib-java) | Java | Tonlib 바이너리 | TON 모노레포에서 제공하는 스마트 계약 상호 작용에 대한 공식 예제 | | +| [labraburn/SwiftyTON](https://github.com/labraburn/SwiftyTON) | Swift | Tonlib 바이너리 | 비동기/대기를 사용하는 tonlib에 대한 네이티브 Swift 래퍼 | | +| [tonlib-xcframework](https://github.com/labraburn/tonlib-xcframework) | Swift | Tonlib 바이너리 | iOS의 모든 아키텍처용 Tonlib 빌드 도우미 | | +| [labraburn/node-tonlib](https://github.com/labraburn/node-tonlib) | NodeJS | Tonlib 바이너리 | tonlibjson을 사용하기 위한 NodeJS용 C++ 애드온 | | +| [olifanton/ton](https://github.com/olifanton/ton) | PHP | RPC ([Orbs](https://www.orbs.com/ton-access/) / [Toncenter](https://toncenter.com/api/v2/) 등) | 표준 프리미티브 및 계약 세트가 포함된 PHP SDK | | From 1f6796e22aaf111901ab6f84059a023b0003aa03 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 12 Aug 2024 19:07:10 +0800 Subject: [PATCH 09/41] New translations sdk.mdx (Chinese Simplified) --- .../current/develop/dapps/apis/sdk.mdx | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx b/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx index aa89463e6d..ad6bf074e8 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx @@ -13,12 +13,13 @@ ### TypeScript / JavaScript -| 库 | 区块链连接 | 说明 | -| ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | -| [ton](https://github.com/ton-org/ton) | 通过 RPC ([Orbs](https://www.orbs.com/ton-access/) / [Toncenter](https://toncenter.com/api/v2/) / 等) | 方便的客户端库,带有钱包包装器,用于在 TON 区块链上开发 dApp。 | -| [tonweb](https://github.com/toncenter/tonweb) | 通过 RPC ([Orbs](https://www.orbs.com/ton-access/) / [Toncenter](https://toncenter.com/api/v2/) / 等) | 旧式 TON JS SDK,外部依赖性极低,已在生产中进行过广泛测试。 | -| [tonkite/adnl](https://github.com/tonkite/adnl) | [ADNL](/develop/network/adnl-tcp) 本地/通过 WebSocket | ADNL TypeScript 实现。 | -| [tonutils](https://github.com/thekiba/tonutils) | 本地 [ADNL](/develop/network/adnl-tcp) | 基于 TypeScript 的界面,用于构建 TON 生态系统中的应用程序并与之交互。由于依赖于本地 ADNL,因此不能用于浏览器中的区块链交互。 | +| 库 | 区块链连接 | 说明 | +| ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | +| [ton](https://github.com/ton-org/ton) | 通过 RPC ([Orbs](https://www.orbs.com/ton-access/) / [Toncenter](https://toncenter.com/api/v2/) / 等) | 方便的客户端库,带有钱包包装器,用于在 TON 区块链上开发 dApp。 | +| [tonweb](https://github.com/toncenter/tonweb) | 通过 RPC ([Orbs](https://www.orbs.com/ton-access/) / [Toncenter](https://toncenter.com/api/v2/) / 等) | 旧式 TON JS SDK,外部依赖性极低,已在生产中进行过广泛测试。 | +| [tonkite/adnl](https://github.com/tonkite/adnl) | [ADNL](/develop/network/adnl-tcp) 本地/通过 WebSocket | ADNL TypeScript 实现。 | +| [tonutils](https://github.com/thekiba/tonutils) | 本地 [ADNL](/develop/network/adnl-tcp) | 基于 TypeScript 的界面,用于构建 TON 生态系统中的应用程序并与之交互。由于依赖于本地 ADNL,因此不能用于浏览器中的区块链交互。 | +| [foton](https://foton.sh/) | 通过 RPC ([Orbs](https://www.orbs.com/ton-access/) / [Toncenter](https://toncenter.com/api/v2/) / 等) | 用于与 TON 钱包和整个区块链交互的 TypeScript 工具包。该库将现有的解决方案(Blueprint 和 TON Connect)封装成一个舒适的 API。 | ### Java @@ -65,13 +66,14 @@ ### 其他语言的 SDK -| 库 | 语言 | 区块链连接 | 说明 | | -| --------------------------------------------------------------------------- | ------ | ----------- | -------------------------------------------- | - | -| [ton-kotlin](https://github.com/ton-community/ton-kotlin) | Kotlin | 本地 ADNL | 开放网络的 Kotlin/多平台 SDK。 | | -| [tonlib-java](https://github.com/ton-blockchain/tonlib-java) | Java | Tonlib bin | TonLib 的 JVM 封装器,可与 Java/Scala/Kotlin 等一起使用。 | | -| [ayrat555/ton](https://github.com/ayrat555/ton) | Elixir | _仅链下_ | 用于 Elixir 的 TON SDK | | -| [C++ Tonlib](https://github.com/ton-blockchain/ton/tree/master/example/cpp) | C++ | Tonlib 二进制 | TON monorepo 中智能合约交互的正式示例 | . | -| [Java Tonlib](https://github.com/ton-blockchain/tonlib-java) | Java | Tonlib 二进制 | TON monorepo 中智能合约交互的官方示例。 | | -| [labraburn/SwiftyTON](https://github.com/labraburn/SwiftyTON) | Swift | Tonlib 二进制 | 使用 async/await 对 tonlib 进行本地 Swift 封装。 | | -| [tonlib-xcframework](https://github.com/labraburn/tonlib-xcframework) | Swift | Tonlib 二进制 | 适用于 iOS 所有架构的 Tonlib 构建助手。 | | -| [labraburn/node-tonlib](https://github.com/labraburn/node-tonlib) | NodeJS | Tonlib 二进制 | 用于 NodeJS 的 C++ 附加组件,可与 tonlibjson 协同工作。 | | +| 库 | 语言 | 区块链连接 | 说明 | | +| --------------------------------------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | - | +| [ton-kotlin](https://github.com/ton-community/ton-kotlin) | Kotlin | 本地 ADNL | 开放网络的 Kotlin/多平台 SDK。 | | +| [tonlib-java](https://github.com/ton-blockchain/tonlib-java) | Java | Tonlib bin | TonLib 的 JVM 封装器,可与 Java/Scala/Kotlin 等一起使用。 | | +| [ayrat555/ton](https://github.com/ayrat555/ton) | Elixir | _仅链下_ | 用于 Elixir 的 TON SDK | | +| [C++ Tonlib](https://github.com/ton-blockchain/ton/tree/master/example/cpp) | C++ | Tonlib 二进制 | TON monorepo 中智能合约交互的正式示例 | . | +| [Java Tonlib](https://github.com/ton-blockchain/tonlib-java) | Java | Tonlib 二进制 | TON monorepo 中智能合约交互的官方示例。 | | +| [labraburn/SwiftyTON](https://github.com/labraburn/SwiftyTON) | Swift | Tonlib 二进制 | 使用 async/await 对 tonlib 进行本地 Swift 封装。 | | +| [tonlib-xcframework](https://github.com/labraburn/tonlib-xcframework) | Swift | Tonlib 二进制 | 适用于 iOS 所有架构的 Tonlib 构建助手。 | | +| [labraburn/node-tonlib](https://github.com/labraburn/node-tonlib) | NodeJS | Tonlib 二进制 | 用于 NodeJS 的 C++ 附加组件,可与 tonlibjson 协同工作。 | | +| [olifanton/ton](https://github.com/olifanton/ton) | PHP | 通过 RPC ([Orbs](https://www.orbs.com/ton-access/) / [Toncenter](https://toncenter.com/api/v2/) / 等) | PHP SDK 包含一套标准原语和合约。 | | From adf85ae596d8279c4c006ff026b6ee942c443945 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 12 Aug 2024 19:07:26 +0800 Subject: [PATCH 10/41] New translations developers.md (Chinese Simplified) --- .../develop/dapps/ton-connect/developers.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/developers.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/developers.md index 60c46ea119..6fc81cc765 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/developers.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/developers.md @@ -10,11 +10,11 @@ - [TON Connect React](/develop/dapps/ton-connect/developers#ton-connect-react) - [TON Connect JS SDK](/develop/dapps/ton-connect/developers#ton-connect-js-sdk) -- [TON Connect Python SDK](/develop/dapps/ton-connect/developers#ton-connect-python) - [TON Connect Dart](/develop/dapps/ton-connect/developers#ton-connect-dart) - [TON Connect C#](/develop/dapps/ton-connect/developers#ton-connect-c) - [TON Connect Unity](/develop/dapps/ton-connect/developers#ton-connect-unity) - [TON Connect Go](/develop/dapps/ton-connect/developers#ton-connect-go) +- [TON Connect Go](/develop/dapps/ton-connect/developers#ton-connect-go) ## TON Connect React @@ -79,9 +79,9 @@ TON Connect 可以通过简单的 UI 元素(如“连接钱包按钮”、“ ## TON Connect Python -### pytonconnect +### ClickoTON-Foundation tonconnect -TON Connect 2.0 的 Python SDK。相当于 `@tonconnect/sdk` 库。 +用于将 TON Connect 连接到 Python 应用的库 使用它可以通过 TonConnect 协议将您的应用程序连接到 TON 钱包。 @@ -93,7 +93,7 @@ pip3 install pytonconnect ### ClickoTON-Foundation tonconnect -用于将 TON Connect 连接到 Python 应用的库 +使用它可以通过 TonConnect 协议将您的应用程序连接到 TON 钱包。 ```bash git clone https://github.com/ClickoTON-Foundation/tonconnect.git @@ -102,9 +102,9 @@ pip install -e tonconnect [GitHub](https://github.com/ClickoTON-Foundation/tonconnect) -## TON Connect Dart +## TON Connect C\\# -TON Connect 2.0 的 Dart SDK。相当于 `@tonconnect/sdk` 库。 +TON Connect 2.0 的 C# SDK。相当于 `@tonconnect/sdk` 库。 使用它可以通过 TonConnect 协议将您的应用程序连接到 TON 钱包。 @@ -112,11 +112,11 @@ TON Connect 2.0 的 Dart SDK。相当于 `@tonconnect/sdk` 库。 $ dart pub add darttonconnect ``` -- [GitHub](https://github.com/romanovichim/dartTonconnect) +- [GitHub](https://github.com/continuation-team/TonSdk.NET/tree/main/TonSDK.Connect) -## TON Connect C\# +## TON Connect Go -TON Connect 2.0 的 C# SDK。相当于 `@tonconnect/sdk` 库。 +TON Connect 2.0 的 Go SDK。 使用它可以通过 TonConnect 协议将您的应用程序连接到 TON 钱包。 @@ -124,11 +124,11 @@ TON Connect 2.0 的 C# SDK。相当于 `@tonconnect/sdk` 库。 $ dotnet add package TonSdk.Connect ``` -- [GitHub](https://github.com/continuation-team/TonSdk.NET/tree/main/TonSDK.Connect) +- [GitHub](https://github.com/cameo-engineering/tonconnect) -## TON Connect Go +## 常见问题和关注点 -TON Connect 2.0 的 Go SDK。 +如果我们的开发者或社区成员在使用 TON Connect 2.0 期间遇到任何额外问题,请联系 [Tonkeeper 开发者](https://t.me/tonkeeperdev) 频道。 使用它可以通过 TonConnect 协议将您的应用程序连接到 TON 钱包。 From 36a71de2a84b194318e97dbaa2eb6765cdabf951 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 12 Aug 2024 19:07:31 +0800 Subject: [PATCH 11/41] New translations overview.mdx (Chinese Simplified) --- .../current/develop/dapps/ton-connect/overview.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx b/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx index b94a5950f0..74afa1a4fc 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx @@ -6,7 +6,7 @@ import Button from '@site/src/components/button' ![](/img/docs/ton-connect/ton-connect-overview.png?raw=true) -随意使用以下流程之一,以集成您的应用程序: +React Apps ```mdx-code-block ``` -## 验证者节点 - -当**验证者节点**持有足够数量的Toncoin作为质押代币时,它将被激活。验证者节点对网络的运行至关重要,参与新网络区块的验证。 +## 归档节点 TON基于权益证明机制运行,其中验证者在维护网络功能方面发挥着关键作用。验证者会因其贡献而[以Toncoin获得奖励](/participate/network-maintenance/staking-incentives),激励网络参与并确保网络安全。 [作为验证者运行全节点](/participate/run-nodes/full-node#become-a-validator) -## 全节点 + Liteserver +\ -当在全节点上激活端点时,节点将承担**Liteserver**的角色。这种节点类型可以处理并响应来自轻客户端的请求,允许与TON区块链无缝互动。 +## 验证者节点 -### 轻客户端:与 TON 交互的SDK +TON operates on a **Proof-of-Stake** mechanism, where `validators` are pivotal in maintaining network functionality. `Validators` are [rewarded in Toncoin](/participate/network-maintenance/staking-incentives) for their contributions, incentivizing network participation and ensuring network security. Liteservers使与轻客户端的快速通信成为可能,便于执行检索余额或提交交易等任务,而不需要完整的区块历史。 每个支持ADNL协议的SDK都可以使用`config.json`文件作为轻客户端。`config.json`文件包含了可以用来连接TON区块链的端点列表。 -[选择TON SDK](/develop/dapps/apis/sdk) +## Liteserver 每个不支持ADNL的SDK通常使用HTTP中间件来连接TON区块链。它的安全性和速度不如ADNL,但使用起来更简单。 -### 与 TON 的互动:公共Liteservers(端点) +`Liteservers` enable swift communication with Lite Clients, facilitating tasks like retrieving balance or submitting transactions without necessitating the full block history. TON基金会提供了几个公共Liteservers,集成到全局配置中,可供普遍使用。这些端点,如标准钱包使用的端点,确保即使不设置个人liteserver,也能与TON区块链进行交互。 @@ -52,32 +54,34 @@ TON基金会提供了几个公共Liteservers,集成到全局配置中,可供 在您的应用程序中使用下载的`config.json`文件与TON SDK。 -#### 故障排除 +If you want to have more stable *connection*, you can run your own `Liteserver`. To run a `full node` as a `Liteserver`, simply enable the `Liteserver` mode in your node's configuration file. -##### 故障排除 +\ -如果您看到此错误,这意味着您尝试连接的liteserver不可用。解决公共liteservers问题的正确方法如下: +## 轻客户端:与 TON 交互的SDK -1. 从tontech链接下载config.json文件: +Each SDK which supports ADNL protocol can be used as a `Lite Client` with `config.json` file (find how to download it [here](/participate/nodes/node-types#troubleshooting)). The `config.json` file contains a list of endpoints that can be used to connect to the TON Blockchain. -```bash -wget https://api.tontech.io/ton/wallet-mainnet.autoconf.json -O /usr/bin/ton/global.config.json -``` +每个不支持ADNL的SDK通常使用HTTP中间件来连接TON区块链。它的安全性和速度不如ADNL,但使用起来更简单。 它会从配置文件中移除响应慢的liteservers。 -2. 在您的应用程序中使用下载的`config.json`文件与TON SDK(/participate/nodes/node-types#lite-clients-the-sdks-to-interact-with-ton)。 +### 故障排除 -### 作为 Liteserver 运行全节点 +Below you can find approaches how to fix common nowed issues with `light clients` -如果你的项目需要高度_安全_,你可以运行自己的 Liteserver。要将完整节点作为 Liteserver 运行,只需在节点配置文件中启用 Liteserver 模式即可: +### 故障排除 [在节点中启用 Liteserver](/participate/run-nodes/full-node#enable-liteserver-mode) -## 归档节点 +1. 从tontech链接下载config.json文件: -[在节点中启用Liteserver](/participate/run-nodes/full-node#enable-liteserver-mode) +```bash +wget https://api.tontech.io/ton/wallet-mainnet.autoconf.json -O /usr/bin/ton/global.config.json +``` 这种节点对于创建需要完整区块链历史的区块链浏览器或其他工具至关重要。 -**归档节点**本质上是存档整个区块历史的全节点。 +2. Use the downloaded config.json file in your application with [TON SDK](/develop/dapps/apis/sdk). From 52927ad9caf409673df1653881d13f32000b62db Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Sun, 1 Sep 2024 09:53:50 +0800 Subject: [PATCH 29/41] New translations sdk.mdx (Korean) --- .../current/develop/dapps/apis/sdk.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx index 34e1a7b420..8f71dd7cb0 100644 --- a/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx +++ b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx @@ -51,17 +51,17 @@ ### Rust -| 라이브러리 | 블록체인 연결 | 설명 | -| ------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------- | -| [tonlib-rs](https://github.com/ston-fi/tonlib-rs) | Tonlib 바이너리 | TON 모노레포에서 가져온 바이너리 종속성을 사용하는 Rust SDK | -| [getgems-io/ton-grpc](https://github.com/getgems-io/ton-grpc) | Tonlib 바이너리 | tonlibjson에 대한 Rust 바인딩(따라서 TON 모노레포의 바이너리에 종속됨) 및 이를 기반으로 구축된 서비스 | +| 라이브러리 | 블록체인 연결 | 설명 | +| ------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------- | +| [tonlib-rs](https://github.com/ston-fi/tonlib-rs) | Tonlib 바이너리 | TON 모노레포에서 가져온 바이너리 종속성을 사용하는 Rust SDK | +| [getgems-io/ton-grpc](https://github.com/getgems-io/ton-grpc) | Tonlib binary | tonlibjson에 대한 Rust 바인딩(따라서 TON 모노레포의 바이너리에 종속됨) 및 이를 기반으로 구축된 서비스 | ### Go | 라이브러리 | 블록체인 연결 | 설명 | | -------------------------------------------------------- | ----------- | --------------------------------- | | [tonutils-go](https://github.com/xssnick/tonutils-go) | 네이티브 ADNL | TON 블록체인과 상호 작용하기 위한 Golang 라이브러리 | -| [tongo](https://github.com/tonkeeper/tongo) | 네이티브 ADNL | TON 블록체인을 위한 Go 구현 라이브러리 | +| [tongo](https://github.com/tonkeeper/tongo) | Native ADNL | TON 블록체인을 위한 Go 구현 라이브러리 | | [tonlib-go](https://github.com/ton-blockchain/tonlib-go) | Tonlib 바이너리 | libtonlibjson에 대한 공식 바인딩 | ### 기타 언어용 SDK From ab114f478c7fb5c432f1ba06e11d598a071a75a6 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Sun, 1 Sep 2024 09:53:51 +0800 Subject: [PATCH 30/41] New translations sdk.mdx (Chinese Simplified) --- .../current/develop/dapps/apis/sdk.mdx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx b/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx index ad6bf074e8..34138a56bf 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/dapps/apis/sdk.mdx @@ -51,18 +51,18 @@ ### Rust -| 库 | 区块链连接 | 说明 | -| ------------------------------------------------------------- | ---------- | ------------------------------------------------------------ | -| [tonlib-rs](https://github.com/ston-fi/tonlib-rs) | Tonlib 二进制 | 开放网络的 Rust SDK,带来 TON monorepo 的二进制依赖性。 | -| [getgems-io/ton-grpc](https://github.com/getgems-io/ton-grpc) | Tonlib 二进制 | tonlibjson 的 Rust 绑定(因此取决于 TON monorepo 中的二进制文件)以及在其基础上构建的服务 | +| 库 | 区块链连接 | 说明 | +| ------------------------------------------------------------- | ------------- | ------------------------------------------------------------ | +| [tonlib-rs](https://github.com/ston-fi/tonlib-rs) | Tonlib 二进制 | 开放网络的 Rust SDK,带来 TON monorepo 的二进制依赖性。 | +| [getgems-io/ton-grpc](https://github.com/getgems-io/ton-grpc) | Tonlib binary | tonlibjson 的 Rust 绑定(因此取决于 TON monorepo 中的二进制文件)以及在其基础上构建的服务 | ### Go -| 库 | 区块链连接 | 说明 | -| -------------------------------------------------------- | ---------- | ----------------------- | -| [tonutils-go](https://github.com/xssnick/tonutils-go) | 本地 ADNL | 用于与 TON 区块链交互的 Golang 库 | -| [tongo](https://github.com/tonkeeper/tongo) | 本地 ADNL | TON 区块链库的 Go 实现 | -| [tonlib-go](https://github.com/ton-blockchain/tonlib-go) | Tonlib 二进制 | libtonlibjson 的官方绑定 | +| 库 | 区块链连接 | 说明 | +| -------------------------------------------------------- | ----------- | ----------------------- | +| [tonutils-go](https://github.com/xssnick/tonutils-go) | 本地 ADNL | 用于与 TON 区块链交互的 Golang 库 | +| [tongo](https://github.com/tonkeeper/tongo) | Native ADNL | TON 区块链库的 Go 实现 | +| [tonlib-go](https://github.com/ton-blockchain/tonlib-go) | Tonlib 二进制 | libtonlibjson 的官方绑定 | ### 其他语言的 SDK From 9c7f501f5aceef2059ba463b80a776a44291347a Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Tue, 3 Sep 2024 09:35:08 +0800 Subject: [PATCH 31/41] New translations faq.md (Chinese Simplified) --- .../current/develop/howto/faq.md | 166 ++++++++++++------ 1 file changed, 109 insertions(+), 57 deletions(-) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/howto/faq.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/howto/faq.md index 7971c60aa9..905c4485d1 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/howto/faq.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/howto/faq.md @@ -25,9 +25,32 @@ 验证者生产区块。现有区块通过Liteservers可用。Liteservers通过轻客户端访问。在轻客户端之上构建了第三方工具,如钱包、浏览器、dapps等。 +1. 要访问轻客户端核心,请查看我们GitHub的这个部分:[ton-blockchain/tonlib](https://github.com/ton-blockchain/ton/tree/master/tonlib) +2. Workchains support cross-shard activity, which means that users can interact between different shardchains or workchains within the same network. In current L2 solutions, cross-shard operations are often complex and require additional bridges or interoperability solutions. In TON, for example, users can easily exchange tokens or perform other transactions between different shardchains without complex procedures. +3. Scalability is one of the main challenges for modern blockchain systems. In traditional L2 solutions, scalability is limited by the capacity of the sequencer. If the TPS (transactions per second) on L2 exceeds the sequencer's capacity, it can lead to problems. In workchains in TON, this problem is solved by dividing the shard. When the load on a shard exceeds its capacity, the shard is automatically divided into two or more shards, allowing the system to scale almost without limit. + +### Is there a need for L2 on the TON? + +At any transaction cost, there will always be applications that cannot sustain such a fee but can function at a much lower cost. Similarly, regardless of the latency achieved, there will always be applications that require even lower latency. Therefore, it is conceivable that there might eventually be a need for L2 solutions on the TON platform to cater to these specific requirements. + +## MEV + +### 区块时间 + +*2-5秒* + +In addition, the current TON architecture lacks a market-based mechanism for determining transaction fees. Commissions are fixed and not subject to change depending on transaction priorities, which makes frontrunning less attractive. Because of the fixed fees and deterministic order of transactions, it is non-trivial to do frontrunning in TON. + +## 最终确定时间 + +### 获取区块信息的RPC方法是什么? + +验证者生产区块。现有区块通过Liteservers可用。Liteservers通过轻客户端访问。在轻客户端之上构建了第三方工具,如钱包、浏览器、dapps等。 + - 要访问轻客户端核心,请查看我们GitHub的这个部分:[ton-blockchain/tonlib](https://github.com/ton-blockchain/ton/tree/master/tonlib) 此外,这里有三个高级第三方区块浏览器: + - https://explorer.toncoin.org/last - https://toncenter.com/ - https://tonwhales.com/explorer @@ -36,15 +59,15 @@ ### 区块时间 -_2-5秒_ +*2-5秒* :::info 通过阅读我们在[ton.org/analysis](https://ton.org/analysis)上的分析,比较TON的链上指标,包括区块时间和最终确定时间。 ::: -### 最终确定时间 +### 获取交易数据的RPC方法是什么? -_小于6秒_ +*小于6秒* :::info 通过阅读我们在[ton.org/analysis](https://ton.org/analysis)上的分析,比较TON的链上指标,包括区块时间和最终确定时间。 @@ -52,7 +75,7 @@ _小于6秒_ ### 平均区块大小 -```bash +```bash max block size param 29 max_block_bytes:2097152 ``` @@ -63,11 +86,11 @@ max_block_bytes:2097152 ### TON 上的区块布局是怎样的? -对布局中每个字段的详细解释: +钱包合约转账的示例(低层级): -- [区块布局](/develop/data-formats/block-layout) +- https://github.com/xssnick/tonutils-go/blob/master/example/wallet/main.go -## 交易 +## 是否可以确定交易100%完成?查询交易级数据是否足以获得这些信息? ### 获取交易数据的RPC方法是什么? @@ -76,63 +99,73 @@ max_block_bytes:2097152 ### TON 交易是异步的还是同步的?是否有文档显示这个系统是如何工作的? TON区块链消息是异步的: + - 发送者准备交易正文(消息boc)并通过轻客户端(或更高级工具)广播 - 轻客户端返回广播状态,而非执行交易的结果 - 发送者通过监听目标账户(地址)状态或整个区块链状态来检查期望结果 使用一个与钱包智能合约相关的例子来解释TON异步消息传递是如何工作的: + - [TON钱包如何工作,以及如何使用JavaScript访问它们](https://blog.ton.org/how-ton-wallets-work-and-how-to-access-them-from-javascript#1b-sending-a-transfer) -钱包合约转账的示例(低层级): -- https://github.com/xssnick/tonutils-go/blob/master/example/wallet/main.go +是的,TON上可以通过两种不同的方式实现交易批量处理: + +- 通过利用TON的异步特性,即向网络发送独立的交易 ### 是否可以确定交易100%完成?查询交易级数据是否足以获得这些信息? -**简短回答:**要确保交易已完成,必须检查接收者的账户。 +\*\*简短回答:\*\*要确保交易已完成,必须检查接收者的账户。 + +默认钱包(v3/v4)也支持在一笔交易中发送多达4条消息。 -要了解有关交易验证的更多信息,请参阅以下示例: - Go: [钱包示例](https://github.com/xssnick/tonutils-go/blob/master/example/wallet/main.go) - Python: [带支付的Storefront bot](/develop/dapps/tutorials/accept-payments-in-a-telegram-bot) - JavaScript: [饺子销售机器人](/develop/dapps/tutorials/accept-payments-in-a-telegram-bot-js) -### TON 中交易的布局是怎样的? +### TON 的货币精度是多少? + +*9位小数* -对布局中每个字段的详细解释: - [交易布局](/develop/data-formats/transaction-layout) -### 是否可以批量处理交易? +### 是否有标准化的协议用于铸造、销毁和交易中转移可替代和不可替代代币? -是的,TON上可以通过两种不同的方式实现交易批量处理: -- 通过利用TON的异步特性,即向网络发送独立的交易 -- 通过使用接收任务并将其作为批处理执行的智能合约 +非同质化代币(NFT): -使用批量处理特性的合约示例(高负载钱包): -- https://github.com/tonuniverse/highload-wallet-api +- [TEP-62:NFT标准](https://github.com/ton-blockchain/TEPs/blob/master/text/0062-nft-standard.md) +- [NFT文档](/develop/dapps/defi/tokens#nft) -默认钱包(v3/v4)也支持在一笔交易中发送多达4条消息。 +Jettons(代币): + +- [TEP-74:Jettons标准](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md) + +其他标准: ## 标准 -### TON 的货币精度是多少? +### 是否有用 Jettons(代币)和 NFT 解析事件的示例? -_9位小数_ +在TON上,所有数据都以boc消息的形式传输。这意味着在交易中使用NFT并不是特殊事件。相反,它是发送给或从(NFT或钱包)合约接收的常规消息,就像涉及标准钱包的交易一样。 :::info Mainnet支持的小数位数:9位。 ::: -### 是否有标准化的协议用于铸造、销毁和交易中转移可替代和不可替代代币? +### 是否有标准化的协议用于在交易中铸造、销毁和转移可替代和不可替代代币? + +要更好地理解这个过程是如何工作的,请参阅[支付处理](/develop/dapps/asset-processing/)部分。 -非同质化代币(NFT): - [TEP-62:NFT标准](https://github.com/ton-blockchain/TEPs/blob/master/text/0062-nft-standard.md) - [NFT文档](/develop/dapps/defi/tokens#nft) Jettons(代币): -- [TEP-74:Jettons标准](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md) -- [分布式代币概览](https://telegra.ph/Scalable-DeFi-in-TON-03-30) + +- [智能合约地址](/learn/overviews/addresses) +- [分布式 TON 代币概述](https://telegra.ph/Scalable-DeFi-in-TON-03-30) - [可替代代币文档(Jettons)](/develop/dapps/defi/tokens#jettons) 其他标准: + - https://github.com/ton-blockchain/TEPs ### 是否有用 Jettons(代币)和 NFT 解析事件的示例? @@ -143,9 +176,9 @@ Jettons(代币): - https://tonapi.io/swagger-ui -要更好地理解这个过程是如何工作的,请参阅[支付处理](/develop/dapps/asset-processing/)部分。 +对于**Jettons**合约必须实现[标准的接口](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md)并在_get_wallet_data()_或_get_jetton_data()_方法上返回数据。 -## 账户结构 +## 是否有特殊账户(例如,由网络拥有的账户)与其他账户有不同的规则或方法? ### 地址格式是什么? @@ -154,74 +187,93 @@ Jettons(代币): ### 是否可以拥有类似于 ENS 的命名账户 是的,请使用TON DNS: + - [TON DNS和域名](/participate/web3/dns) -### 如何区分普通账户和智能合约? +### 是否可以检测到 TON 上的合约部署事件? - [一切都是智能合约](/learn/overviews/addresses#everything-is-a-smart-contract) ### 如何判断地址是否为代币地址? -对于**Jettons**合约必须实现[标准的接口](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md)并在_get_wallet_data()_或_get_jetton_data()_方法上返回数据。 +智能合约可以存在于未初始化状态,意味着其状态在区块链中不可用但合约有非零余额。初始状态本身可以稍后通过内部或外部消息发送到网络,因此可以监控这些来检测合约部署。 -### 是否有特殊账户(例如,由网络拥有的账户)与其他账户有不同的规则或方法? +### Are there any special accounts (e.g. accounts owned by the network) that have different rules or methods from the rest? -TON内有一个特殊的主链叫做Masterchain。它由网络范围内的合约组成,包括网络配置、与验证者相关的合约等: +There is a special master blockchain inside a TON called Masterchain. It consists of network-wide contracts with network configuration, validator-related contracts, etc: :::info -在TON区块链概述文章中阅读更多关于masterchain、workchains和shardchains的信息:[Blockchain of Blockchains](/learn/overviews/ton-blockchain)。 +Read more about masterchain, workchains and shardchains in TON Blockchain overview article: [Blockchain of Blockchains](/learn/overviews/ton-blockchain). ::: -一个很好的例子是治理智能合约,它是masterchain的一部分: -- [治理合约](/develop/smart-contracts/governance) +是的,这是可能的。如果智能合约执行特定指令(`set_code()`),其代码可以被更新并且地址将保持不变。 -## 智能合约 +- [Governance contracts](/develop/smart-contracts/governance) -### 是否可以检测到 TON 上的合约部署事件? +## 智能合约可以被删除吗? -[TON中的一切都是智能合约](/learn/overviews/addresses#everything-is-a-smart-contract)。 +### Is it possible to detect contract deployment events on TON? -账户地址是从其_初始状态_确定生成的,其中包括_初始代码_和_初始数据_(对于钱包,初始数据包括公钥在内的其他参数)。当任何组件发生变化时,地址相应改变。 +[Everything in TON is a smart contract](/learn/overviews/addresses#everything-is-a-smart-contract). -智能合约可以存在于未初始化状态,意味着其状态在区块链中不可用但合约有非零余额。初始状态本身可以稍后通过内部或外部消息发送到网络,因此可以监控这些来检测合约部署。 +是的,智能合约地址是区分大小写的,因为它们是使用[base64算法](https://en.wikipedia.org/wiki/Base64)生成的。您可以在[这里](/learn/overviews/addresses)了解更多关于智能合约地址的信息。 -为了防止消息链在不存在的合约处中断,TON使用了“弹回”功能。在这些文章中了解更多信息: +Smart contract can exist in uninitialized state, meaning that its state is not available in blockchain but contract has non-zero balance. Initial state itself can be sent to the network later with an internal or external message, so those can be monitored to detect contract deployment. -- [通过TonLib部署钱包](https://ton.org/docs/develop/dapps/asset-processing/#deploying-wallet) -- [支付查询处理费用并发送响应](https://ton.org/docs/develop/smart-contracts/guidelines/processing) +TVM与以太坊虚拟机(EVM)不兼容,因为TON采用了完全不同的架构(TON是异步的,而以太坊是同步的)。 -### 是否可以将代码重新部署到现有地址,还是必须作为新合约部署? +- [Deploying wallet via TonLib](https://ton.org/docs/develop/dapps/asset-processing/#deploying-wallet) +- [Paying for processing queries and sending responses](https://ton.org/docs/develop/smart-contracts/guidelines/processing) -是的,这是可能的。如果智能合约执行特定指令(`set_code()`),其代码可以被更新并且地址将保持不变。 +### 是否可以为 TON 编写 Solidity? -如果合约最初无法执行`set_code()`(通过其代码或来自外部的其他代码的执行),那么它的代码将永远无法更改。没有人能够在同一地址重新部署带有其他代码的合约。 +相关地,TON生态系统不支持在以太坊的Solidity编程语言中开发。 -### 智能合约可以被删除吗? +但如果您在Solidity语法中添加异步消息并能够与数据进行低层级交互,那么您可以使用FunC。FunC具有大多数现代编程语言通用的语法,并专为TON上的开发设计。 -是的,要么是由于存储费用累积的结果(合约需要达到-1 TON余额才能被删除),要么是通过发送带有[mode 160](https://docs.ton.org/develop/smart-contracts/messages#message-modes)的消息。 +1. Pay attention to projects with a good reputation and well-known development teams. +2. Reputable projects always conduct independent code audits to make sure the code is safe and reliable. Look for projects that have several completed audits from reputable auditing firms. +3. An active community and positive feedback can serve as an additional indicator of a project's reliability. +4. Examine exactly how the project implements the update process. The more transparent and decentralized the process, the less risk to users. -### 智能合约地址是否区分大小写? +### 推荐的节点提供商用于数据提取包括: -是的,智能合约地址是区分大小写的,因为它们是使用[base64算法](https://en.wikipedia.org/wiki/Base64)生成的。您可以在[这里](/learn/overviews/addresses)了解更多关于智能合约地址的信息。 +API类型: -### Ton 虚拟机(TVM)与 EVM 兼容吗? +Sometimes the logic for updating may exist, but the rights to change the code may be moved to an "empty" address, which also precludes changes. - TVM与以太坊虚拟机(EVM)不兼容,因为TON采用了完全不同的架构(TON是异步的,而以太坊是同步的)。 +### Is it possible to re-deploy code to an existing address or does it have to be deployed as a new contract? - [了解更多关于异步智能合约](https://telegra.ph/Its-time-to-try-something-new-Asynchronous-smart-contracts-03-25)。 +Yes, this is possible. If a smart contract carries out specific instructions (`set_code()`) its code can be updated and the address will remain the same. -### 是否可以为 TON 编写 Solidity? +TON社区项目目录: + +### Can smart contract be deleted? + +Yes, either as a result of storage fee accumulation (contract needs to reach -1 TON balance to be deleted) or by sending a message with [mode 160](https://docs.ton.org/develop/smart-contracts/messages#message-modes). + +### Are smart contract addresses case sensitive? + +Yes, smart contract addresses are case sensitive because they are generated using the [base64 algorithm](https://en.wikipedia.org/wiki/Base64). You can learn more about smart contract addresses [here](/learn/overviews/addresses). - 相关地,TON生态系统不支持在以太坊的Solidity编程语言中开发。 +### Is the Ton Virtual Machine (TVM) EVM-compatible? - 但如果您在Solidity语法中添加异步消息并能够与数据进行低层级交互,那么您可以使用FunC。FunC具有大多数现代编程语言通用的语法,并专为TON上的开发设计。 +The TVM is not compatible with the Ethereum Virtual Machine (EVM) because TON leverages a completely different architecture (TON is asynchronous, while Ethereum is synchronous). +[Read more on asynchronous smart contracts](https://telegra.ph/Its-time-to-try-something-new-Asynchronous-smart-contracts-03-25). + +### Is it possible to write on Solidity for TON? + +Relatedly, the TON ecosystem does not support development in Ethereum’s Solidity programming language. + +But if you add asynchronous messages to the Solidity syntax and the ability to interact with data at a low level, then you get FunC. FunC features a syntax that is common to most modern programming languages and is designed specifically for development on TON. ## 远程过程调用(RPC) ### 推荐的节点提供商用于数据提取包括: API类型: + - 了解更多关于不同[API类型](/develop/dapps/apis/)(索引、HTTP和ADNL) 节点提供商合作伙伴: @@ -229,7 +281,7 @@ API类型: - https://toncenter.com/api/v2/ - [getblock.io](https://getblock.io/) - https://www.orbs.com/ton-access/ -- [toncenter/ton-http-api](https://github.com/toncenter/ton-http-api) +- [toncenter/ton-http-api](https://github.com/toncenter/ton-http-api) - [nownodes.io](https://nownodes.io/nodes) - https://dton.io/graphql From 875d78eb4a761067ab09a7df09d93c473388662e Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Wed, 4 Sep 2024 09:30:47 +0800 Subject: [PATCH 32/41] New translations compile.md (Chinese Simplified) --- .../current/develop/howto/compile.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/howto/compile.md b/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/howto/compile.md index b8eff00459..eb5a60a327 100644 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/howto/compile.md +++ b/i18n/zh-CN/docusaurus-plugin-content-docs/current/develop/howto/compile.md @@ -35,13 +35,13 @@ apt update sudo apt install build-essential cmake clang openssl libssl-dev zlib1g-dev gperf libreadline-dev ccache libmicrohttpd-dev pkg-config libsodium-dev libsecp256k1-dev ``` -3. 假设您已将源代码树获取到目录`~/ton`,其中`~`是您的主目录,并且您已创建一个空目录`~/ton-build`: +3. Suppose that you have fetched the source tree to directory `~/ton`, where `~` is your home directory, and that you have created an empty directory `~/ton-build`: ```bash mkdir ton-build ``` -然后在Linux或MacOS的终端中运行以下命令: +Then run the following in a terminal of Linux or MacOS: ```bash cd ton-build From 73eccd332280e6cb22b99b84c4f0e34cbcfe0811 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:57:23 +0800 Subject: [PATCH 33/41] New translations overview.md (Korean) --- .../dapps/asset-processing/overview.md | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md new file mode 100644 index 0000000000..db5f355804 --- /dev/null +++ b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/overview.md @@ -0,0 +1,62 @@ +import Button from '@site/src/components/button' +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Asset Processing Overview + +Here you can find a **short overview** on [how TON transfers work](/develop/dapps/asset-processing/overview#overview-on-messages-and-transactions), what [asset types](/develop/dapps/asset-processing/overview#digital-asset-types-on-ton) can you find in TON (and what about will you read [next](/develop/dapps/asset-processing/overview#read-next)) and how to [interact with ton](/develop/dapps/asset-processing/overview#interaction-with-ton-blockchain) using your programming language, it's recommended to understand all information, discovered below, before going to the next pages. + +## Overview on messages and transactions + +전적으로 비동기적 접근 방식을 구현한 TON 블록체인은 전통적인 블록체인과는 다른 몇 가지 개념을 포함하고 있습니다. 특히, 블록체인과의 모든 참여자의 상호작용은 스마트 계약 및/또는 외부 세계 간에 비동기적으로 전송되는 [메시지](/develop/smart-contracts/guidelines/message-delivery-guarantees)의 그래프로 구성됩니다. 각 트랜잭션은 하나의 수신 메시지와 최대 512개의 발신 메시지로 이루어집니다. + +There are 3 types of messages, that are fully described [here](/develop/smart-contracts/messages#types-of-messages). To put it briefly: + +- [external message](/develop/smart-contracts/guidelines/external-messages): + - `external in message` (sometimes called just `external message`) is message that is sent from *outside* of the blockchain to a smart contract *inside* the blockchain. + - `external out message` (usually called `logs message`) is sent from a *blockchain entity* to the *outer world*. +- [internal message](/develop/smart-contracts/guidelines/internal-messages) is sent from one *blockchain entity* to *another*, can carry some amount of digital assets and arbitrary portion of data. + +The common path of any interaction starts with an external message sent to a `wallet` smart contract, which authenticates the message sender using public-key cryptography, takes charge of fee payment, and sends internal blockchain messages. That messages queue form directional acyclic graph, or a tree. + +For example: + +![](/img/docs/asset-processing/alicemsgDAG.svg) + +- `Alice` use e.g [Tonkeeper](https://tonkeeper.com/) to send an `external message` to her wallet. +- `external message` is the input message for `wallet A v4` contract with empty soure (a message from nowhere, such as [Tonkeeper](https://tonkeeper.com/)). +- `outgoing message` is the output message for `wallet A v4` contract and input message for `wallet B v4` contract with `wallet A v4` source and `wallet B v4` destination. + +As a result there are 2 transactions with their set of input and output messages. + +Each action, when contract take message as input (triggered by it), process it and generate or not generate outgoing messages as output, called `transaction`. Read more about transactions [here](/develop/smart-contracts/guidelines/message-delivery-guarantees#what-is-a-transaction). + +That `transactions` can span a **prolonged period** of time. Technically, transactions with queues of messages are aggregated into blocks processed by validators. The asynchronous nature of the TON Blockchain **does not allow to predict the hash and lt (logical time) of a transaction** at the stage of sending a message. + +The `transaction` accepted to the block is final and cannot be modified. + +:::info Transaction Confirmation +TON transactions are irreversible after just one confirmation. For the best user experience, it is suggested to avoid waiting on additional blocks once transactions are finalized on the TON Blockchain. Read more in the [Catchain.pdf](https://docs.ton.org/catchain.pdf#page=3). +::: + +Smart contracts pay several types of [fees](/develop/smart-contracts/fees) for transactions (usually from the balance of an incoming message, behavior depends on [message mode](/develop/smart-contracts/messages#message-modes)). Amount of fees depends on workchain configs with maximal fees on `masterchain` and substantially lower fees on `basechain`. + +## Digital asset types on TON + +TON has three types of digital assets. + +- Toncoin, the main token of the network. It is used for all basic operations on the blockchain, for example, paying gas fees or staking for validation. +- Contract assets, such as tokens and NFTs, which are analogous to the ERC-20/ERC-721 standards and are managed by arbitrary contracts and thus can require custom rules for processing. You can find more info on it's processing in [process NFTs](/develop/dapps/asset-processing/nfts) and [process Jettons](/develop/dapps/asset-processing/jettons) articles. +- Native token, which is special kind of assets that can be attached to any message on the network. But these asset is currently not in use since the functionality for issuing new native tokens is closed. + +## Interaction with TON blockchain + +Basic operations on TON Blockchain can be carried out via TonLib. It is a shared library which can be compiled along with a TON node and expose APIs for interaction with the blockchain via so-called lite servers (servers for lite clients). TonLib follows a trustless approach by checking proofs for all incoming data; thus, there is no necessity for a trusted data provider. Methods available to TonLib are listed [in the TL scheme](https://github.com/ton-blockchain/ton/blob/master/tl/generate/scheme/tonlib_api.tl#L234). They can be used either as a shared library via [wrappers](/develop/dapps/asset-processing/#repositories). + +## Read next + +After reading this article you can check: + +1. [Payments processing](/develop/dapps/asset-processing/) to get how to work with `TON coins` +2. [Jetton processing](/develop/dapps/asset-processing/jettons) to get how to work with `jettons` (sometime called `tokens`) +3. [NFT processing](/develop/dapps/asset-processing/nfts) to get how to work with `NFT` (that is the special type of `jetton`) From 1fbce3ab455447094d19fbe9a35f324c7317e165 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:57:24 +0800 Subject: [PATCH 34/41] New translations usdt.md (Korean) --- .../develop/dapps/asset-processing/usdt.md | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/usdt.md diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/usdt.md b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/usdt.md new file mode 100644 index 0000000000..e37e1ce12d --- /dev/null +++ b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/asset-processing/usdt.md @@ -0,0 +1,52 @@ +import Button from '@site/src/components/button' + +# USDT Processing + +## Tether + +스테이블코인은 가격을 안정적으로 유지하기 위해 법정 화폐나 금과 같은 자산에 1:1로 고정된 암호화폐의 일종입니다. 최근까지 jUSDT 토큰이 있었는데, 이는 [bridge.ton.org](bridge.ton.org)를 통해 이더리움 토큰을 브릿지한 ERC-20 기반의 래핑된 토큰입니다. 하지만 [2023년 4월 18일](https://t.me/toncoin/824), [Tether](https://tether.to/en/)사가 발행한 **네이티브** USD₮ 토큰의 공개 출시가 있었습니다. USD₮가 출시된 후 jUSDT는 우선순위가 두 번째로 밀렸지만 여전히 USD₮의 대안 또는 추가 수단으로 서비스에서 사용되고 있습니다. + +In TON Blockchain USD₮ supported as a [Jetton Asset](/develop/dapps/asset-processing/jettons). + +:::info +To integrate Tether’s USD₮ Token on TON Blockchain use the contract address: +[EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs](https://tonviewer.com/EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs?section=jetton) +::: + + + + + +## Advantages of USD₮ on TON + +### Seamless Telegram integration + +[USD₮ on TON](https://ton.org/borderless) will be seamlessly integrated into Telegram, offering a uniquely user-friendly experience that positions TON as the most convenient blockchain for USDt transactions. This integration will simplify DeFi for Telegram users, making it more accessible and understandable. + +### Lower transaction fees + +Fee consumed by Ethereum USD₮ transfer is calculated dynamically depending on the network load. That's why transaction can cost a lot. + +```cpp +transaction_fee = gas_used * gas_price +``` + +- `gas_used` is the amount of gas was used during transaction execution. +- `gas_price` price on 1 unit of gas in Gwei, calculated dynamically + +On the other hand average fee for sending any amount of USD₮ in TON Blockchain is about 0.0145 TON nowadays. Even if TON price increases 100 times, transactions will [remain ultra-cheap](/develop/smart-contracts/fees#average-transaction-cost). The core TON development team has optimized Tether’s smart contract to make it three times cheaper than any other Jetton. + +### Faster and scalable + +TON’s high throughput and rapid confirmation times enable USD₮ transactions to be processed more quickly than ever before. + +## Advanced Details + +:::caution IMPORTANT + +See important [recommendations](/develop/dapps/asset-processing/jettons#jetton-wallet-processing). +::: + +## See Also + +- [Payments Processing](/develop/dapps/asset-processing/) From fad344226a89195b6e68cf0ac10214ae0b571384 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:57:32 +0800 Subject: [PATCH 35/41] New translations developers.md (Korean) --- .../develop/dapps/ton-connect/developers.md | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/developers.md diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/developers.md b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/developers.md new file mode 100644 index 0000000000..3b85cf71e4 --- /dev/null +++ b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/developers.md @@ -0,0 +1,162 @@ +# TON Connect SDKs + +## SDK List + +:::info +If possible, it is recommended to use the [@tonconnect/ui-react](/develop/dapps/ton-connect/developers#ton-connect-ui-react) kit for your dApps. Only switch to lower levels of the SDK or reimplement your version of the protocol if it is really necessary for your product. +::: + +This page contents the list of useful libraries for TON Connect. + +- [TON Connect React](/develop/dapps/ton-connect/developers#ton-connect-react) +- [TON Connect JS SDK](/develop/dapps/ton-connect/developers#ton-connect-js-sdk) +- [TON Connect Python SDK](/develop/dapps/ton-connect/developers#ton-connect-python) +- [TON Connect Dart](/develop/dapps/ton-connect/developers#ton-connect-dart) +- [TON Connect C#](/develop/dapps/ton-connect/developers#ton-connect-c) +- [TON Connect Unity](/develop/dapps/ton-connect/developers#ton-connect-unity) +- [TON Connect Go](/develop/dapps/ton-connect/developers#ton-connect-go) + +## TON Connect React + +- [@tonconnect/ui-react](/develop/dapps/ton-connect/developers#ton-connect-ui-react) - TON Connect User Interface (UI) for React applications + +TonConnect UI React is a React UI kit for TonConnect SDK. Use it to connect your app to TON wallets via TonConnect protocol in React apps. + +- `@tonconnect/ui-react`를 사용한 DApp의 예시: [GitHub](https://github.com/ton-connect/demo-dapp-with-react-ui) +- Example of deployed `demo-dapp-with-react-ui`: [GitHub](https://ton-connect.github.io/demo-dapp-with-react-ui/) + +```bash +npm i @tonconnect/ui-react +``` + +- [GitHub](https://github.com/ton-connect/sdk/tree/main/packages/ui-react) +- [NPM](https://www.npmjs.com/package/@tonconnect/ui-react) +- [API Documentation](https://ton-connect.github.io/sdk/modules/_tonconnect_ui_react.html) + +## TON Connect JS SDK + +The TON Connect repository contains following main packages: + +- [@tonconnect/ui](/develop/dapps/ton-connect/developers#ton-connect-ui) - TON Connect User Interface (UI) +- [@tonconnect/sdk](/develop/dapps/ton-connect/developers#ton-connect-sdk) - TON Connect SDK +- [@tonconnect/protocol](/develop/dapps/ton-connect/developers#ton-connect-protocol-models) - TON Connect protocol specifications + +### TON Connect UI + +TonConnect UI is a UI kit for TonConnect SDK. Use it to connect your app to TON wallets via TonConnect protocol. It allows you to integrate TonConnect to your app easier using our UI elements such as "connect wallet button", "select wallet dialog" and confirmation modals. + +```bash +npm i @tonconnect/ui +``` + +- [GitHub](https://github.com/ton-connect/sdk/tree/main/packages/ui) +- [NPM](https://www.npmjs.com/package/@tonconnect/ui) +- [API Documentation](https://ton-connect.github.io/sdk/modules/_tonconnect_ui.html) + +The TON Connect User Interface (UI) is a framework that allows developers to improve the user experience (UX) for application users. + +TON Connect can easily be integrated with apps using simple UI elements such as the "connect wallet button", "select wallet dialog" and confirmation modals. Here are three main examples of how TON Connect improves UX in apps: + +- Example of app functionality in the DAppbrowser: [GitHub](https://ton-connect.github.io/demo-dapp/) +- Example of a backend partition of the DAppabove: [GitHub](https://github.com/ton-connect/demo-dapp-backend) +- Bridge server using Go: [GitHub](https://github.com/ton-connect/bridge) + +This kit will simplify the implementation of TON Connect in apps built for TON Blockchain. Standard frontend frameworks are supported, as well as applications that don’t use predetermined frameworks. + +### TON Connect SDK + +The most low-level of the three frameworks that helps developers integrate TON Connect into their applications is the TON Connect SDK. It is primarily used to connect apps to TON Wallets via the TON Connect protocol. + +- [GitHub](https://github.com/ton-connect/sdk/tree/main/packages/sdk) +- [NPM](https://www.npmjs.com/package/@tonconnect/sdk) + +### TON Connect protocol models + +This package contains protocol requests, protocol responses, event models and encoding and decoding functions. It can be used to integrate TON Connect to wallet apps written in TypeScript. In order to integrate TON Connect into a DAppthe [@tonconnect/sdk](https://www.npmjs.com/package/@tonconnect/sdk) should be used. + +- [GitHub](https://github.com/ton-connect/sdk/tree/main/packages/protocol) +- [NPM](https://www.npmjs.com/package/@tonconnect/protocol) + +## TON Connect Python + +### pytonconnect + +Python SDK for TON Connect 2.0. Analogue of the `@tonconnect/sdk` library. + +Use it to connect your app to TON wallets via TonConnect protocol. + +```bash +pip3 install pytonconnect +``` + +- [GitHub](https://github.com/XaBbl4/pytonconnect) + +### ClickoTON-Foundation tonconnect + +Library for connecting TON Connect to Python apps + +```bash +git clone https://github.com/ClickoTON-Foundation/tonconnect.git +pip install -e tonconnect +``` + +[GitHub](https://github.com/ClickoTON-Foundation/tonconnect) + +## TON Connect Dart + +Dart SDK for TON Connect 2.0. Analogue of the `@tonconnect/sdk` library. + +Use it to connect your app to TON wallets via TonConnect protocol. + +```bash + $ dart pub add darttonconnect +``` + +- [GitHub](https://github.com/romanovichim/dartTonconnect) + +## TON Connect C\# + +C# SDK for TON Connect 2.0. Analogue of the `@tonconnect/sdk` library. + +Use it to connect your app to TON wallets via TonConnect protocol. + +```bash + $ dotnet add package TonSdk.Connect +``` + +- [GitHub](https://github.com/continuation-team/TonSdk.NET/tree/main/TonSDK.Connect) + +## TON Connect Go + +Go SDK for TON Connect 2.0. + +Use it to connect your app to TON wallets via TonConnect protocol. + +```bash + go get github.com/cameo-engineering/tonconnect +``` + +- [GitHub](https://github.com/cameo-engineering/tonconnect) + +## General Questions and Concerns + +If any of our developers or community members encounter any additional issues during the implementation of TON Connect 2.0, please contact the [Tonkeeper developer](https://t.me/tonkeeperdev) channel. + +If you experience any additional issues, or would like to present a proposal on how to improve TON Connect 2.0, please contact us directly through the appropriate [GitHub directory](https://github.com/ton-connect/). + +## TON Connect Unity + +Unity asset for TON Connect 2.0. Uses `continuation-team/TonSdk.NET/tree/main/TonSDK.Connect`. + +Use it to integrate TonConnect protocol with your game. + +- [GitHub](https://github.com/continuation-team/unity-ton-connect) +- [Docs](https://docs.tonsdk.net/user-manual/unity-tonconnect-2.0/getting-started) + +## See Also + +- [Step by step guide for building your first web client](https://ton-community.github.io/tutorials/03-client/) +- [[YouTube] TON Smart Contracts | 10 | Telegram DApp[EN]](https://www.youtube.com/watch?v=D6t3eZPdgAU\&t=254s\&ab_channel=AlefmanVladimir%5BEN%5D) +- [Ton Connect Getting started](https://github.com/ton-connect/sdk/tree/main/packages/sdk) +- [Integration Manual](/develop/dapps/ton-connect/integration) +- [[YouTube] TON Dev Study TON Connect Protocol [RU]](https://www.youtube.com/playlist?list=PLyDBPwv9EPsCJ226xS5_dKmXXxWx1CKz_) From 8ddd80e09d0e3ad2a8993065ffea41a2577ebcdc Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:57:35 +0800 Subject: [PATCH 36/41] New translations integration.md (Korean) --- .../develop/dapps/ton-connect/integration.md | 506 ++++++++++++++++++ 1 file changed, 506 insertions(+) create mode 100644 i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/integration.md diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/integration.md b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/integration.md new file mode 100644 index 0000000000..5f9ee299ff --- /dev/null +++ b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/integration.md @@ -0,0 +1,506 @@ +# Integration manual with the JavaScript SDK + +In this tutorial, we’ll create a sample web app that supports TON Connect 2.0 authentication. It will allow for signature verification to eliminate the possibility of fraudulent identity impersonation without agreement establishment between parties. + +## Documentation links + +1. [@tonconnect/sdk documentation](https://www.npmjs.com/package/@tonconnect/sdk) +2. [Wallet-application message exchange protocol](https://github.com/ton-connect/docs/blob/main/requests-responses.md) +3. [Tonkeeper implementation of wallet side](https://github.com/tonkeeper/wallet/tree/main/src/tonconnect) + +## Prerequisites + +In order for connectivity to be fluent between apps and wallets, the web app must make use of manifest that is accessible via wallet applications. The prerequisite to accomplish this is typically a host for static files. For example, say if a developer wants to make use of GitHub pages, or deploy their website using TON Sites hosted on their computer. This would therefore mean their web app site is publicly accessible. + +## Getting wallets support list + +To increase the overall adoption of TON Blockchain, it is necessary that TON Connect 2.0 is able to facilitate a vast number of application and wallet connectivity integrations. Of late and of significant importance, the ongoing development of TON Connect 2.0 has allowed for the connection of the Tonkeeper, TonHub, MyTonWallet and other wallets with various TON Ecosystem Apps. It is our mission to eventually allow for the exchange of data between applications and all wallet types built on TON via the TON Connect protocol. For now, this is realized by providing the ability for TON Connect to load an extensive list of available wallets currently operating within the TON Ecosystem. + +At the moment our sample web app enables the following: + +1. loads the TON Connect SDK (library meant to simplify integration), +2. creates a connector (currently without an application manifest), +3. loads a list of supported wallets (from [wallets.json on GitHub](https://raw.githubusercontent.com/ton-connect/wallets-list/main/wallets.json)). + +For learning purposes, let's take a looks at the HTML page described by the following code: + +```html + + + + + + + + + + +``` + +If you load this page in browser and look into console, you may get something like that: + +```bash +> Array [ {…}, {…} ] + +0: Object { name: "Tonkeeper", imageUrl: "https://tonkeeper.com/assets/tonconnect-icon.png", aboutUrl: "https://tonkeeper.com", … } + aboutUrl: "https://tonkeeper.com" + bridgeUrl: "https://bridge.tonapi.io/bridge" + deepLink: undefined + embedded: false + imageUrl: "https://tonkeeper.com/assets/tonconnect-icon.png" + injected: false + jsBridgeKey: "tonkeeper" + name: "Tonkeeper" + tondns: "tonkeeper.ton" + universalLink: "https://app.tonkeeper.com/ton-connect" +``` + +According to TON Connect 2.0 specifications, wallet app information always makes use of the following format: + +```js +{ + name: string; + imageUrl: string; + tondns?: string; + aboutUrl: string; + universalLink?: string; + deepLink?: string; + bridgeUrl?: string; + jsBridgeKey?: string; + injected?: boolean; // true if this wallet is injected to the webpage + embedded?: boolean; // true if the DAppis opened inside this wallet's browser +} +``` + +## Button display for various wallet apps + +Buttons may vary according to your web application design. +The current page produces the following result: + +```html + + + + + + + // highlight-start + + // highlight-end + + + // highlight-start +
+
+ // highlight-end + + + + +``` + +Please note the following: + +1. If the web page is displayed through a wallet application, it sets the property `embedded` option to `true`. This means it is important to highlight this login option because it's most commonly used. +2. If a specific wallet is built using only JavaScript (it has no `bridgeUrl`) and it hasn't set property `injected` (or `embedded`, for safety), then it is clearly inaccessible and the button should be disabled. + +## Connection without the app manifest + +In the instance the connection is made without the app manifest, the script should be changed as follows: + +```js + const $ = document.querySelector.bind(document); + + window.onload = async () => { + const connector = new TonConnectSDK.TonConnect(); + const walletsList = await connector.getWallets(); + + const unsubscribe = connector.onStatusChange( + walletInfo => { + console.log('Connection status:', walletInfo); + } + ); + + let buttonsContainer = $('#tonconnect-buttons'); + + for (let wallet of walletsList) { + let connectButton = document.createElement('button'); + connectButton.innerText = 'Connect with ' + wallet.name; + + if (wallet.embedded) { + // `embedded` means we are browsing the app from wallet application + // we need to mark this sign-in option somehow + connectButton.classList.add('featured'); + } + + // highlight-start + if (wallet.embedded || wallet.injected) { + connectButton.onclick = () => { + connectButton.disabled = true; + connector.connect({jsBridgeKey: wallet.jsBridgeKey}); + }; + } else if (wallet.bridgeUrl) { + connectButton.onclick = () => { + connectButton.disabled = true; + console.log('Connection link:', connector.connect({ + universalLink: wallet.universalLink, + bridgeUrl: wallet.bridgeUrl + })); + }; + } else { + // wallet app does not provide any auth method + connectButton.disabled = true; + } + // highlight-end + + buttonsContainer.appendChild(connectButton); + } + }; +``` + +Now that the above process has been carried out, status changes are being logged (to see whether TON Connect works or not). Showing the modals with QR codes for connectivity is out of the scope of this manual. For testing purposes, it is possible to use a browser extension or send a connection request link to the user’s phone by any means necessary (for example, using Telegram). +Note: we haven't created an app manifest yet. At this time, the best approach is to analyze the end result if this requirement is not fulfilled. + +### Logging in with Tonkeeper + +In order to log into Tonkeeper, the following link is created for authentication (provided below for reference): + +``` +https://app.tonkeeper.com/ton-connect?v=2&id=3c12f5311be7e305094ffbf5c9b830e53a4579b40485137f29b0ca0c893c4f31&r=%7B%22manifestUrl%22%3A%22null%2Ftonconnect-manifest.json%22%2C%22items%22%3A%5B%7B%22name%22%3A%22ton_addr%22%7D%5D%7D +``` + +When decoded, the `r` parameter produces the following JSON format: + +```js +{"manifestUrl":"null/tonconnect-manifest.json","items":[{"name":"ton_addr"}]} +``` + +Upon clicking the mobile phone link, Tonkeeper automatically opens and then closes, dismissing the request. Additionally, the following error appears in the web app page console: +`Error: [TON_CONNECT_SDK_ERROR] Can't get null/tonconnect-manifest.json`. + +This means the application manifest must be available for download. + +## Connection with using app manifest + +Starting from this point forward, it is necessary to host user files (mostly tonconnect-manifest.json) somewhere. In this instance we’ll use the manifest from another web application. This however is not recommended for production environments, but allowed for testing purposes. + +The following code snippet: + +```js + window.onload = async () => { + const connector = new TonConnectSDK.TonConnect(); + + const walletsList = await connector.getWallets(); + + const unsubscribe = connector.onStatusChange( + walletInfo => { + console.log('Connection status:', walletInfo); + } + ); +``` + +Must be replaced with this version: + +```js + window.onload = async () => { + const connector = new TonConnectSDK.TonConnect({manifestUrl: 'https://ratingers.pythonanywhere.com/ratelance/tonconnect-manifest.json'}); + // highlight-next-line + window.connector = connector; // for experimenting in browser console + + const walletsList = await connector.getWallets(); + + const unsubscribe = connector.onStatusChange( + walletInfo => { + console.log('Connection status:', walletInfo); + } + ); + // highlight-next-line + connector.restoreConnection(); +``` + +In the newer version above, the storing `connector` variable in the `window` was added so it is accessible in the browser console. Additionally, the `restoreConnection` so users don’t have to log in on each web application page. + +### Logging in with Tonkeeper + +If we decline our request from wallet, The result that appeared in the console will `Error: [TON_CONNECT_SDK_ERROR] Wallet declined the request`. + +Therefore, the user is able to accept the same login request if the link is saved. This means the web app should be able to handle the authentication decline as non-final so it works correctly. + +Afterwards, the login request is accepted and is immediately reflected in the browser console as follows: + +```bash +22:40:13.887 Connection status: +Object { device: {…}, provider: "http", account: {…} } + account: Object { address: "0:b2a1ec...", chain: "-239", walletStateInit: "te6cckECFgEAAwQAAgE0ARUBFP8A9..." } + device: Object {platform: "android", appName: "Tonkeeper", appVersion: "2.8.0.261", …} + provider: "http" +``` + +The results above take the following into consideration: + +1. **Account**: information: contains the address (workchain+hash), network (mainnet/testnet), and the wallet stateInit that is used for public key extraction. +2. **Device**: information: contains the name and wallet application version (the name should be equal to what was requested initially, but this can be verified to ensure authenticity), and the platform name and supported features list. +3. **Provider**: contains http -- which allows all requests and responses between the wallet and web applications to be served over the bridge. + +## Logging out and requesting TonProof + +Now we have logged into our Mini App, but... how does the backend know that it is the correct party? To verify this we must request the wallet ownership proof. + +This can be completed only using authentication, so we must log out. Therefore, we run the following code in the console: + +```js +connector.disconnect(); +``` + +When the disconnection process is complete, the `Connection status: null` will be displayed. + +Before the TonProof is added, let's alter the code to show that the current implementation is insecure: + +```js +let connHandler = connector.statusChangeSubscriptions[0]; +connHandler({ + device: { + appName: "Uber Singlesig Cold Wallet App", + appVersion: "4.0.1", + features: [], + maxProtocolVersion: 3, + platform: "ios" + }, + account: { + /* TON Foundation address */ + address: '0:83dfd552e63729b472fcbcc8c45ebcc6691702558b68ec7527e1ba403a0f31a8', + chain: '-239', + walletStateInit: 'te6ccsEBAwEAoAAFcSoCATQBAgDe/wAg3SCCAUyXuiGCATOcurGfcbDtRNDTH9MfMdcL/+ME4KTyYIMI1xgg0x/TH9Mf+CMTu/Jj7UTQ0x/TH9P/0VEyuvKhUUS68qIE+QFUEFX5EPKj+ACTINdKltMH1AL7AOjRAaTIyx/LH8v/ye1UAFAAAAAAKamjF3LJ7WtipuLroUqTuQRi56Nnd3vrijj7FbnzOETSLOL/HqR30Q==' + }, + provider: 'http' +}); +``` + +The resulting lines of code in the console are almost identical to those displayed when the connection was initiated in the first place. Therefore, if the backend doesn't perform user authentication correctly as expected, a way to test if it is working correctly is required. To accomplish this, it is possible to act as the TON Foundation within the console, so the legitimacy of token balances and token ownership parameters can be tested. Naturally, the provided code doesn't change any variables in the connector, but the user is able to use the app as desired unless that connector is protected by the closure. Even if that is the case, it is not difficult to extract it using a debugger and coding breakpoints. + +Now that the authentication of the user has been verified, let's proceed to writing the code. + +## Connection using TonProof + +According to TON Connect’s SDK documentation, the second argument refers to the `connect()` method which contains a payload that will be wrapped and signed by the wallet. Therefore, the result is new connection code: + +```js + if (wallet.embedded || wallet.injected) { + connectButton.onclick = () => { + connectButton.disabled = true; + connector.connect({jsBridgeKey: wallet.jsBridgeKey}, + {tonProof: 'doc-example-'}); + }; + } else if (wallet.bridgeUrl) { + connectButton.onclick = () => { + connectButton.disabled = true; + console.log('Connection link:', connector.connect({ + universalLink: wallet.universalLink, + bridgeUrl: wallet.bridgeUrl + }, {tonProof: 'doc-example-'})); + }; +``` + +Connection link: + +``` +https://app.tonkeeper.com/ton-connect?v=2&id=4b0a7e2af3b455e0f0bafe14dcdc93f1e9e73196ae2afaca4d9ba77e94484a44&r=%7B%22manifestUrl%22%3A%22https%3A%2F%2Fratingers.pythonanywhere.com%2Fratelance%2Ftonconnect-manifest.json%22%2C%22items%22%3A%5B%7B%22name%22%3A%22ton_addr%22%7D%2C%7B%22name%22%3A%22ton_proof%22%2C%22payload%22%3A%22doc-example-%3CBACKEND_AUTH_ID%3E%22%7D%5D%7D +``` + +Expanded and simplified `r` parameter: + +```js +{ + "manifestUrl": + "https://ratingers.pythonanywhere.com/ratelance/tonconnect-manifest.json", + "items": [ + {"name": "ton_addr"}, + {"name": "ton_proof", "payload": "doc-example-"} + ] +} +``` + +Next, the url address link is sent to a mobile device and opened using Tonkeeper. + +After this process is complete, the following wallet-specific information is received: + +```js +{ + "device": { + "platform": "android", + "appName": "Tonkeeper", + "appVersion": "2.8.0.261", + "maxProtocolVersion": 2, + "features": [ + "SendTransaction" + ] + }, + "provider": "http", + "account": { + "address": "0:b2a1ecf5545e076cd36ae516ea7ebdf32aea008caa2b84af9866becb208895ad", + "chain": "-239", + "walletStateInit": "te6cckECFgEAAwQAAgE0ARUBFP8A9KQT9LzyyAsCAgEgAxACAUgEBwLm0AHQ0wMhcbCSXwTgItdJwSCSXwTgAtMfIYIQcGx1Z70ighBkc3RyvbCSXwXgA/pAMCD6RAHIygfL/8nQ7UTQgQFA1yH0BDBcgQEI9ApvoTGzkl8H4AXTP8glghBwbHVnupI4MOMNA4IQZHN0crqSXwbjDQUGAHgB+gD0BDD4J28iMFAKoSG+8uBQghBwbHVngx6xcIAYUATLBSbPFlj6Ahn0AMtpF8sfUmDLPyDJgED7AAYAilAEgQEI9Fkw7UTQgQFA1yDIAc8W9ADJ7VQBcrCOI4IQZHN0coMesXCAGFAFywVQA88WI/oCE8tqyx/LP8mAQPsAkl8D4gIBIAgPAgEgCQ4CAVgKCwA9sp37UTQgQFA1yH0BDACyMoHy//J0AGBAQj0Cm+hMYAIBIAwNABmtznaiaEAga5Drhf/AABmvHfaiaEAQa5DrhY/AABG4yX7UTQ1wsfgAWb0kK29qJoQICga5D6AhhHDUCAhHpJN9KZEM5pA+n/mDeBKAG3gQFImHFZ8xhAT48oMI1xgg0x/TH9MfAvgju/Jk7UTQ0x/TH9P/9ATRUUO68qFRUbryogX5AVQQZPkQ8qP4ACSkyMsfUkDLH1Iwy/9SEPQAye1U+A8B0wchwACfbFGTINdKltMH1AL7AOgw4CHAAeMAIcAC4wABwAORMOMNA6TIyx8Syx/L/xESExQAbtIH+gDU1CL5AAXIygcVy//J0Hd0gBjIywXLAiLPFlAF+gIUy2sSzMzJc/sAyEAUgQEI9FHypwIAcIEBCNcY+gDTP8hUIEeBAQj0UfKnghBub3RlcHSAGMjLBcsCUAbPFlAE+gIUy2oSyx/LP8lz+wACAGyBAQjXGPoA0z8wUiSBAQj0WfKnghBkc3RycHSAGMjLBcsCUAXPFlAD+gITy2rLHxLLP8lz+wAACvQAye1UAFEAAAAAKamjFyM60x2mt5eboNyOTE+5RGOe9Ee2rK1Qcb+0ZuiP9vb7QJRlz/c=" + }, + "connectItems": { + "tonProof": { + "name": "ton_proof", + "proof": { + "timestamp": 1674392728, + "domain": { + "lengthBytes": 28, + "value": "ratingers.pythonanywhere.com" + }, + "signature": "trCkHit07NZUayjGLxJa6FoPnaGHkqPy2JyNjlUbxzcc3aGvsExCmHXi6XJGuoCu6M2RMXiLzIftEm6PAoy1BQ==", + "payload": "doc-example-" + } + } + } +} +``` + +서명을 검증하기 위해 Python을 사용할 수 있습니다. 이는 백엔드와 쉽게 상호작용할 수 있기 때문입니다. 이 과정을 수행하기 위해 필요한 라이브러리는 `tonsdk`와 `pynacl`입니다. + +Next, it is necessary to retrieve the wallet's public key. To accomplish this, `tonapi.io` or similar services are not used because the end result cannot be reliably trusted. Instead, this is accomplished by parsing the `walletStateInit`. + +It is also critical to ensure that the `address` and `walletStateInit` match, or the payload could be signed with their wallet key by providing their own wallet in the `stateInit` field and another wallet in the `address` field. + +The `StateInit` is made up of two reference types: one for code and one for data. In this context, the purpose is to retrieve the public key so the second reference (the data reference) is loaded. Then 8 bytes are skipped (4 bytes are used for the `seqno` field and 4 for `subwallet_id` in all modern wallet contracts) and the next 32 bytes are loaded (256 bits) -- the public key. + +```python +import nacl.signing +import tonsdk + +import hashlib +import base64 + +received_state_init = 'te6cckECFgEAAwQAAgE0ARUBFP8A9KQT9LzyyAsCAgEgAxACAUgEBwLm0AHQ0wMhcbCSXwTgItdJwSCSXwTgAtMfIYIQcGx1Z70ighBkc3RyvbCSXwXgA/pAMCD6RAHIygfL/8nQ7UTQgQFA1yH0BDBcgQEI9ApvoTGzkl8H4AXTP8glghBwbHVnupI4MOMNA4IQZHN0crqSXwbjDQUGAHgB+gD0BDD4J28iMFAKoSG+8uBQghBwbHVngx6xcIAYUATLBSbPFlj6Ahn0AMtpF8sfUmDLPyDJgED7AAYAilAEgQEI9Fkw7UTQgQFA1yDIAc8W9ADJ7VQBcrCOI4IQZHN0coMesXCAGFAFywVQA88WI/oCE8tqyx/LP8mAQPsAkl8D4gIBIAgPAgEgCQ4CAVgKCwA9sp37UTQgQFA1yH0BDACyMoHy//J0AGBAQj0Cm+hMYAIBIAwNABmtznaiaEAga5Drhf/AABmvHfaiaEAQa5DrhY/AABG4yX7UTQ1wsfgAWb0kK29qJoQICga5D6AhhHDUCAhHpJN9KZEM5pA+n/mDeBKAG3gQFImHFZ8xhAT48oMI1xgg0x/TH9MfAvgju/Jk7UTQ0x/TH9P/9ATRUUO68qFRUbryogX5AVQQZPkQ8qP4ACSkyMsfUkDLH1Iwy/9SEPQAye1U+A8B0wchwACfbFGTINdKltMH1AL7AOgw4CHAAeMAIcAC4wABwAORMOMNA6TIyx8Syx/L/xESExQAbtIH+gDU1CL5AAXIygcVy//J0Hd0gBjIywXLAiLPFlAF+gIUy2sSzMzJc/sAyEAUgQEI9FHypwIAcIEBCNcY+gDTP8hUIEeBAQj0UfKnghBub3RlcHSAGMjLBcsCUAbPFlAE+gIUy2oSyx/LP8lz+wACAGyBAQjXGPoA0z8wUiSBAQj0WfKnghBkc3RycHSAGMjLBcsCUAXPFlAD+gITy2rLHxLLP8lz+wAACvQAye1UAFEAAAAAKamjFyM60x2mt5eboNyOTE+5RGOe9Ee2rK1Qcb+0ZuiP9vb7QJRlz/c=' +received_address = '0:b2a1ecf5545e076cd36ae516ea7ebdf32aea008caa2b84af9866becb208895ad' + +state_init = tonsdk.boc.Cell.one_from_boc(base64.b64decode(received_state_init)) + +address_hash_part = base64.b16encode(state_init.bytes_hash()).decode('ascii').lower() +assert received_address.endswith(address_hash_part) + +public_key = state_init.refs[1].bits.array[8:][:32] + +print(public_key) +# bytearray(b'#:\xd3\x1d\xa6\xb7\x97\x9b\xa0\xdc\x8eLO\xb9Dc\x9e\xf4G\xb6\xac\xadPq\xbf\xb4f\xe8\x8f\xf6\xf6\xfb') + +verify_key = nacl.signing.VerifyKey(bytes(public_key)) +``` + +After the sequencing code above is implemented, the correct documentation is consulted to check which parameters are verified and signed using the wallet key: + +> ``` +> message = utf8_encode("ton-proof-item-v2/") ++ +> Address ++ +> AppDomain ++ +> Timestamp ++ +> Payload +> +> signature = Ed25519Sign( +> privkey, +> sha256(0xffff ++ utf8_encode("ton-connect") ++ sha256(message)) +> ) +> ``` + +> Whereby the: +> +> - `Address` denotes the wallet address encoded as a sequence: +> - `workchain`: 32-bit signed integer big endian; +> - `hash`: 256-bit unsigned integer big endian; +> - `AppDomain` is the Length ++ EncodedDomainName +> - `Length` uses a 32-bit value of utf-8 encoded app domain name length in bytes +> - `EncodedDomainName` id `Length`-byte utf-8 encoded app domain name +> - `Timestamp` denotes the 64-bit unix epoch time of the signing operation +> - `Payload` denotes a variable-length binary string +> - `utf8_encode` produces a plain byte string with no length prefixes. + +Let's reimplement this in Python. The endianness of some of the integers above is not specified, so several examples must be considered. Please refer to the following Tonkeeper implementation detailing some related examples: : [ConnectReplyBuilder.ts](https://github.com/tonkeeper/wallet/blob/77992c08c663dceb63ca6a8e918a2150c75cca3a/src/tonconnect/ConnectReplyBuilder.ts#L42). + +```python +received_timestamp = 1674392728 +signature = 'trCkHit07NZUayjGLxJa6FoPnaGHkqPy2JyNjlUbxzcc3aGvsExCmHXi6XJGuoCu6M2RMXiLzIftEm6PAoy1BQ==' + +message = (b'ton-proof-item-v2/' + + 0 .to_bytes(4, 'big') + si.bytes_hash() + + 28 .to_bytes(4, 'little') + b'ratingers.pythonanywhere.com' + + received_timestamp.to_bytes(8, 'little') + + b'doc-example-') +# b'ton-proof-item-v2/\x00\x00\x00\x00\xb2\xa1\xec\xf5T^\x07l\xd3j\xe5\x16\xea~\xbd\xf3*\xea\x00\x8c\xaa+\x84\xaf\x98f\xbe\xcb \x88\x95\xad\x1c\x00\x00\x00ratingers.pythonanywhere.com\x984\xcdc\x00\x00\x00\x00doc-example-' + +signed = b'\xFF\xFF' + b'ton-connect' + hashlib.sha256(message).digest() +# b'\xff\xffton-connectK\x90\r\xae\xf6\xb0 \xaa\xa9\xbd\xd1\xaa\x96\x8b\x1fp\xa9e\xff\xdf\x81\x02\x98\xb0)E\t\xf6\xc0\xdc\xfdx' + +verify_key.verify(hashlib.sha256(signed).digest(), base64.b64decode(signature)) +# b'\x0eT\xd6\xb5\xd5\xe8HvH\x0b\x10\xdc\x8d\xfc\xd3#n\x93\xa8\xe9\xb9\x00\xaaH%\xb5O\xac:\xbd\xcaM' +``` + +After implementing the above parameters, if an attacker tries to impersonate a user and doesn't provide a valid signature, the following error will be displayed: `nacl.exceptions.BadSignatureError: Signature was forged or corrupt`. + +## Next steps + +When writing a dApp, the following should also be considered: + +- after a successful connection is completed (either a restored or new connection), the `Disconnect` button should be displayed instead of several `Connect` buttons +- after a user disconnects, `Disconnect` buttons will need to be recreated +- wallet code should be checked, because + - newer wallet versions could place public keys in a different location and create issues + - the current user may sign in using another type of contract instead of a wallet. Thankfully, this will contain the public key in the expected location + +Good luck and have fun writing dApps! From 5d42e2b5ee19640d0b50a1d3f824d704b385d669 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:57:36 +0800 Subject: [PATCH 37/41] New translations message-builders.mdx (Korean) --- .../dapps/ton-connect/message-builders.mdx | 1798 +++++++++++++++++ 1 file changed, 1798 insertions(+) create mode 100644 i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/message-builders.mdx diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/message-builders.mdx b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/message-builders.mdx new file mode 100644 index 0000000000..5ac1958434 --- /dev/null +++ b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/message-builders.mdx @@ -0,0 +1,1798 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Preparing Messages + +While using TON Connect, you should construct the Message Body for the Payload used in various transactions. On this page you can find the most relevant examples of payload for use with the TON Connect SDKs. + +:::info +It is expected, that you learn basics on the creating TON Connect connection. Learn more with the [integration manual](/develop/dapps/ton-connect/integration). +::: + +## TON Connect JS SDK Examples + +### Transaction Template + +No matter what level of the task developer are solving, typically it is necessary to use connector entity from @tonconnect/sdk or @tonconnect/ui. +Examples created based on @tonconnect/sdk and @tonconnect/ui: + + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; +const [tonConnectUI] = useTonConnectUI(); + +const transaction = { + //transaction body +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + +
+ + +```js +import TonConnectUI from '@tonconnect/ui'; + +const tonConnectUI = new TonConnectUI({ //connect application + manifestUrl: 'https:///tonconnect-manifest.json', + buttonRootId: '' +}); + +const transaction = { + //transaction body +} + +const result = await tonConnectUI.sendTransaction(transaction) + +``` + + + + +```js +import TonConnect from '@tonconnect/sdk'; +const connector = new TonConnect(); + +await connector.sendTransaction({ + //transaction body +}) + +``` + + + +
+ +### Regular TON Transfer + +TON Connect SDKs include wrappers for sending messages, making it easy to prepare regular transfers of Toncoins between two wallets as default transaction without payload. + +A regular TON transfer using the TON Connect JS SDKs can be executed as follows: + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; +const [tonConnectUI] = useTonConnectUI(); + +const transaction = { + messages: [ + { + address: "0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F", // destination address + amount: "20000000" //Toncoin in nanotons + } + ] + +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + +
+ + + +```js +import TonConnectUI from '@tonconnect/ui'; + +const tonConnectUI = new TonConnectUI({ //connect application + manifestUrl: 'https:///tonconnect-manifest.json', + buttonRootId: '' +}); + +const transaction = { + messages: [ + { + address: "0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F", // destination address + amount: "20000000" //Toncoin in nanotons + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + + +```js +import TonConnect from '@tonconnect/sdk'; +const connector = new TonConnect(); + +await connector.sendTransaction({ + messages: [ + { + address: "0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F", // destination address + amount: "20000000" //Toncoin in nanotons + } + ] +}) + +``` + + +
+ +:::tip +Learn more about [TON Smart Contract Addresses](/learn/overviews/addresses). +::: + +For specific custom transaction, a certain payload must be defined. + +### Transfer With a Comment + +The simplest example is adding a payload with a comment. See more details on [this page](/develop/smart-contracts/guidelines/internal-messages#simple-message-with-comment). +Before transaction, it is necessary prepare a `body` [cell](/develop/data-formats/cell-boc) via the [@ton/ton](https://github.com/ton-org/ton) JavaScript library. + +```js +import { beginCell } from '@ton/ton' + +const body = beginCell() + .storeUint(0, 32) // write 32 zero bits to indicate that a text comment will follow + .storeStringTail("Hello, TON!") // write our text comment + .endCell(); +``` + +The transaction body is created by the following: + + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; +import { toNano } from '@ton/ton' + +const myTransaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: destination, + amount: toNano(0.05).toString(), + payload: body.toBoc().toString("base64") // payload with comment in body + } + ] +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + +
+ + + +```js +import TonConnectUI from '@tonconnect/ui' +import { toNano } from '@ton/ton' + +const transaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: destination, + amount: toNano(0.05).toString(), + payload: body.toBoc().toString("base64") // payload with comment in body + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + + +```js +import TonConnect from '@tonconnect/sdk'; +import { toNano } from '@ton/ton' + +const connector = new TonConnect(); + +await connector.sendTransaction({ + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: destination, + amount: toNano(0.05).toString(), + payload: body.toBoc().toString("base64") // payload with comment in body + } + ] +}) +``` + + +
+ +### Jetton Transfer + +`Jetton Transfer`([TEP-74](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md#1-transfer))의 `body`는 일반적으로 다음과 같은 방식으로 작성되어야 합니다: + +```js + import { beginCell, toNano, Address } from '@ton/ton' + // transfer#0f8a7ea5 query_id:uint64 amount:(VarUInteger 16) destination:MsgAddress + // response_destination:MsgAddress custom_payload:(Maybe ^Cell) + // forward_ton_amount:(VarUInteger 16) forward_payload:(Either Cell ^Cell) + // = InternalMsgBody; + + const body = beginCell() + .storeUint(0xf8a7ea5, 32) // jetton transfer op code + .storeUint(0, 64) // query_id:uint64 + .storeCoins(1000000) // amount:(VarUInteger 16) - Jetton amount for transfer (decimals = 6 - jUSDT, 9 - default) + .storeAddress(Address.parse(Wallet_DST)) // destination:MsgAddress + .storeAddress(Address.parse(Wallet_SRC)) // response_destination:MsgAddress + .storeUint(0, 1) // custom_payload:(Maybe ^Cell) + .storeCoins(toNano(0.05)) // forward_ton_amount:(VarUInteger 16) - if >0, will send notification message + .storeUint(0,1) // forward_payload:(Either Cell ^Cell) + .endCell(); +``` + +Next, sending the transaction with this body to sender's jettonWalletContract executed: + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; +import { toNano } from '@ton/ton' + +const myTransaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // sender jetton wallet + amount: toNano(0.05).toString(), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with jetton transfer body + } + ] +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + +
+ + + +```js +import TonConnectUI from '@tonconnect/ui' +import { toNano } from '@ton/ton' + +const transaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // sender jetton wallet + amount: toNano(0.05).toString(), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with jetton transfer body + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + + +```js +import TonConnect from '@tonconnect/sdk'; +import { toNano } from '@ton/ton' + +const connector = new TonConnect(); +//... +await connector.sendTransaction({ + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // sender jetton wallet + amount: toNano(0.05).toString(), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with jetton transfer body + } + ] +}) +``` + + +
+ +- `validUntil` - UNIX-time until message valid +- `jettonWalletAddress` - Address, JettonWallet address, that defined based on JettonMaser and Wallet contracts +- `balance` - Integer, amount of Toncoin for gas payments in nanotons. +- `body` - payload for the jettonContract + +
+ Jetton Wallet State Init and Address preparation example + +```js +import { Address, TonClient, beginCell, StateInit, storeStateInit } from '@ton/ton' + +async function main() { + const client = new TonClient({ + endpoint: 'https://toncenter.com/api/v2/jsonRPC', + apiKey: 'put your api key' + }) + + const jettonWalletAddress = Address.parse('Sender_Jetton_Wallet'); + let jettonWalletDataResult = await client.runMethod(jettonWalletAddress, 'get_wallet_data'); + jettonWalletDataResult.stack.readNumber(); + const ownerAddress = jettonWalletDataResult.stack.readAddress(); + const jettonMasterAddress = jettonWalletDataResult.stack.readAddress(); + const jettonCode = jettonWalletDataResult.stack.readCell(); + const jettonData = beginCell() + .storeCoins(0) + .storeAddress(ownerAddress) + .storeAddress(jettonMasterAddress) + .storeRef(jettonCode) + .endCell(); + + const stateInit: StateInit = { + code: jettonCode, + data: jettonData + } + + const stateInitCell = beginCell() + .store(storeStateInit(stateInit)) + .endCell(); + + console.log(new Address(0, stateInitCell.hash())); +} +``` + +
+ +### Jetton Transfer with Comment + +`Jetton Transfer`([TEP-74](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md#1-transfer))에서 `messageBody`에 댓글을 추가하려면, 일반적인 전송 `body`에 더해 댓글을 직렬화하고 이를 `forwardPayload`에 포함시켜야 합니다. + +```js + import { beginCell, toNano, Address } from '@ton/ton' + // transfer#0f8a7ea5 query_id:uint64 amount:(VarUInteger 16) destination:MsgAddress + // response_destination:MsgAddress custom_payload:(Maybe ^Cell) + // forward_ton_amount:(VarUInteger 16) forward_payload:(Either Cell ^Cell) + // = InternalMsgBody; + + const destinationAddress = Address.parse('put destination wallet address'); + + const forwardPayload = beginCell() + .storeUint(0, 32) // 0 opcode means we have a comment + .storeStringTail('Hello, TON!') + .endCell(); + + const body = beginCell() + .storeUint(0xf8a7ea5, 32) // opcode for jetton transfer + .storeUint(0, 64) // query id + .storeCoins(toNano(5)) // jetton amount, amount * 10^9 + .storeAddress(destinationAddress) // TON wallet destination address + .storeAddress(destinationAddress) // response excess destination + .storeBit(0) // no custom payload + .storeCoins(toNano(0.02).toString()) // forward amount (if >0, will send notification message) + .storeBit(1) // we store forwardPayload as a reference + .storeRef(forwardPayload) + .endCell(); + +``` + +Next, sending the transaction with this body to sender's jettonWalletContract executed: + + + + +```js + import { useTonConnectUI } from '@tonconnect/ui-react'; + import { toNano } from '@ton/ton' + + + const jettonWalletContract = Address.parse('put your jetton wallet address'); + + const myTransaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // sender jetton wallet + amount: toNano(0.05).toString(), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with jetton transfer and comment body + } + ] + } + + export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+); +}; +``` + +
+ + + +```js + import TonConnectUI from '@tonconnect/ui' + import { toNano } from '@ton/ton' + + const transaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ +{ + address: jettonWalletContract, // sender jetton wallet + amount: toNano(0.05).toString(), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with jetton transfer and comment body +} + ] +} + + const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + + +```js + import TonConnect from '@tonconnect/sdk'; + import { toNano } from '@ton/ton' + + const connector = new TonConnect(); + //... + await connector.sendTransaction({ + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ +{ + address: jettonWalletContract, // sender jetton wallet + amount: toNano(0.05).toString(), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with jetton transfer and comment body +} + ] +}) +``` + + +
+ +- `validUntil` - UNIX-time until message valid +- `jettonWalletAddress` - Address, JettonWallet address, that defined based on JettonMaser and Wallet contracts +- `balance` - Integer, amount of Toncoin for gas payments in nanotons. +- `body` - payload for the jettonContract + +
+ Jetton Wallet State Init and Address preparation example + +```js + import { Address, TonClient, beginCell, StateInit, storeStateInit } from '@ton/ton' + + async function main() { + const client = new TonClient({ + endpoint: 'https://toncenter.com/api/v2/jsonRPC', + apiKey: 'put your api key' +}) + + const jettonWalletAddress = Address.parse('Sender_Jetton_Wallet'); + let jettonWalletDataResult = await client.runMethod(jettonWalletAddress, 'get_wallet_data'); + jettonWalletDataResult.stack.readNumber(); + const ownerAddress = jettonWalletDataResult.stack.readAddress(); + const jettonMasterAddress = jettonWalletDataResult.stack.readAddress(); + const jettonCode = jettonWalletDataResult.stack.readCell(); + const jettonData = beginCell() + .storeCoins(0) + .storeAddress(ownerAddress) + .storeAddress(jettonMasterAddress) + .storeRef(jettonCode) + .endCell(); + + const stateInit: StateInit = { + code: jettonCode, + data: jettonData +} + + const stateInitCell = beginCell() + .store(storeStateInit(stateInit)) + .endCell(); + + console.log(new Address(0, stateInitCell.hash())); +} +``` + +
+ +### Jetton Burn + +`Jetton Burn`([TEP-74](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md#2-burn))의 `body`는 일반적으로 다음과 같은 방식으로 작성되어야 합니다: + +```js + import { beginCell, Address } from '@ton/ton' +// burn#595f07bc query_id:uint64 amount:(VarUInteger 16) +// response_destination:MsgAddress custom_payload:(Maybe ^Cell) +// = InternalMsgBody; + + const body = beginCell() + .storeUint(0x595f07bc, 32) // jetton burn op code + .storeUint(0, 64) // query_id:uint64 + .storeCoins(1000000) // amount:(VarUInteger 16) - Jetton amount in decimal + .storeAddress(Address.parse(Wallet_SRC)) // response_destination:MsgAddress - owner's wallet + .storeUint(0, 1) // custom_payload:(Maybe ^Cell) - w/o payload typically + .endCell(); +``` + +Message places into the following request: + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; +import { toNano } from '@ton/ton' + +const myTransaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // owner's jetton wallet + amount: toNano(0.05).toString(), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with a jetton burn body + } + ] +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + +
+ + + +```js +import TonConnectUI from '@tonconnect/ui' +import { toNano } from '@ton/ton' + +const transaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // owner's jetton wallet + amount: toNano(0.05).toString(), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with a jetton burn body + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + + +```js +await connector.sendTransaction({ + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // owner's jetton wallet + amount: toNano(0.05).toString(), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with a jetton burn body + } + ] +}) +``` + + +
+ +- `jettonWalletAddress` - Jetton Wallet contract address, that defined based on JettonMaser and Wallet contracts +- `amount` - Integer, amount of Toncoin for gas payments in nanotons. +- `body` - payload for the jetton wallet with the `burn#595f07bc` op code + +### NFT Transfer + +The `body` message typically should be done according the following way: + +```js +import { beginCell, toNano } from '@ton/ton' + +// transfer#5fcc3d14 query_id:uint64 new_owner:MsgAddress response_destination:MsgAddress custom_payload:(Maybe ^Cell) +// forward_amount:(VarUInteger 16) forward_payload:(Either Cell ^Cell) = InternalMsgBody; + + const body = beginCell() + .storeUint(0x5fcc3d14, 32) // NFT transfer op code 0x5fcc3d14 + .storeUint(0, 64) // query_id:uint64 + .storeAddress(Address.parse(NEW_OWNER_WALLET)) // new_owner:MsgAddress + .storeAddress(Address.parse(Wallet_DST)) // response_destination:MsgAddress + .storeUint(0, 1) // custom_payload:(Maybe ^Cell) + .storeCoins(toNano(0.000000001).toString()) // forward_amount:(VarUInteger 16) + .storeUint(0,1) // forward_payload:(Either Cell ^Cell) + .endCell(); +``` + +`WALLET_DST` - Address - The address of the initial NFT owner for the receiving excess +Transfer the `NFTitem` to a new owner `NEW_OWNER_WALLET`. + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; +import { toNano } from '@ton/ton' + +const myTransaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // NFT Item address, which will be transferred + amount: toNano(0.05).toString(), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with a NFT transfer body + } + ] +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + +
+ + + +```js +import TonConnectUI from '@tonconnect/ui' +import { toNano } from '@ton/ton' + +const transaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: NFTitem, // NFT Item address, which will be transferred + amount: toNano(0.05).toString(), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with a NFT transfer body + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + + +```js +await connector.sendTransaction({ + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: NFTitem, // NFT Item address, which will be transferred + amount: toNano(0.05).toString(), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with a NFT transfer body + } + ] +}) +``` + + +
+ +- `NFTitem` - Address - The address of NFT item smart contract which we want transfer to a new owner `NEW_OWNER_WALLET`. +- `balance` - Integer, amount of Toncoin for gas payments in nanotons. +- `body` - payload for the NFT contract + +### NFT Sale (GetGems) + +여기 GetGems 마켓플레이스에서 [nft-fixprice-sale-v3r2](https://github.com/getgems-io/nft-contracts/blob/main/packages/contracts/sources/nft-fixprice-sale-v3r2.fc) 계약에 따라 메시지와 거래를 준비하는 예시가 있습니다. + +To place NFT on GetGems Sale Contract, we should prepare special message body `transferNftBody` that will be transfer NFT to special NFT Sale Contract. + +```js + const transferNftBody = beginCell() + .storeUint(0x5fcc3d14, 32) // Opcode for NFT transfer + .storeUint(0, 64) // query_id + .storeAddress(Address.parse(destinationAddress)) // new_owner - GetGems sale contracts deployer, should never change for this operation + .storeAddress(Address.parse(walletAddress)) // response_destination for excesses + .storeBit(0) // we do not have custom_payload + .storeCoins(toNano(1).toString()) // forward_amount + .storeBit(0) // we store forward_payload is this cell + .storeUint(0x0fe0ede, 31) // not 32, because previous 0 will be read as do_sale opcode in deployer + .storeRef(stateInitCell) + .storeRef(saleBody) + .endCell(); +``` + +Because message requires a lot of steps, the entire algorithm huge and could be found here: + +
+ Show entire algorithm for the creating NFT Sale message body + +```js +import { Address, beginCell, StateInit, storeStateInit, toNano, Cell } from '@ton/ton' + +async function main() { + const fixPriceV3R2Code = Cell.fromBase64('te6cckECCwEAArkAART/APSkE/S88sgLAQIBIAIDAgFIBAUAfvIw7UTQ0wDTH/pA+kD6QPoA1NMAMMABjh34AHAHyMsAFssfUATPFljPFgHPFgH6AszLAMntVOBfB4IA//7y8AICzQYHAFegOFnaiaGmAaY/9IH0gfSB9AGppgBgYaH0gfQB9IH0AGEEIIySsKAVgAKrAQH30A6GmBgLjYSS+CcH0gGHaiaGmAaY/9IH0gfSB9AGppgBgYOCmE44BgAEqYhOmPhW8Q4YBKGATpn8cIxbMbC3MbK2QV44LJOZlvKAVxFWAAyS+G8BJrpOEBFcCBFd0VYACRWdjYKdxjgthOjq+G6hhoaYPqGAD9gHAU4ADAgB92YIQO5rKAFJgoFIwvvLhwiTQ+kD6APpA+gAwU5KhIaFQh6EWoFKQcIAQyMsFUAPPFgH6AstqyXH7ACXCACXXScICsI4XUEVwgBDIywVQA88WAfoCy2rJcfsAECOSNDTiWnCAEMjLBVADzxYB+gLLaslx+wBwIIIQX8w9FIKAejy0ZSzjkIxMzk5U1LHBZJfCeBRUccF8uH0ghAFE42RFrry4fUD+kAwRlAQNFlwB8jLABbLH1AEzxZYzxYBzxYB+gLMywDJ7VTgMDcowAPjAijAAJw2NxA4R2UUQzBw8AXgCMACmFVEECQQI/AF4F8KhA/y8AkA1Dg5ghA7msoAGL7y4clTRscFUVLHBRWx8uHKcCCCEF/MPRQhgBDIywUozxYh+gLLassfFcs/J88WJ88WFMoAI/oCE8oAyYMG+wBxUGZFFQRwB8jLABbLH1AEzxZYzxYBzxYB+gLMywDJ7VQAlsjLHxPLPyPPFlADzxbKAIIJycOA+gLKAMlxgBjIywUmzxZw+gLLaszJgwb7AHFVUHAHyMsAFssfUATPFljPFgHPFgH6AszLAMntVNZeZYk='); + + const marketplaceAddress = Address.parse('EQBYTuYbLf8INxFtD8tQeNk5ZLy-nAX9ahQbG_yl1qQ-GEMS'); // GetGems Address + const marketplaceFeeAddress = Address.parse('EQCjk1hh952vWaE9bRguFkAhDAL5jj3xj9p0uPWrFBq_GEMS'); // GetGems Address for Fees + const destinationAddress = Address.parse("EQAIFunALREOeQ99syMbO6sSzM_Fa1RsPD5TBoS0qVeKQ-AR"); // GetGems sale contracts deployer + + const walletAddress = Address.parse('EQArLGBnGPvkxaJE57Y6oS4rwzDWuOE8l8_sghntXLkIt162'); + const royaltyAddress = Address.parse('EQArLGBnGPvkxaJE57Y6oS4rwzDWuOE8l8_sghntXLkIt162'); + const nftAddress = Address.parse('EQCUWoe7hLlklVxH8gduCf45vPNocsjRP4wbX42UJ0Ja0S2f'); + const price = toNano(5).toString(); // 5 TON + + const feesData = beginCell() + .storeAddress(marketplaceFeeAddress) + // 5% - GetGems fee + .storeCoins(price / BigInt(100) * BigInt(5)) + .storeAddress(royaltyAddress) + // 5% - Royalty, can be changed + .storeCoins(price / BigInt(100) * BigInt(5)) + .endCell(); + + const saleData = beginCell() + .storeBit(0) // is_complete + .storeUint(Math.round(Date.now() / 1000), 32) // created_at + .storeAddress(marketplaceAddress) // marketplace_address + .storeAddress(nftAddress) // nft_address + .storeAddress(walletAddress) // previous_owner_address + .storeCoins(price) // full price in nanotons + .storeRef(feesData) // fees_cell + .storeBit(0) // can_be_deployed_externally + .endCell(); + + const stateInit: StateInit = { + code: fixPriceV3R2Code, + data: saleData + }; + const stateInitCell = beginCell() + .store(storeStateInit(stateInit)) + .endCell(); + + // not needed, just for example + const saleContractAddress = new Address(0, stateInitCell.hash()); + + const saleBody = beginCell() + .storeUint(1, 32) // just accept coins on deploy + .storeUint(0, 64) + .endCell(); + + const transferNftBody = beginCell() + .storeUint(0x5fcc3d14, 32) // Opcode for NFT transfer + .storeUint(0, 64) // query_id + .storeAddress(destinationAddress) // new_owner + .storeAddress(walletAddress) // response_destination for excesses + .storeBit(0) // we do not have custom_payload + .storeCoins(toNano(1).toString()) // forward_amount + .storeBit(0) // we store forward_payload is this cell + // not 32, because we stored 0 bit before | do_sale opcode for deployer + .storeUint(0x0fe0ede, 31) + .storeRef(stateInitCell) + .storeRef(saleBody) + .endCell(); +} +``` + +
+ +Prepared `transferNftBody` should be sent to the NFT Item Contract with at least `1.08` TON, that expected for success processing. Excess will be returned to a sender's wallet. + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; +import { toNano } from '@ton/ton' + +const myTransaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: NFTitem, //address of the NFT Item contract, that should be placed on market + amount: toNano(1.08).toString(), // amount that will require on gas fees, excess will be return + payload: transferNftBody.toBoc().toString("base64") // payload with the transferNftBody message + } + ] +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + +
+ + + +```js +import TonConnectUI from '@tonconnect/ui' +import { toNano } from '@ton/ton' + +const transaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: NFTitem, //address of NFT Item contract, that should be placed on market + amount: toNano(1.08).toString(), // amount that will require on gas fees, excess will be return + payload: transferNftBody.toBoc().toString("base64") // payload with the transferNftBody message + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + + +```js +await connector.sendTransaction({ + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: NFTitem, //address of NFT Item contract, that should be placed on market + amount: toNano(1.08).toString(), // amount that will require on gas fees, excess will be return + payload: transferNftBody.toBoc().toString("base64") // payload with the transferNftBody message + } + ] +}) +``` + + +
+ +### NFT Buy (GetGems) + +[nft-fixprice-sale-v3r2](https://github.com/getgems-io/nft-contracts/blob/main/packages/contracts/sources/nft-fixprice-sale-v3r2.fc) 판매 계약에서 NFT를 구매하는 과정은 페이로드가 없는 일반적인 전송으로 수행할 수 있으며, 중요한 것은 정확한 TON 금액입니다. 그 금액은 다음과 같이 계산됩니다:\ +`buyAmount = Nftprice TON + 1.0 TON` + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; +import { toNano } from '@ton/ton' + +const myTransaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: nftSaleContract, // NFT Sale contract, that is current desired NFT Item + amount: toNano(buyAmount), // NFT Price + exactly 1 TON, excess will be returned + } + ] +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + +
+ + + +```js +import TonConnectUI from '@tonconnect/ui' +import { toNano } from '@ton/ton' + +const transaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: nftSaleContract, // NFT Sale contract, that is current desired NFT Item + amount: toNano(buyAmount), // NFT Price + exactly 1 TON, excess will be returned + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + +```js +await connector.sendTransaction({ +validUntil: Math.floor(Date.now() / 1000) + 360, +messages: [ + { + address: nftSaleContract, // NFT Sale contract, that is current desired NFT Item + amount: toNano(buyAmount), // NFT Price + exactly 1 TON, excess will be returned + } +] +}) +``` + + +
+ +## TON Connect Python SDK + +Python examples are using [PyTonConnect](https://github.com/XaBbl4/pytonconnect) and [pytoniq](https://github.com/yungwine/pytoniq). + +```python + from pytoniq_core import Address + from pytonconnect import TonConnect +``` + +:::tip +Read examples [source](https://github.com/yungwine/ton-connect-examples/blob/master/main.py). +::: + +### Regular TON Transfer + +```python +connector = TonConnect( + manifest_url='https://raw.githubusercontent.com/XaBbl4/pytonconnect/main/pytonconnect-manifest.json') +is_connected = await connector.restore_connection() + +transaction = { + 'valid_until': int(time.time() + 3600), + 'messages': [ + { + 'address' :'0:0000000000000000000000000000000000000000000000000000000000000000', # destination address + 'amount' : 1000000000, # amount should be specified in nanocoins, 1 TON + } + ] +} +``` + +### Transfer With Comment + +At first order, implement a message with comment via the following function: + +```python + def get_comment_message(destination_address: str, amount: int, comment: str) -> dict: + + data = { + 'address': destination_address, + 'amount': str(amount), + 'payload': urlsafe_b64encode( + begin_cell() + .store_uint(0, 32) # op code for comment message + .store_string(comment) # store comment + .end_cell() # end cell + .to_boc() # convert it to boc + ) + .decode() # encode it to urlsafe base64 + } + + return data +``` + +Final transaction body for transfer with comment: + +```python +transaction = { + 'valid_until': int(time.time() + 3600), + 'messages': [ + get_comment_message( + destination_address='0:0000000000000000000000000000000000000000000000000000000000000000', + amount=int(0.01 * 10**9), # amount should be specified in nanocoins + comment='hello world!' + ) + ] +} +``` + +:::tip +Learn more about [TON Smart Contract Addresses](/learn/overviews/addresses). +::: + +### Jetton Transfer + +Jetton 전송 거래를 생성하는 함수 예시: + +```python +from pytoniq_core import begin_cell +from base64 import urlsafe_b64encode + +def get_jetton_transfer_message(jetton_wallet_address: str, recipient_address: str, transfer_fee: int, jettons_amount: int, response_address: str = None) -> dict: + data = { + 'address': jetton_wallet_address, + 'amount': str(transfer_fee), + 'payload': urlsafe_b64encode( + begin_cell() + .store_uint(0xf8a7ea5, 32) # op code for jetton transfer message + .store_uint(0, 64) # query_id + .store_coins(jettons_amount) + .store_address(recipient_address) # destination address + .store_address(response_address or recipient_address) # address send excess to + .store_uint(0, 1) # custom payload + .store_coins(1) # forward amount + .store_uint(0, 1) # forward payload + .end_cell() # end cell + .to_boc() # convert it to boc + ) + .decode() # encode it to urlsafe base64 + } + + return data +``` + +Final transaction body: + +```python +transaction = { + 'valid_until': int(time.time() + 3600), + 'messages': [ + get_jetton_transfer_message( + jetton_wallet_address='EQCXsVvdxTVmSIvYv4tTQoQ-0Yq9mERGTKfbsIhedbN5vTVV', + recipient_address='0:0000000000000000000000000000000000000000000000000000000000000000', + transfer_fee=int(0.07 * 10**9), + jettons_amount=int(0.01 * 10**9), # replace 9 for jetton decimal. For example for jUSDT it should be (amount * 10**6) + response_address=wallet_address + ), + ] +} + +``` + +### Jetton Burn + +Jetton 소각 거래를 생성하는 함수 예시: + +```python +from pytoniq_core import begin_cell +from base64 import urlsafe_b64encode + +def get_jetton_burn_message(jetton_wallet_address: str, transfer_fee: int, jettons_amount: int, response_address: str = None) -> dict: + data = { + 'address': jetton_wallet_address, + 'amount': str(transfer_fee), + 'payload': urlsafe_b64encode( + begin_cell() + .store_uint(0x595f07bc, 32) # op code for jetton burn message + .store_uint(0, 64) # query_id + .store_coins(jettons_amount) + .store_address(response_address) # address send excess to + .end_cell() # end cell + .to_boc() # convert it to boc + ) + .decode() # encode it to urlsafe base64 + } + return data +``` + +The final transaction body: + +```python +transaction = { + 'valid_until': int(time.time() + 3600), + 'messages': [ + get_jetton_burn_message( + jetton_wallet_address='EQCXsVvdxTVmSIvYv4tTQoQ-0Yq9mERGTKfbsIhedbN5vTVV', + transfer_fee=int(0.07 * 10 ** 9), + jettons_amount=int(0.01 * 10 ** 9), # replace 9 for jetton decimal. For example for jUSDT it should be (amount * 10**6) + response_address=wallet_address + ), + ] +} +``` + +### NFT Transfer + +Example of function for a NFT transfer transaction: + +```python +from pytoniq_core import begin_cell +from base64 import urlsafe_b64encode + + +def get_nft_transfer_message(nft_address: str, recipient_address: str, transfer_fee: int, response_address: str = None) -> dict: + data = { + 'address': nft_address, + 'amount': str(transfer_fee), + 'payload': urlsafe_b64encode( + begin_cell() + .store_uint(0x5fcc3d14, 32) # op code for nft transfer message + .store_uint(0, 64) # query_id + .store_address(recipient_address) # new owner + .store_address(response_address or recipient_address) # address send excess to + .store_uint(0, 1) # custom payload + .store_coins(1) # forward amount + .store_uint(0, 1) # forward payload + .end_cell() # end cell + .to_boc() # convert it to boc + ) + .decode() # encode it to urlsafe base64 + } + return data + +``` + +The final transaction body: + +```python +transaction = { + 'valid_until': int(time.time() + 3600), + 'messages': [ + get_nft_transfer_message( + nft_address='EQDrA-3zsJXTfGo_Vdzg8d07Da4vSdHZllc6W9qvoNoMstF-', + recipient_address='0:0000000000000000000000000000000000000000000000000000000000000000', + transfer_fee=int(0.07 * 10**9), + response_address=wallet_address + ), + ] +} +``` + +### NFT Sale (GetGems) + +여기 GetGems 마켓플레이스에서 [nft-fixprice-sale-v3r2](https://github.com/getgems-io/nft-contracts/blob/main/packages/contracts/sources/nft-fixprice-sale-v3r2.fc) 계약에 따라 메시지와 거래를 준비하는 예시가 있습니다. + +To place NFT on GetGems Sale Contract, we should prepare special message body `transferNftBody` that will be transfer NFT to special NFT Sale Contract. + +
+Example of creating NFT Sale Body + +```python +import time +from base64 import urlsafe_b64encode + +from pytoniq_core.boc import Cell, begin_cell, Address +from pytoniq_core.tlb import StateInit + + +def get_sale_body(wallet_address: str, royalty_address: str, nft_address: str, price: int, amount: int): + + # contract code + nft_sale_code_cell = Cell.one_from_boc('te6cckECCwEAArkAART/APSkE/S88sgLAQIBIAIDAgFIBAUAfvIw7UTQ0wDTH/pA+kD6QPoA1NMAMMABjh34AHAHyMsAFssfUATPFljPFgHPFgH6AszLAMntVOBfB4IA//7y8AICzQYHAFegOFnaiaGmAaY/9IH0gfSB9AGppgBgYaH0gfQB9IH0AGEEIIySsKAVgAKrAQH30A6GmBgLjYSS+CcH0gGHaiaGmAaY/9IH0gfSB9AGppgBgYOCmE44BgAEqYhOmPhW8Q4YBKGATpn8cIxbMbC3MbK2QV44LJOZlvKAVxFWAAyS+G8BJrpOEBFcCBFd0VYACRWdjYKdxjgthOjq+G6hhoaYPqGAD9gHAU4ADAgB92YIQO5rKAFJgoFIwvvLhwiTQ+kD6APpA+gAwU5KhIaFQh6EWoFKQcIAQyMsFUAPPFgH6AstqyXH7ACXCACXXScICsI4XUEVwgBDIywVQA88WAfoCy2rJcfsAECOSNDTiWnCAEMjLBVADzxYB+gLLaslx+wBwIIIQX8w9FIKAejy0ZSzjkIxMzk5U1LHBZJfCeBRUccF8uH0ghAFE42RFrry4fUD+kAwRlAQNFlwB8jLABbLH1AEzxZYzxYBzxYB+gLMywDJ7VTgMDcowAPjAijAAJw2NxA4R2UUQzBw8AXgCMACmFVEECQQI/AF4F8KhA/y8AkA1Dg5ghA7msoAGL7y4clTRscFUVLHBRWx8uHKcCCCEF/MPRQhgBDIywUozxYh+gLLassfFcs/J88WJ88WFMoAI/oCE8oAyYMG+wBxUGZFFQRwB8jLABbLH1AEzxZYzxYBzxYB+gLMywDJ7VQAlsjLHxPLPyPPFlADzxbKAIIJycOA+gLKAMlxgBjIywUmzxZw+gLLaszJgwb7AHFVUHAHyMsAFssfUATPFljPFgHPFgH6AszLAMntVNZeZYk=') + + # fees cell + + marketplace_address = Address('EQBYTuYbLf8INxFtD8tQeNk5ZLy-nAX9ahQbG_yl1qQ-GEMS') + marketplace_fee_address = Address('EQCjk1hh952vWaE9bRguFkAhDAL5jj3xj9p0uPWrFBq_GEMS') + destination_address = Address('EQAIFunALREOeQ99syMbO6sSzM_Fa1RsPD5TBoS0qVeKQ-AR') + + wallet_address = Address(wallet_address) + royalty_address = Address(royalty_address) + nft_address = Address(nft_address) + + marketplace_fee = int(price * 5 / 100) # 5% + royalty_fee = int(price * 5 / 100) # 5% + + fees_data_cell = (begin_cell() + .store_address(marketplace_fee_address) + .store_coins(marketplace_fee) + .store_address(royalty_address) + .store_coins(royalty_fee) + .end_cell()) + + + sale_data_cell = (begin_cell() + .store_bit_int(0) + .store_uint(int(time.time()), 32) + .store_address(marketplace_address) + .store_address(nft_address) + .store_address(wallet_address) + .store_coins(price) + .store_ref(fees_data_cell) + .store_bit_int(0) + .end_cell()) + + state_init_cell = StateInit(code=nft_sale_code_cell, data=sale_data_cell).serialize() + + sale_body = (begin_cell() + .store_uint(1, 32) + .store_uint(0, 64) + .end_cell()) + + transfer_nft_body = (begin_cell() + .store_uint(0x5fcc3d14, 32) + .store_uint(0, 64) + .store_address(destination_address) + .store_address(wallet_address) + .store_bit_int(0) + .store_coins(int(1 * 10**9)) + .store_bit_int(0) + .store_uint(0x0fe0ede, 31) + .store_ref(state_init_cell) + .store_ref(sale_body) + .end_cell()) + + data = { + 'address': nft_address.to_str(), + 'amount': str(amount), + 'payload': urlsafe_b64encode(transfer_nft_body.to_boc()).decode() + } + + return data +``` + +
+ +The final transaction body: + +```python +transaction = { + 'valid_until': int(time.time() + 3600), + 'messages': [ + get_sale_body( + nft_address='EQDrA-3zsJXTfGo_Vdzg8d07Da4vSdHZllc6W9qvoNoMstF-', + wallet_address='0:0000000000000000000000000000000000000000000000000000000000000000', + royalty_address='0:0000000000000000000000000000000000000000000000000000000000000000', + price=int(5 * 10**9), + amount=int(1.08 * 10**9) + ), + ] +} +``` + +### NFT Buy (GetGems) + +[nft-fixprice-sale-v3r2](https://github.com/getgems-io/nft-contracts/blob/main/packages/contracts/sources/nft-fixprice-sale-v3r2.fc) 판매 계약에서 NFT를 구매하는 과정은 페이로드가 없는 일반적인 전송으로 수행할 수 있으며, 중요한 것은 정확한 TON 금액입니다. 그 금액은 다음과 같이 계산됩니다:\ +`buyAmount = Nftprice TON + 1.0 TON` + +```python +transaction = { + 'valid_until': int(time.time() + 3600), + 'messages': [ + { + 'address': nft_address, + 'amount': buyAmount, + } + ] +} +``` + +## TON Connect Go SDK + +Go examples are using [tonconnect](https://github.com/cameo-engineering/tonconnect) and [tonutils-go](https://github.com/xssnick/tonutils-go). + +```go +import "github.com/cameo-engineering/tonconnect" +import "github.com/xssnick/tonutils-go/address" +``` + +:::tip +Read [tonconnect](https://github.com/cameo-engineering/tonconnect/blob/master/examples/basic/main.go) and [tonutils-go](https://github.com/xssnick/tonutils-go?tab=readme-ov-file#how-to-use) examples. +::: + +There you can find how to create tonconnect session and send transaction constructed with messages. + +```go +s, _ := tonconnect.NewSession() +// create ton links +// ... +// create new message msg and transaction +boc, _ := s.SendTransaction(ctx, *tx) +``` + +In further examples only messages and transactions will be created. + +### Regular TON Transfer + +Example of function for building regular TON transfer message: + +```go +import ( + "fmt" + + "github.com/cameo-engineering/tonconnect" +) + +func Transfer(dest string, amount uint64) (*tonconnect.Message, error) { + msg, err := tonconnect.NewMessage( + dest, + fmt.Sprintf("%d", amount), // nanocoins to transfer/compute message + ) + return msg, err +} +``` + +Final transaction body: + +```go +msg, err := Transfer("0QBZ_35Wy144n2GBM93YpcV4KOKcIjDJk8DdX4kyXEEHcbLZ", uint64(math.Pow(10, 9))) +if err != nil { + log.Fatal(err) +} +tx, err := tonconnect.NewTransaction( + tonconnect.WithTimeout(10*time.Minute), + tonconnect.WithTestnet(), + tonconnect.WithMessage(*msg), +) +if err != nil { + log.Fatal(err) +} +``` + +### Transfer with Comment + +Example of function for building transfer with comment message: + +```go +import ( + "fmt" + + "github.com/cameo-engineering/tonconnect" + "github.com/xssnick/tonutils-go/tvm/cell" +) + +func TransferWithComment(dest string, amount uint64, comment string) (*tonconnect.Message, error) { + payload, _ := cell.BeginCell(). + MustStoreUInt(0, 32). + MustStoreStringSnake(comment). + EndCell().MarshalJSON() + msg, err := tonconnect.NewMessage( + dest, + fmt.Sprintf("%d", amount), // nanocoins to transfer/compute message + tonconnect.WithPayload(payload)) + return msg, err +} +``` + +Final transaction body: + +```go +msg, err := TransferWithComment("0QBZ_35Wy144n2GBM93YpcV4KOKcIjDJk8DdX4kyXEEHcbLZ", uint64(math.Pow(10, 9)), "new comment") +if err != nil { + log.Fatal(err) +} +tx, err := tonconnect.NewTransaction( + tonconnect.WithTimeout(10*time.Minute), + tonconnect.WithTestnet(), + tonconnect.WithMessage(*msg), +) +if err != nil { + log.Fatal(err) +} +``` + +### Jetton Transfer + +Jetton 전송 메시지를 생성하는 함수 예시: + +```go +import ( + "fmt" + + "github.com/cameo-engineering/tonconnect" + "github.com/xssnick/tonutils-go/address" + "github.com/xssnick/tonutils-go/tvm/cell" +) + +func JettonTransferMessage(jetton_wallet_address string, amount uint64, + jettons_amount uint64, recipient_address, response_address string, + fwd_amount uint64, fwd_payload *cell.Cell) (*tonconnect.Message, error) { + payload, _ := cell.BeginCell(). + MustStoreUInt(0xf8a7ea5, 32). // op code for jetton transfer message (op::transfer) + MustStoreUInt(0, 64). // query_id + MustStoreCoins(jettons_amount). + MustStoreAddr(address.MustParseAddr(recipient_address)). // address send excess to + MustStoreAddr(address.MustParseAddr(response_address)). + MustStoreUInt(0, 1). // custom payload + MustStoreCoins(fwd_amount). // set 0 if don't want transfer notification + MustStoreMaybeRef(fwd_payload). + EndCell().MarshalJSON() + + msg, err := tonconnect.NewMessage( + jetton_wallet_address, + fmt.Sprintf("%d", amount), // nanocoins to transfer/compute message + tonconnect.WithPayload(payload)) + + if err != nil { + return nil, err + } + + return msg, nil +} +``` + +Final transaction body: + +```go +msg, err := JettonTransferMessage("kQA8Q7m_pSNPr6FcqRYxllpAZv-0ieXy_KYER2iP195hBXiX", + uint64(math.Pow(10, 9)), + uint64(10), + "0QBZ_35Wy144n2GBM93YpcV4KOKcIjDJk8DdX4kyXEEHcbL2", + "EQBuObr2M7glm08w6cBGjIuuCbmvBFGwuVs6qb3AQpac9XpX", + uint64(0), nil) +if err != nil { + log.Fatal(err) +} +tx, err := tonconnect.NewTransaction( + tonconnect.WithTimeout(10*time.Minute), + tonconnect.WithTestnet(), + tonconnect.WithMessage(*msg), +) +if err != nil { + log.Fatal(err) +} +``` + +### Jetton Burn + +Jetton 소각 메시지를 생성하는 함수 예시: + +```go +import ( + "fmt" + + "github.com/cameo-engineering/tonconnect" + "github.com/xssnick/tonutils-go/address" + "github.com/xssnick/tonutils-go/tvm/cell" +) + +func JettonBurnMessage(jetton_wallet_address string, amount uint64, + jettons_amount uint64, response_address string) (*tonconnect.Message, error) { + + payload, _ := cell.BeginCell(). + MustStoreUInt(0xf8a7ea5, 32). // op code for jetton burn message (op::burn) + MustStoreUInt(0, 64). // query_id + MustStoreCoins(jettons_amount). // jetton amount to burn + MustStoreAddr(address.MustParseAddr(response_address)). // address send excess to + EndCell().MarshalJSON() + + msg, err := tonconnect.NewMessage( + jetton_wallet_address, + fmt.Sprintf("%d", amount), // nanocoins to transfer/compute message + tonconnect.WithPayload(payload)) + + if err != nil { + return nil, err + } + + return msg, nil +} +``` + +Final transaction body: + +```go +msg, err := JettonBurnMessage("kQA8Q7m_pSNPr6FcqRYxllpAZv-0ieXy_KYER2iP195hBXiX", + uint64(math.Pow(10, 9)), + uint64(10), + "EQBuObr2M7glm08w6cBGjIuuCbmvBFGwuVs6qb3AQpac9XpX") +if err != nil { + log.Fatal(err) +} +tx, err := tonconnect.NewTransaction( + tonconnect.WithTimeout(10*time.Minute), + tonconnect.WithTestnet(), + tonconnect.WithMessage(*msg), +) +if err != nil { + log.Fatal(err) +} +``` + +### NFT Transfer + +Example of function for NFT transfer message: + +```go +import ( + "fmt" + + "github.com/cameo-engineering/tonconnect" + "github.com/xssnick/tonutils-go/address" + "github.com/xssnick/tonutils-go/tvm/cell" +) + +func NftTransferMessage(nft_address string, amount uint64, recipient_address, response_address string, + fwd_amount uint64, fwd_payload *cell.Cell) (*tonconnect.Message, error) { + + payload, _ := cell.BeginCell(). + MustStoreUInt(0x5fcc3d14, 32). // op code for nft transfer message (op::transfer()) + MustStoreUInt(0, 64). // query_id + MustStoreAddr(address.MustParseAddr(recipient_address)). // new owner + MustStoreAddr(address.MustParseAddr(response_address)). // address send excess to + MustStoreUInt(0, 1). // custom payload + MustStoreCoins(fwd_amount). // set 0 if don't want transfer notification + MustStoreMaybeRef(fwd_payload). + EndCell().MarshalJSON() + + msg, err := tonconnect.NewMessage( + nft_address, + fmt.Sprintf("%d", amount), // nanocoins to transfer/compute message + tonconnect.WithPayload(payload)) + + if err != nil { + return nil, err + } + + return msg, nil +} +``` + +Final transaction body: + +```go +msg, err := NftTransferMessage("EQDrA-3zsJXTfGo_Vdzg8d07Da4vSdHZllc6W9qvoNoMstF-", + uint64(math.Pow(10, 9)), + "0QBZ_35Wy144n2GBM93YpcV4KOKcIjDJk8DdX4kyXEEHcbL2", + "0QBZ_35Wy144n2GBM93YpcV4KOKcIjDJk8DdX4kyXEEHcbL2", + uint64(0), nil) +if err != nil { + log.Fatal(err) +} +tx, err := tonconnect.NewTransaction( + tonconnect.WithTimeout(10*time.Minute), + tonconnect.WithTestnet(), + tonconnect.WithMessage(*msg), +) +if err != nil { + log.Fatal(err) +} +``` + +### NFT Sale (GetGems) + +여기 GetGems 마켓플레이스에서 [nft-fixprice-sale-v3r2](https://github.com/getgems-io/nft-contracts/blob/main/packages/contracts/sources/nft-fixprice-sale-v3r2.fc) 계약에 따라 메시지와 거래를 준비하는 예시가 있습니다. + +To place NFT on GetGems Sale Contract, we should prepare special message body `transferNftBody` that will be transfer NFT to special NFT Sale Contract. + +```go +transferNftBody := cell.BeginCell(). + MustStoreUInt(0x5fcc3d14, 32). // opcode for NFT transfer + MustStoreUInt(0, 64). // query_id + MustStoreAddress(destinationAddress). // new_owner - GetGems sale contracts deployer, should never change for this operation + MustStoreAddress(walletAddress). // response_destination for excesses + MustStoreUInt(0, 1). // we do not have custom_payload + MustStoreCoins(1.08*math.Pow(10, 9)). // forward_amount + MustStoreUInt(0, 1). // we store forward_payload is this cell + MustStoreUInt(0x0fe0ede, 31). // not 32, because previous 0 will be read as do_sale opcode in deployer (op::do_sale) + MustStoreRef(stateInitCell). + MustStoreRef(saleBody). + EndCell() +``` + +Because message requires a lot of steps, the entire algorithm huge and could be found here: + +
+ Show entire algorithm for the creating NFT Sale message body + +```go +import ( + "fmt" + "math" + "time" + + "github.com/cameo-engineering/tonconnect" + "github.com/xssnick/tonutils-go/address" + "github.com/xssnick/tonutils-go/tlb" + "github.com/xssnick/tonutils-go/tvm/cell" +) + +func NftSaleMessage(wallet, royalty, nft string, amount, price uint64) (*tonconnect.Message, error) { + fixPriceV3R2Code := new(cell.Cell) + fixPriceV3R2Code.UnmarshalJSON([]byte("te6cckECCwEAArkAART/APSkE/S88sgLAQIBIAIDAgFIBAUAfvIw7UTQ0wDTH/pA+kD6QPoA1NMAMMABjh34AHAHyMsAFssfUATPFljPFgHPFgH6AszLAMntVOBfB4IA//7y8AICzQYHAFegOFnaiaGmAaY/9IH0gfSB9AGppgBgYaH0gfQB9IH0AGEEIIySsKAVgAKrAQH30A6GmBgLjYSS+CcH0gGHaiaGmAaY/9IH0gfSB9AGppgBgYOCmE44BgAEqYhOmPhW8Q4YBKGATpn8cIxbMbC3MbK2QV44LJOZlvKAVxFWAAyS+G8BJrpOEBFcCBFd0VYACRWdjYKdxjgthOjq+G6hhoaYPqGAD9gHAU4ADAgB92YIQO5rKAFJgoFIwvvLhwiTQ+kD6APpA+gAwU5KhIaFQh6EWoFKQcIAQyMsFUAPPFgH6AstqyXH7ACXCACXXScICsI4XUEVwgBDIywVQA88WAfoCy2rJcfsAECOSNDTiWnCAEMjLBVADzxYB+gLLaslx+wBwIIIQX8w9FIKAejy0ZSzjkIxMzk5U1LHBZJfCeBRUccF8uH0ghAFE42RFrry4fUD+kAwRlAQNFlwB8jLABbLH1AEzxZYzxYBzxYB+gLMywDJ7VTgMDcowAPjAijAAJw2NxA4R2UUQzBw8AXgCMACmFVEECQQI/AF4F8KhA/y8AkA1Dg5ghA7msoAGL7y4clTRscFUVLHBRWx8uHKcCCCEF/MPRQhgBDIywUozxYh+gLLassfFcs/J88WJ88WFMoAI/oCE8oAyYMG+wBxUGZFFQRwB8jLABbLH1AEzxZYzxYBzxYB")) + + marketplaceAddress := address.MustParseAddr("EQBYTuYbLf8INxFtD8tQeNk5ZLy-nAX9ahQbG_yl1qQ-GEMS") // GetGems Address + marketplaceFeeAddress := address.MustParseAddr("EQCjk1hh952vWaE9bRguFkAhDAL5jj3xj9p0uPWrFBq_GEMS") // GetGems Address for Fees + destinationAddress := address.MustParseAddr("EQAIFunALREOeQ99syMbO6sSzM_Fa1RsPD5TBoS0qVeKQ-AR") // GetGems sale contracts deployer + + walletAddress := address.MustParseAddr(wallet) + royaltyAddress := address.MustParseAddr(royalty) + nftAddress := address.MustParseAddr(nft) + + feesData := cell.BeginCell(). + MustStoreAddr(marketplaceFeeAddress). + // 5% - GetGems fee + MustStoreCoins(price * 100 * 5). + MustStoreAddr(royaltyAddress). + // 5% - Royalty, can be changed + MustStoreCoins(price / 100 * 5). + EndCell() + + saleData := cell.BeginCell(). + MustStoreUInt(0, 1). // is_complete + MustStoreUInt(uint64(time.Now().UTC().Unix()), 32). // created_at + MustStoreAddr(marketplaceAddress). // marketplace_address + MustStoreAddr(nftAddress). // nft_address + MustStoreAddr(walletAddress). // previous_owner_address + MustStoreCoins(price). // full price in nanotons + MustStoreRef(feesData). // fees_cell + MustStoreUInt(0, 1). // can_be_deployed_externally + EndCell() + + stateInit := &tlb.StateInit{ + Data: saleData, + Code: fixPriceV3R2Code, + } + + stateInitCell, err := tlb.ToCell(stateInit) + if err != nil { + return nil, err + } + + // not needed, just for example + // saleContractAddress := address.NewAddress(0, 0, stateInitCell.Hash()) + + saleBody := cell.BeginCell(). + MustStoreUInt(1, 32). // just accept coins on deploy + MustStoreUInt(0, 64). + EndCell() + + transferNftBody, err := cell.BeginCell(). + MustStoreUInt(0x5fcc3d14, 32). // opcode for NFT transfer + MustStoreUInt(0, 64). // query_id + MustStoreAddr(destinationAddress). // new_owner - GetGems sale contracts deployer, should never change for this operation + MustStoreAddr(walletAddress). // response_destination for excesses + MustStoreUInt(0, 1). // we do not have custom_payload + MustStoreCoins(uint64(1*math.Pow(10, 9))). // forward_amount + MustStoreUInt(0, 1). // we store forward_payload is this cell + MustStoreUInt(0x0fe0ede, 31). // not 32, because previous 0 will be read as do_sale opcode in deployer (op::do_sale) + MustStoreRef(stateInitCell). + MustStoreRef(saleBody). + EndCell().MarshalJSON() + + if err != nil { + return nil, err + } + + msg, err := tonconnect.NewMessage( + nftAddress.String(), + fmt.Sprintf("%d", amount), + tonconnect.WithPayload(transferNftBody)) + + if err != nil { + return nil, err + } + + return msg, nil +} +``` + +The final transaction body: + +```go +msg, err := NftSaleMessage("EQArLGBnGPvkxaJE57Y6oS4rwzDWuOE8l8_sghntXLkIt162", + "EQArLGBnGPvkxaJE57Y6oS4rwzDWuOE8l8_sghntXLkIt162", + "EQCUWoe7hLlklVxH8gduCf45vPNocsjRP4wbX42UJ0Ja0S2f", + uint64(1.08*math.Pow(10, 9)), uint64(5*math.Pow(10, 9))) +if err != nil { + log.Fatal(err) +} +tx, err := tonconnect.NewTransaction( + tonconnect.WithTimeout(10*time.Minute), + tonconnect.WithTestnet(), + tonconnect.WithMessage(*msg), +) +if err != nil { + log.Fatal(err) +} +``` + +
+ +### NFT Buy (GetGems) + +[nft-fixprice-sale-v3r2](https://github.com/getgems-io/nft-contracts/blob/main/packages/contracts/sources/nft-fixprice-sale-v3r2.fc) 판매 계약에서 NFT를 구매하는 과정은 페이로드가 없는 일반적인 전송으로 수행할 수 있으며, 중요한 것은 정확한 TON 금액입니다. 그 금액은 다음과 같이 계산됩니다:\ +`buyAmount = Nftprice TON + 1.0 TON` + +```go +msg, err := tonconnect.NewMessage(nftAddress, buyAmount) +if err != nil { + log.Fatal(err) +} +tx, err := tonconnect.NewTransaction( + tonconnect.WithTimeout(10*time.Minute), + tonconnect.WithTestnet(), + tonconnect.WithMessage(*msg), +) +if err != nil { + log.Fatal(err) +} +``` + +## Authors + +- JavaScript examples provided by [@aSpite](https://t.me/aspite) +- Python examples provided by [@yunwine](https://t.me/yungwine) +- Go examples provided by [@gleb498](https://t.me/gleb498) + +## See Also + +- [TON Connect SDKs](/develop/dapps/ton-connect/developers) +- [TON Connect - Sending Messages](/develop/dapps/ton-connect/transactions) +- [Smart Contract Developmet - Sending Messages (Low Level)](/develop/smart-contracts/messages) +- [TON Jetton processing](/develop/dapps/asset-processing/jettons) +- [NFT processing on TON](/develop/dapps/asset-processing/nfts) From 91e3381a40f2fa4eeca10369fd2781363981981d Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:57:38 +0800 Subject: [PATCH 38/41] New translations overview.mdx (Korean) --- .../develop/dapps/ton-connect/overview.mdx | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx new file mode 100644 index 0000000000..4fe1ba4ab3 --- /dev/null +++ b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/overview.mdx @@ -0,0 +1,113 @@ +import Button from '@site/src/components/button' + +# About TON Connect + +TON Connect is a powerful open-source toolkit that serves as a universal application authorization standard within the [TON](/learn/introduction) ecosystem, enabling users to securely and conveniently log into applications and services using their TON wallets instead of traditional logins and passwords. + +![](/img/docs/ton-connect/ton-connect-overview.png?raw=true) + +Feel free to use one of the following flows for integration of your application: + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +```mdx-code-block + +``` + +## Use Cases For Your DApp + +TON Ecosystem이 제공하는 DApp 통합을 위한 우수한 기능들을 탐구하세요. + +- **Traffic**. Drive additional user visits via crypto wallets that support TON Connect. +- **Authenticity**. Leverage TON user's wallets as ready-made accounts, removing the need for additional authentication steps and thus, boosting user experience. +- **결제**. Toncoin 또는 래핑된 스테이블 코인(jUSDC/jUSDT)을 사용하여 TON 블록체인을 통해 빠르고 안전하게 거래를 처리합니다. +- **Retention**. Enhance user retention through the in-app list-saving feature which allows users to keep track of recently opened and favorite apps. + +## For Wallet Developers + +If you are a wallet developer, you can connect your wallet to TON Connect and enable your users to interact with TON apps in a secure and convenient way, read how to [integrate TON Connect into your wallet](/develop/dapps/ton-connect/wallet/). + +## Success Stories + +- [GetGems — The Open Network Marketplace](https://getgems.io/) +- [STON.fi — AMM DEX for TON blockchain](https://ston.fi/) +- [Tonstarter](http://tonstarter.com/) + +
+ Show the entire list + +- [getgems.io](https://getgems.io/) +- [fragment.com](https://fragment.com/) (Ton Connect v.1) +- [ston.fi](https://ston.fi/) +- [ton.diamonds](https://ton.diamonds/) +- [beta.disintar.io](https://beta.disintar.io/) +- [tegro.finance](https://tegro.finance/liquidity) +- [minter.ton.org](https://minter.ton.org/) +- [libermall.com](https://libermall.com/) +- [dedust.io](https://dedust.io/swap) +- [toncap.net](https://toncap.net/) +- [cryptomus.com](https://cryptomus.com/) +- [avanchange.com](https://avanchange.com/) +- [wton.dev](https://wton.dev/) +- [mint.spiroverse.io/shop](https://mint.spiroverse.io/shop) +- [vk.com/vk_nft_hub](https://vk.com/vk_nft_hub) +- [tonverifier.live](https://verifier.ton.org/) +- [stickerface.io/member](https://stickerface.io/member) +- [tonstarter.com](https://tonstarter.com/) +- [cryptogas.shop/ton](https://cryptogas.shop/ton) +- [megaton.fi](https://megaton.fi/) +- [dns.ton.org](https://dns.ton.org/) +- [coinpaymaster.com](https://coinpaymaster.com/) +- [ton.gagarin.world/app/](https://ton.gagarin.world/app) +- [daolama.co](https://daolama.co/) +- [marketplace.playmuse.org](http://marketplace.playmuse.org/) +- [ton.vote](https://ton.vote/) +- [plane.tonfancy.io](https://plane.tonfancy.io/) +- [pi.oberton.io](https://pi.oberton.io/) +- [business.thetonpay.app](https://business.thetonpay.app/) +- [bridge.orbitchain.io](https://bridge.orbitchain.io/) +- [connecton-web-new.vercel.app](https://connecton-web-new.vercel.app/) +- [app.fanz.ee/staking](https://app.fanz.ee/staking) +- [testnet.pton.fi](https://testnet.pton.fi/) +- [tonft.app](https://tonft.app/) +- [cardify.casino](https://cardify.casino/) +- [4riends.org](https://4riends.org/#/) +- [tonflex.fi](https://tonflex.fi/swap) +- [soquest.xyz](https://soquest.xyz/) +- [app.evaa.finance](https://app.evaa.finance/) + +
+ +## Join the TON Ecosystem + +To connect your service with the TON Ecosystem, you need to implement the following: + +- **TON Connect**. Incorporate the TON Connect protocol within your application. +- **Transactions**. Create specified transaction messages using TON libraries. Dive into the process of [sending messages](/develop/dapps/ton-connect/message-builders) with our comprehensive guide. +- **Payments**. Process payments via the public API ([tonapi](https://tonapi.io/)) or your own indexer, for instance, [gobycicle](http://github.com/gobicycle/bicycle). Learn more from our extensive guide on [asset processing](/develop/dapps/asset-processing). From e580ff40cd19c35a033b1f640d67f717156a5f3f Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:57:39 +0800 Subject: [PATCH 39/41] New translations readme.md (Korean) --- .../dapps/ton-connect/protocol/README.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/protocol/README.md diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/protocol/README.md b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/protocol/README.md new file mode 100644 index 0000000000..6bfcb404a1 --- /dev/null +++ b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/protocol/README.md @@ -0,0 +1,55 @@ +# Protocol specifications + +Understand how TON Connect works under the hood. + +## Who is this section for? + +- If you implement a wallet +- If you develop an SDK +- If you want to learn how TON Connect works + +## Sections overview + +- [Protocol workflows](/develop/dapps/ton-connect/protocol/workflow) is an overview of all the protocols involved in TON Connect. +- [Bridge API](/develop/dapps/ton-connect/protocol/bridge) specifies how the data is transmitted between the app and the wallet. +- [Session protocol](/develop/dapps/ton-connect/protocol/session) ensures end-to-end encrypted communication over the bridge. +- [Requests protocol](/develop/dapps/ton-connect/protocol/requests-responses) defines requests and responses for the app and the wallet. +- [Wallet guidelines](/develop/dapps/ton-connect/protocol/wallet-guidelines) defines guidelines for wallet developers. + +## FAQ + +#### I am building an HTML/JS app, what should I read? + +Simply use the [Supported SDKs](/develop/dapps/ton-connect/developers) and do not worry about the underlying protocols. + +#### I need an SDK in my favorite language + +Please take the [JS SDK](/develop/dapps/ton-connect/developers) as a reference and check out the protocol docs above. + +#### How do you detect whether the app is embedded in the wallet? + +JS SDK does that for you; just get wallets list `connector.getWallets()` and check `embedded` property of the corresponding list item. If you build your own SDK you should check `window.[targetWalletJsBridgeKey].tonconnect.isWalletBrowser`. + +#### How do you detect if the wallet is a browser extension? + +Like with embedded apps (see above), JS SDK detects it for you via `injected` property of the corresponding `connector.getWallets()` list item. If you build your own SDK you should check that `window.[targetWalletJsBridgeKey].tonconnect` exists. + +#### How to implement backend authorization with tonconnect? + +[See an example of dapp-backend](https://github.com/ton-connect/demo-dapp-backend) + +#### How do I make my own bridge? + +You don’t need to, unless you are building a wallet. + +If you build a wallet, you will need to provide a bridge. See our [reference implementation in Go](https://github.com/ton-connect/bridge). + +Keep in mind that the wallet’s side of the bridge API is not mandated. + +빠른 시작을 위해 일반적으로 사용되는 TON Connect 브릿지 [https://bridge.tonapi.io/bridge](https://bridge.tonapi.io/bridge)을 사용할 수 있습니다. + +#### I make a wallet, how do I add it to the list of wallets? + +Submit a pull request for the [wallets-list](https://github.com/ton-blockchain/wallets-list) repository and fill our all the necessary metadata. + +Apps may also add wallets directly through the SDK. From a011dd53daf3839e6ad74ce32614e1f4903912f8 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:57:42 +0800 Subject: [PATCH 40/41] New translations wallet-guidelines.md (Korean) --- .../ton-connect/protocol/wallet-guidelines.md | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/protocol/wallet-guidelines.md diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/protocol/wallet-guidelines.md b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/protocol/wallet-guidelines.md new file mode 100644 index 0000000000..ee2277dade --- /dev/null +++ b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/protocol/wallet-guidelines.md @@ -0,0 +1,61 @@ +# Wallet Guidelines + +## Networks + +### There aren't many networks. + +At the moment, there are only two networks - Mainnet and Testnet. +In the foreseeable future, the emergence of new Mainnet TON-like networks is not expected. Note that the current Mainnet has a built-in mechanism for alternative networks - workchains. + +### Hide the Testnet from ordinary users. + +Testnet is used exclusively by developers. Ordinary users should not see the Testnet. +This means that switching to Testnet should not be readily available and users SHOULD NOT be prompted to switch wallet to Testnet even if DAppis in Testnet. +Users switch to Testnet, don't understand this action, can't switch back to Mainnet. + +For these reasons, dapps do not need to switch networks in runtime, on the contrary, it is more preferable to have different instances of DAppon different domains dapp.com, Testnet.dapp.com. +For the same reason there is no `NetworkChanged` or `ChainChanged` event in the Ton Connect protocol. + +### Do not send anything if the DAppis in Testnet and the wallet is in Mainnet. + +It is necessary to prevent loss of funds when DApptries to send a transaction in Testnet, and the wallet sends it in Mainnet. + +Dapps should explicitly indicate `network` field in `SendTransaction` request. + +If the `network` parameter is set, but the wallet has a different network set, the wallet should show an alert and DO NOT ALLOW TO SEND this transaction. + +The wallet SHOULD NOT offer to switch to another network in this case. + +## Multi accounts + +Multiple network accounts can be created for one key pair. Implement this functionality in your wallet - users will find it useful. + +### In general, there is no current "active" account + +At the moment, the TON Connect is not built on the paradigm that there is one selected account in the wallet, and when the user switches to another account, the `AccountChanged` event is sent to dapp. + +We think of a wallet as a physical wallet that can contain many "bank cards" (accounts). + +In most cases the sender address is not important to dapp, in these cases the user can select the appropriate account at the time of approving the transaction and the transaction will be sent from selected account. + +In some cases, it is important for DAppto send the transaction from a specific address, in which case it explicitly specifies the `from` field in `SendTransaction` request. If `from` parameter is set, the wallet should DO NOT ALLOW user to select the sender's address; If sending from the specified address is impossible, the wallet should show an alert and DO NOT ALLOW TO SEND this transaction. + +### Login flow + +When DAppconnects the wallet, the user selects in the wallet one of their accounts that they want to log into dapp. + +Regardless of what accounts the user uses next in the wallet, DAppworks with the account he received on the connection. + +Just like if you logged into a web service with one of your email accounts - if you then change the email account in the email service, the web service continues to use the one he got when you logged in. + +For this reason, the protocol does not provide the `AccountChanged` event. + +To switch account user need to disconnect (Log out) and connect (Login) again in DAppUI. + +We recommend wallets provide the ability to disconnect session with a specified DAppbecause the DAppmay have an incomplete UI. + +## See Also + +- [TON Connect Overview](/dapps/ton-connect/overview) +- [프로토콜 사양](/dapps/ton-connect/protocol/) +- [Connect a Wallet](/dapps/ton-connect/wallet) From 920b175b14c9cd2fba49bb84f65e116d3a258005 Mon Sep 17 00:00:00 2001 From: Townsquare DevOps <147710825+TonSquare@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:57:43 +0800 Subject: [PATCH 41/41] New translations react.mdx (Korean) --- .../develop/dapps/ton-connect/react.mdx | 332 ++++++++++++++++++ 1 file changed, 332 insertions(+) create mode 100644 i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/react.mdx diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/react.mdx b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/react.mdx new file mode 100644 index 0000000000..59563613e9 --- /dev/null +++ b/i18n/ko/docusaurus-plugin-content-docs/current/develop/dapps/ton-connect/react.mdx @@ -0,0 +1,332 @@ +# TON Connect for React + +Recommended SDK for React Apps is a [UI React SDK](/develop/dapps/ton-connect/developers#ton-connect-react). It is a React component that provides a high-level way to interact with TON Connect. + +## Implementation + +### 1. 설치 + +To start integrating TON Connect into your DApp, you need to install the `@tonconnect/ui-react` package. You can use npm or yarn for this purpose: + +```bash npm2yarn +npm i @tonconnect/ui-react +``` + +### 2. TON Connect 시작 + +After installing the package, you should create a `manifest.json` file for your application. More information on how to create a manifest.json file can be found [here](/develop/dapps/ton-connect/manifest). + +After creating the manifest file, import TonConnectUIProvider to the root of your Mini App and pass the manifest URL: + +```tsx +import { TonConnectUIProvider } from '@tonconnect/ui-react'; + +export function App() { + return ( + + { /* Your app */ } + + ); +} + +``` + +### 3. 지갑에 연결 + +Add the `TonConnectButton`. The TonConnect Button is a universal UI component for initializing a connection. After the wallet is connected, it transforms into a wallet menu. It is recommended to place it in the top right corner of your app. + +```tsx +export const Header = () => { + return ( +
+ My App with React UI + +
+ ); +}; +``` + +You can add className and style props to the button as well. Note that you cannot pass child to the TonConnectButton: + +```js + +``` + +Moreover, you always can initiate the connection manually, using `useTonConnectUI` hook and [connectWallet](https://github.com/ton-connect/sdk/tree/main/packages/ui#call-connect) method. + +### 4. 리다이렉트 + +If you want to redirect user to a specific page after wallet connection, you can use `useTonConnectUI` hook and [customize your return strategy](https://github.com/ton-connect/sdk/tree/main/packages/ui#add-the-return-strategy). + +#### Telegram Mini Apps + +If you want to redirect user to a [Telegram Mini App](/develop/dapps/telegram-apps/) after wallet connection, you can customize the `TonConnectUIProvider` element: + +```tsx + ' + }} + > + +``` + +[Open example on GitHub](https://github.com/ton-connect/demo-dapp-with-wallet/blob/master/src/App.tsx) + +### 5. UI 사용자 지정 + +To [customize UI](https://github.com/ton-connect/sdk/tree/main/packages/ui#ui-customisation) of the modal you can use `useTonConnectUI` hook and `setOptions` function. See more about useTonConnectUI hook in [Hooks](#hooks) section. + +## Hooks + +If you want to use some low-level TON Connect UI SDK features in your React app, you can use hooks from `@tonconnect/ui-react` package. + +### useTonAddress + +Use it to get user's current ton wallet address. Pass boolean parameter isUserFriendly to choose format of the address. If wallet is not connected hook will return empty string. + +```tsx +import { useTonAddress } from '@tonconnect/ui-react'; + +export const Address = () => { + const userFriendlyAddress = useTonAddress(); + const rawAddress = useTonAddress(false); + + return ( + userFriendlyAddress && ( +
+ User-friendly address: {userFriendlyAddress} + Raw address: {rawAddress} +
+ ) + ); +}; +``` + +### useTonWallet + +Use it to get user's current ton wallet. If wallet is not connected hook will return null. + +See all wallet's properties + +[Wallet interface](https://ton-connect.github.io/sdk/interfaces/_tonconnect_sdk.Wallet.html) +[WalletInfo interface](https://ton-connect.github.io/sdk/types/_tonconnect_sdk.WalletInfo.html) + +```tsx +import { useTonWallet } from '@tonconnect/ui-react'; + +export const Wallet = () => { + const wallet = useTonWallet(); + + return ( + wallet && ( +
+ Connected wallet: {wallet.name} + Device: {wallet.device.appName} +
+ ) + ); +}; +``` + +### useTonConnectUI + +Use it to get access to the `TonConnectUI` instance and UI options updating function. + +[See more about TonConnectUI instance methods](https://github.com/ton-connect/sdk/tree/main/packages/ui#send-transaction) + +[See more about setOptions function](https://github.com/ton-connect/sdk/tree/main/packages/ui#change-options-if-needed) + +```tsx +import { Locales, useTonConnectUI } from '@tonconnect/ui-react'; + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + const onLanguageChange = (lang: string) => { + setOptions({ language: lang as Locales }); + }; + + return ( +
+ + +
+ + +
+
+ ); +}; +``` + +### useIsConnectionRestored + +Indicates current status of the connection restoring process. +You can use it to detect when connection restoring process if finished. + +```tsx +import { useIsConnectionRestored } from '@tonconnect/ui-react'; + +export const EntrypointPage = () => { + const connectionRestored = useIsConnectionRestored(); + + if (!connectionRestored) { + return Please wait...; + } + + return ; +}; +``` + +## Usage + +Let's take a look at how to use the React UI SDK on practice. + +### Sending transactions + +Send TON coins (in nanotons) to a specific address: + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; + +const transaction = { + messages: [ + { + address: "0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F", // destination address + amount: "20000000" //Toncoin in nanotons + } + ] + +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + +- Get more examples here: [Preparing Messages](/develop/dapps/ton-connect/message-builders) + +### Understanding Transaction Status by Hash + +The principle located in Payment Processing (using tonweb). [See more](/develop/dapps/asset-processing/#checking-contracts-transactions) + +### Optional Check (ton_proof) on the Backend + +:::tip +Understand how to sign and verify messages: [Signing and Verification](/develop/dapps/ton-connect/sign) +::: + +Use `tonConnectUI.setConnectRequestParameters` function to pass your connect request parameters. + +This function takes one parameter: + +Set state to 'loading' while you are waiting for the response from your backend. If user opens connect wallet modal at this moment, he will see a loader. + +```ts +const [tonConnectUI] = useTonConnectUI(); + +tonConnectUI.setConnectRequestParameters({ + state: 'loading' +}); +``` + +or + +Set state to 'ready' and define `tonProof` value. Passed parameter will be applied to the connect request (QR and universal link). + +```ts +const [tonConnectUI] = useTonConnectUI(); + +tonConnectUI.setConnectRequestParameters({ + state: 'ready', + value: { + tonProof: '' + } +}); +``` + +or + +Remove loader if it was enabled via `state: 'loading'` (e.g. you received an error instead of a response from your backend). Connect request will be created without any additional parameters. + +```ts +const [tonConnectUI] = useTonConnectUI(); + +tonConnectUI.setConnectRequestParameters(null); +``` + +You can call `tonConnectUI.setConnectRequestParameters` multiple times if your tonProof payload has bounded lifetime (e.g. you can refresh connect request parameters every 10 minutes). + +```ts +const [tonConnectUI] = useTonConnectUI(); + +// enable ui loader +tonConnectUI.setConnectRequestParameters({ state: 'loading' }); + +// fetch you tonProofPayload from the backend +const tonProofPayload: string | null = await fetchTonProofPayloadFromBackend(); + +if (!tonProofPayload) { + // remove loader, connect request will be without any additional parameters + tonConnectUI.setConnectRequestParameters(null); +} else { + // add tonProof to the connect request + tonConnectUI.setConnectRequestParameters({ + state: "ready", + value: { tonProof: tonProofPayload } + }); +} + +``` + +You can find `ton_proof` result in the `wallet` object when wallet will be connected: + +```ts +import {useTonConnectUI} from "@tonconnect/ui-react"; + +const [tonConnectUI] = useTonConnectUI(); + +useEffect(() => + tonConnectUI.onStatusChange(wallet => { + if (wallet.connectItems?.tonProof && 'proof' in wallet.connectItems.tonProof) { + checkProofInYourBackend(wallet.connectItems.tonProof.proof, wallet.account); + } + }), []); +``` + +### Wallet Disconnection + +Call to disconnect the wallet: + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; + +const [tonConnectUI] = useTonConnectUI(); + +await tonConnectUI.disconnect(); +``` + +## API Documentation + +[Latest API documentation](https://ton-connect.github.io/sdk/modules/_tonconnect_ui_react.html) + +## Examples + +- Step-by-step [TON Hello World guide](https://ton-community.github.io/tutorials/03-client/) to create a simple DAppwith React UI. +- [Demo dApp](https://github.com/ton-connect/demo-dapp-with-react-ui) - `@tonconnect/ui-react`를 사용한 DApp 예시. +- [ton.vote](https://github.com/orbs-network/ton-vote) - Example of React website with TON Connect implementation.