├── .build └── website │ ├── .gitignore │ ├── README.md │ ├── babel.config.js │ ├── docusaurus.config.js │ ├── favicons.js │ ├── license │ ├── link │ ├── footer.js │ ├── index.js │ ├── main.js │ ├── navbar.js │ └── redirect.js │ ├── package.json │ ├── preview.sh │ ├── script │ ├── build-pdf.sh │ └── sitmap.js │ ├── sidebars.js │ ├── src │ ├── components │ │ ├── HomepageFeatures.js │ │ └── HomepageFeatures.module.css │ ├── css │ │ └── custom.css │ ├── pages │ │ └── index.module.css │ └── theme │ │ ├── SearchBar │ │ ├── DocSearch.js │ │ ├── algolia.css │ │ ├── index.js │ │ ├── lib │ │ │ ├── DocSearch.js │ │ │ ├── lunar-search.js │ │ │ ├── templates.js │ │ │ └── utils.js │ │ ├── lunar-search.js │ │ ├── styles.css │ │ ├── templates.js │ │ └── utils.js │ │ └── SiteMetadata │ │ └── index.tsx │ ├── static │ ├── .nojekyll │ ├── img │ │ └── logo.svg │ └── robots.txt │ └── yarn.lock ├── .github └── workflows │ ├── deploy.yml │ └── test.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── docswrite.md ├── readme.md └── src ├── arch ├── 05-basics.md ├── 07-tlb-and-boc.md ├── 10-tvm.md ├── 25-fee-calculation.md ├── 30-managing-gas.md ├── 35-executor.md ├── 37-logic-time.md ├── 40-accounts.md ├── 45-message.md ├── 50-transactions.md ├── 55-security.md ├── 70-workchains.md ├── 80-multithreading.md ├── _category_.json ├── consensus │ ├── 00-introduction.md │ ├── 10-comparison.md │ ├── 20-components.md │ ├── 30-overview.md │ ├── 40-messages.md │ ├── _category_.json │ └── img │ │ ├── 0_5C1TuB_hyZiHnYLI.webp │ │ └── 0__qmtJKNeq-aBuQU8.webp └── networking │ ├── _category_.json │ ├── adnl.md │ ├── dht.md │ ├── networking.md │ ├── overlay.md │ ├── remp.md │ ├── rldp.md │ └── tl.md ├── contribute ├── _category_.json ├── bug-bounty-program.md └── getting-started.md ├── develop ├── _category_.json ├── account-abstraction.md ├── actor-model.md ├── graphql-pagination.md ├── intro.md ├── payment.md ├── recipes │ ├── _category_.json │ ├── backend-integration.md │ ├── connect-wallet.md │ ├── ever-sdk-guides │ │ ├── _category_.json │ │ ├── ever-sdk-start.md │ │ ├── other-sdk-guides.md │ │ └── remp.md │ ├── img │ │ ├── ew01.png │ │ ├── ew02.png │ │ └── ew03.png │ ├── intro.md │ ├── read-data.md │ ├── surf-wallet-advanced.md │ ├── tip3-integration.md │ └── write-data.md ├── sc-abi-messages.md ├── smart-contracts │ ├── _category_.json │ ├── everdev.md │ ├── locklift-setup.md │ ├── tokensale.md │ ├── use-fungible-tokens.md │ └── voting-system.md ├── tools-overview.md └── tvmcell-data-structure.md ├── img ├── debot-architecture.svg ├── debot-sequence.svg ├── delegator.svg ├── depool-architecture.svg ├── multi-round-elections.png ├── remp1.svg ├── remp2.svg ├── remp3.svg ├── tp-1.svg ├── tp-2.svg └── what_concepts_were_used_before_operating_systems.jpg ├── overview ├── _category_.json ├── concepts.md ├── differences-from-evm.md ├── img │ ├── CDBC.jpg │ ├── Enterprise.jpg │ ├── Everscale_s-parallel-smart-contracts-execution_1-50.gif │ ├── Two_spheres2.jpg │ ├── everscale-banner.jpg │ ├── evervseth.jpg │ └── network-architecture.gif ├── infinite-scalability.md ├── lore.md └── overview.md ├── spec ├── 10-abi.md ├── 20-depool-specification.md ├── 30-debot-specifications.md └── _category_.json ├── standard ├── TIP-1 │ ├── 1.md │ ├── 2.md │ └── _category_.json ├── TIP-3 │ ├── 1.md │ ├── 2.md │ ├── _category_.json │ └── core-description.md ├── TIP-4 │ ├── 1.md │ ├── 2.md │ ├── 3.md │ ├── 4.md │ ├── 5.md │ ├── 6.md │ ├── _category_.json │ ├── core-description.md │ └── img │ │ ├── burn.svg │ │ ├── buy.svg │ │ ├── changeManager.svg │ │ ├── changeOwner.svg │ │ ├── collection.svg │ │ ├── index1.svg │ │ ├── index2.svg │ │ ├── index3.svg │ │ ├── legend1.svg │ │ ├── legend2.svg │ │ ├── mint.svg │ │ ├── sell.svg │ │ ├── storage1.svg │ │ ├── storage2.svg │ │ ├── storage3.svg │ │ ├── tip3buy.svg │ │ └── tip3sell.svg ├── TIP-5 │ ├── 1.md │ └── core-description.md ├── TIP-6 │ ├── 1.md │ ├── _category_.json │ └── core-description.md ├── _category_.json └── workflow.md ├── validate.md └── welcome.md /.build/website/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | *.pdf 7 | .bin 8 | *.tex 9 | 10 | # Generated files 11 | .docusaurus 12 | .cache-loader 13 | 14 | # Misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /.build/website/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 4 | 5 | ### Installation 6 | 7 | ```shell 8 | $ yarn 9 | ``` 10 | 11 | ### Local Development 12 | 13 | ```shell 14 | $ yarn start 15 | ``` 16 | 17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ### Build 20 | 21 | ```shell 22 | $ yarn build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | For emulate prod build: 28 | ```shell 29 | $ yarn emul 30 | ``` 31 | 32 | ### Deployment `gh-pages` 33 | 34 | ```shell 35 | $ export SITE_URL=https://%USER%.github.io 36 | $ export SITE_BASE_URL=/docs/ 37 | $ git remote add gh-pages git@github.com:%USER%/docs.git 38 | $ yarn deploy-gh-pages 39 | ``` 40 | or 41 | 42 | ```shell 43 | cd .build/website 44 | yarn install 45 | bash preview.sh 46 | ``` 47 | -------------------------------------------------------------------------------- /.build/website/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /.build/website/docusaurus.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Note: type annotations allow type checking and IDEs autocompletion 3 | 4 | const lightCodeTheme = require('prism-react-renderer/themes/github'); 5 | const darkCodeTheme = require('prism-react-renderer/themes/dracula'); 6 | 7 | const math = require('remark-math'); 8 | const katex = require('rehype-katex'); 9 | const simplePlantUML = require("@akebifiky/remark-simple-plantuml"); 10 | const link = require('./link'); 11 | 12 | const plugins = [ 13 | require.resolve('docusaurus-lunr-search'), 14 | [ 15 | '@docusaurus/plugin-client-redirects', 16 | { 17 | ...link.redirect, 18 | }, 19 | ], 20 | ]; 21 | 22 | if (process.env.APP_GA_MEASUREMENT_ID) { 23 | plugins.push([ 24 | '@docusaurus/plugin-google-gtag', 25 | { 26 | trackingID: process.env.APP_GA_MEASUREMENT_ID, 27 | anonymizeIP: true, 28 | }, 29 | ]) 30 | } 31 | 32 | /** @type {import('@docusaurus/types').Config} */ 33 | const config = { 34 | title: 'Docs of Everscale', 35 | url: process.env.SITE_URL || 'https://docs.everscale.network', 36 | baseUrl: process.env.SITE_BASE_URL || '/', 37 | onBrokenLinks: 'throw', 38 | onBrokenMarkdownLinks: 'warn', 39 | favicon: 'img/favicon.ico', 40 | organizationName: 'everscale-docs', 41 | projectName: 'docs', 42 | markdown: { 43 | mermaid: true, 44 | }, 45 | themes: [ 46 | '@docusaurus/theme-mermaid', 47 | ], 48 | scripts: [ 49 | ], 50 | plugins, 51 | stylesheets: [ 52 | { 53 | href: 'https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css', 54 | type: 'text/css', 55 | integrity: 'sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM', 56 | crossorigin: 'anonymous', 57 | }, 58 | ], 59 | presets: [ 60 | [ 61 | 'classic', 62 | /** @type {import('@docusaurus/preset-classic').Options} */ 63 | ({ 64 | docs: { 65 | sidebarPath: require.resolve('./sidebars.js'), 66 | editUrl: 'https://github.com/everscale-org/docs/edit/main/.build/website', 67 | remarkPlugins: [ 68 | math, 69 | simplePlantUML, 70 | ], 71 | rehypePlugins: [katex], 72 | showLastUpdateAuthor: false, 73 | showLastUpdateTime: true, 74 | path: "../../src", 75 | routeBasePath: '/', 76 | }, 77 | theme: { 78 | customCss: require.resolve('./src/css/custom.css'), 79 | }, 80 | sitemap: { 81 | changefreq: 'weekly', 82 | priority: 0.5, 83 | }, 84 | }), 85 | ], 86 | ], 87 | 88 | themeConfig: 89 | /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ 90 | ({ 91 | navbar: { 92 | title: 'Everscale Docs', 93 | logo: { 94 | alt: 'Everscale Docs', 95 | src: 'img/logo.svg', 96 | }, 97 | items: link.navbar, 98 | }, 99 | footer: { 100 | style: 'dark', 101 | links: link.footer, 102 | copyright: `Copyright © 2020—${new Date().getFullYear()} 103 | Everscale All rights reserved 104 | Touch 105 |
106 | 107 | Creative Commons License 108 | `, 109 | }, 110 | prism: { 111 | theme: lightCodeTheme, 112 | darkTheme: darkCodeTheme, 113 | additionalLanguages: [ 114 | "rust", 115 | "solidity" 116 | ] 117 | }, 118 | }), 119 | }; 120 | 121 | module.exports = config; 122 | -------------------------------------------------------------------------------- /.build/website/favicons.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const favicons = require('favicons') 3 | const source = 'static/img/logo.svg' // Source image(s). `string`, `buffer` or array of `string` 4 | const configuration = { 5 | path: '/', // Path for overriding default icons path. `string` 6 | appName: null, // Your application's name. `string` 7 | appShortName: null, // Your application's short_name. `string`. Optional. If not set, appName will be used 8 | appDescription: null, // Your application's description. `string` 9 | developerName: null, // Your (or your developer's) name. `string` 10 | developerURL: null, // Your (or your developer's) URL. `string` 11 | dir: 'auto', // Primary text direction for name, short_name, and description 12 | lang: 'en-US', // Primary language for name and short_name 13 | background: '#fff', // Background colour for flattened icons. `string` 14 | theme_color: '#fff', // Theme color user for example in Android's task switcher. `string` 15 | appleStatusBarStyle: 'black-translucent', // Style for Apple status bar: 'black-translucent', 'default', 'black'. `string` 16 | display: 'standalone', // Preferred display mode: 'fullscreen', 'standalone', 'minimal-ui' or 'browser'. `string` 17 | orientation: 'any', // Default orientation: 'any', 'natural', 'portrait' or 'landscape'. `string` 18 | scope: '/', // set of URLs that the browser considers within your app 19 | start_url: '/?homescreen=1', // Start URL when launching the application from a device. `string` 20 | version: '1.0', // Your application's version string. `string` 21 | logging: false, // Print logs to console? `boolean` 22 | pixel_art: false, // Keeps pixels 'sharp' when scaling up, for pixel art. Only supported in offline mode. 23 | loadManifestWithCredentials: false, // Browsers don't send cookies when fetching a manifest, enable this to fix that. `boolean` 24 | icons: { 25 | // Platform Options: 26 | // - offset - offset in percentage 27 | // - background: 28 | // * false - use default 29 | // * true - force use default, e.g. set background for Android icons 30 | // * color - set background for the specified icons 31 | // * mask - apply mask in order to create circle icon (applied by default for firefox). `boolean` 32 | // * overlayGlow - apply glow effect after mask has been applied (applied by default for firefox). `boolean` 33 | // * overlayShadow - apply drop shadow after mask has been applied .`boolean` 34 | // 35 | android: false, // Create Android homescreen icon. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources 36 | appleIcon: false, // Create Apple touch icons. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources 37 | appleStartup: false, // Create Apple startup images. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources 38 | coast: false, // Create Opera Coast icon. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources 39 | favicons: true, // Create regular favicons. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources 40 | firefox: false, // Create Firefox OS icons. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources 41 | windows: false, // Create Windows 8 tile icons. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources 42 | yandex: false, // Create Yandex browser icon. `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources 43 | }, 44 | }, 45 | callback = function (error, response) { 46 | if (error) { 47 | console.log(error.message) // Error description e.g. 'An unknown error has occurred' 48 | return 49 | } 50 | for (image of response.images) { // Array of { name: string, contents: } 51 | fs.writeFileSync(`static/img/${image.name}`, image.contents) 52 | } 53 | // console.log(response.files) // Array of { name: string, contents: } 54 | // console.log(response.html) // Array of strings (html elements) 55 | } 56 | 57 | favicons(source, configuration, callback) 58 | -------------------------------------------------------------------------------- /.build/website/license: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /.build/website/link/footer.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | { 3 | title: 'About', 4 | items: [ 5 | { 6 | label: 'Jobs and Vacancy', 7 | href: 'https://github.com/everscale-org/job/issues', 8 | }, 9 | { 10 | label: 'White Paper', 11 | href: 'https://everscale.network/files/Everscale_Whitepaper.pdf', 12 | }, 13 | { 14 | label: 'Lite Paper', 15 | href: 'https://everscale.network/files/Everscale_Litepaper.pdf', 16 | }, 17 | { 18 | label: 'Digest', 19 | href: 'https://www.youtube.com/@everscale.network/search?query=Digest', 20 | }, 21 | { 22 | label: 'Visual Brand Identity', 23 | href: 'https://everscale.network/about/brand', 24 | }, 25 | ], 26 | }, 27 | { 28 | title: 'Community', 29 | items: [ 30 | { 31 | label: 'Grants', 32 | href: 'https://everscale.network/grants', 33 | }, 34 | { 35 | label: 'Bounties', 36 | href: 'https://github.com/everscale-org/bounties/issues', 37 | }, 38 | { 39 | label: 'Smart Contracts Chat', 40 | href: 'https://t.me/EverscaleSmartContracts', 41 | }, 42 | { 43 | label: 'Everscale Validators Channel', 44 | href: 'https://t.me/ever_validators', 45 | }, 46 | { 47 | label: 'DeBots Chat', 48 | href: 'https://t.me/everscaledebots', 49 | }, 50 | { 51 | label: 'SDK Chat', 52 | href: 'https://t.me/ever_sdk', 53 | }, 54 | { 55 | label: 'Stack Overflow', 56 | href: 'https://stackoverflow.com/questions/tagged/everscale', 57 | }, 58 | ], 59 | }, 60 | { 61 | title: 'Workshop', 62 | items: [ 63 | { 64 | label: 'Crash Course', 65 | href: 'https://everscale.guide/', 66 | }, 67 | { 68 | label: 'EverDev Tutorial', 69 | to: '/develop/smart-contracts/', 70 | }, 71 | { 72 | label: 'Smart contract architecture', 73 | href: 'https://youtu.be/XKMnroPWXek', 74 | }, 75 | { 76 | label: 'Smart contract development', 77 | href: 'https://youtu.be/YBIaFeaksMY', 78 | }, 79 | { 80 | label: 'Development of DeBots', 81 | href: 'https://youtu.be/vFAatJO6cBM', 82 | }, 83 | ], 84 | }, 85 | { 86 | title: 'More', 87 | items: [ 88 | { 89 | label: 'Sample smart-contracts', 90 | href: 'https://github.com/tonlabs/samples', 91 | }, 92 | { 93 | label: 'Sample SDK', 94 | href: 'https://github.com/tonlabs/sdk-samples', 95 | }, 96 | { 97 | label: 'Solidity API', 98 | href: 'https://github.com/tonlabs/TON-Solidity-Compiler/blob/master/API.md', 99 | }, 100 | { 101 | label: 'ABI Specification', 102 | href: '/spec/abi/', 103 | }, 104 | { 105 | label: 'NFT', 106 | to: '/standard/TIP-4/', 107 | }, 108 | { 109 | label: 'CLI', 110 | href: 'https://github.com/tonlabs/tonos-cli', 111 | }, 112 | { 113 | label: 'SDK', 114 | href: 'https://docs.everos.dev/ever-sdk/', 115 | }, 116 | ], 117 | }, 118 | ] 119 | -------------------------------------------------------------------------------- /.build/website/link/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | main: require('./main'), 3 | redirect: require('./redirect'), 4 | footer: require('./footer'), 5 | navbar: require('./navbar'), 6 | } 7 | -------------------------------------------------------------------------------- /.build/website/link/main.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | first: [ 3 | { 4 | title: 'Welcome to Everscale!', 5 | link: '/welcome/', 6 | }, 7 | ], 8 | feature: [ 9 | { 10 | title: '🧰 Start Building', 11 | description: 'Get started building scalable and decentralized App', 12 | link: '/develop/', 13 | }, 14 | { 15 | title: '🏗️ Learn Everscale Architecture', 16 | description: 'Get a high-level understanding of Everscale architecture', 17 | link: '/arch/', 18 | }, 19 | { 20 | title: '🪙 Learn Everscale Standards (TIPs)', 21 | description: 'Description of the Everscale blockchain standards', 22 | link: '/standard/', 23 | }, 24 | { 25 | title: '🧑‍💻 Integrate Network or Token', 26 | description: 'Follow our extensive integration guides to ensure a seamless user experience', 27 | link: '/develop/integrate/', 28 | }, 29 | { 30 | title: '🗳️ Run a Validator Node', 31 | description: 'Validate transactions, secure the network, and earn rewards', 32 | link: '/validate/', 33 | }, 34 | { 35 | title: '🎓 Understand Everscale and its use cases', 36 | description: 'Get familiar with the terminology and core concepts of Everscale', 37 | link: '/learn/overview/', 38 | }, 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /.build/website/link/navbar.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | { 3 | label: 'Overview', 4 | to: '/overview/', 5 | }, 6 | { 7 | label: 'Build', 8 | to: '/develop/' 9 | }, 10 | { 11 | label: 'Validate', 12 | to: '/validate/' 13 | }, 14 | { 15 | label: 'Standards', 16 | to: '/standard/', 17 | }, 18 | { 19 | label: 'Crash Course', 20 | href: 'https://everscale.guide/', 21 | }, 22 | { 23 | label: 'Contribute', 24 | to: '/contribute/', 25 | position: 'right', 26 | }, 27 | { 28 | label: 'Blog', 29 | href: 'https://blog.everscale.network/', 30 | position: 'right', 31 | }, 32 | { 33 | label: 'Status', 34 | href: 'https://monitoring.ever.rs/', 35 | position: 'right', 36 | }, 37 | { 38 | href: 'https://github.com/everscale-org/docs/', 39 | label: 'GitHub', 40 | position: 'right', 41 | }, 42 | ] 43 | -------------------------------------------------------------------------------- /.build/website/link/redirect.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | redirects: [ 3 | { 4 | from: '/develop/tools', 5 | to: '/develop/tools-overview/', 6 | }, 7 | { 8 | from: '/develop/tutorial/getting-started', 9 | to: '/contribute/getting-started/', 10 | }, 11 | { 12 | from: '/develop/debots', 13 | to: '/spec/debot-specifications/', 14 | }, 15 | { 16 | from: '/develop/integrate/tutorial/add-everscale-to-your-exchange', 17 | to: '/develop/recipes/backend-integration/', 18 | }, 19 | { 20 | from: '/develop/client-api/overview', 21 | to: '/develop/tools-overview/', 22 | }, 23 | { 24 | from: '/develop/solidity-developing/samples', 25 | to: '/develop/', 26 | }, 27 | { 28 | from: '/develop/tutorial/smart-digital-assets', 29 | to: '/develop/smart-contracts/use-fungible-tokens/', 30 | }, 31 | { 32 | from: '/integrate/products-api', 33 | to: '/develop/tools-overview/', 34 | }, 35 | { 36 | from: '/develop/tools', 37 | to: '/develop/tools-overview/', 38 | }, 39 | { 40 | from: '/arch/ever-os', 41 | to: '/arch/', 42 | }, 43 | { 44 | from: '/develop/tutorial/everdev-sc', 45 | to: '/develop/smart-contracts/everdev/', 46 | }, 47 | { 48 | from: '/learn/overview', 49 | to: '/overview/', 50 | }, 51 | { 52 | from: '/develop/multisignature-wallet', 53 | to: '/develop/tools-overview/', 54 | }, 55 | { 56 | from: '/validate/staking', 57 | to: '/spec/depool-specification/', 58 | }, 59 | ], 60 | } 61 | -------------------------------------------------------------------------------- /.build/website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "everscale-docs-website", 3 | "version": "1.0.0-alpha.0", 4 | "license": "UNLICENSED", 5 | "engines": { 6 | "node": ">=16.14" 7 | }, 8 | "externalDocs": { 9 | "EverVM": "1.8.136" 10 | }, 11 | "scripts": { 12 | "emul": "yarn clear && yarn build && yarn serve", 13 | "docusaurus": "docusaurus", 14 | "start": "docusaurus start", 15 | "build-favicons": "node favicons", 16 | "cname": "echo docs.everscale.network > build/CNAME", 17 | "build-after": "node script/sitmap", 18 | "build-search": "yarn swizzle docusaurus-lunr-search SearchBar -- --eject --danger", 19 | "build-before": "yarn build-favicons && yarn build-pdf", 20 | "build-pdf": "bash script/build-pdf.sh", 21 | "build": "yarn build-before && docusaurus build && yarn build-after", 22 | "swizzle": "docusaurus swizzle", 23 | "deploy-gh-pages": "yarn clear && yarn build && gh-pages --repo $(git remote get-url gh-pages) --dist build", 24 | "clear": "docusaurus clear && rm -f static/*.pdf && rm -f *.tex", 25 | "serve": "docusaurus serve", 26 | "write-translations": "docusaurus write-translations", 27 | "write-heading-ids": "docusaurus write-heading-ids" 28 | }, 29 | "dependencies": { 30 | "@akebifiky/remark-simple-plantuml": "^1.0.2", 31 | "@docusaurus/core": "^2.4.1", 32 | "@docusaurus/plugin-client-redirects": "^2.4.1", 33 | "@docusaurus/plugin-google-gtag": "^2.4.1", 34 | "@docusaurus/plugin-sitemap": "^2.4.1", 35 | "@docusaurus/preset-classic": "^2.4.1", 36 | "@docusaurus/theme-mermaid": "^2.4.1", 37 | "@mdx-js/react": "^1.6.21", 38 | "clsx": "^1.1.1", 39 | "docusaurus-lunr-search": "^2.1.15", 40 | "favicons": "^6", 41 | "gh-pages": "^3.2.3", 42 | "hast-util-is-element": "1.1.0", 43 | "prism-react-renderer": "^1.2.1", 44 | "react": "^17.0.1", 45 | "react-dom": "^17.0.1", 46 | "rehype-katex": "5", 47 | "rehype-mathjax": "^4.0.2", 48 | "remark-math": "3" 49 | }, 50 | "browserslist": { 51 | "production": [ 52 | ">0.5%", 53 | "not dead", 54 | "not op_mini all" 55 | ], 56 | "development": [ 57 | "last 1 chrome version", 58 | "last 1 firefox version", 59 | "last 1 safari version" 60 | ] 61 | }, 62 | "devDependencies": { 63 | "fast-xml-parser": "^4.1.3" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /.build/website/preview.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | pr="${1}" 6 | if [ -z "${pr}" ]; then 7 | echo "Usage: $0 " 8 | exit 1 9 | fi 10 | 11 | if [ ! -f local-pages/.git/config ]; then 12 | git clone --depth 1 git@github.com:everscale-org/preview.git local-pages 13 | else 14 | git -C local-pages pull 15 | fi 16 | 17 | export SITE_URL="https://everscale-org.github.io" 18 | export SITE_BASE_URL="/preview/PR-${pr}/" 19 | git remote remove gh-pages || true 20 | yarn clear 21 | yarn build 22 | rm -fr "local-pages/PR-${pr}" 23 | mv build "local-pages/PR-${pr}" 24 | git -C local-pages add . 25 | ref=$(git log -n 1 --pretty=format:%h) 26 | git -C local-pages commit -m "up https://github.com/everscale-org/docs/pull/${pr} by https://github.com/everscale-org/docs/commit/${ref}" 27 | git -C local-pages push 28 | -------------------------------------------------------------------------------- /.build/website/script/build-pdf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | 5 | if [ ! -f .bin/laton ]; then 6 | mkdir -p .bin/ 7 | curl -L https://raw.githubusercontent.com/aslushnikov/latex-online/master/util/latexonline > .bin/laton && chmod 755 .bin/laton 8 | fi 9 | 10 | EVER_VM_VERSION=${1:-"$(jq < package.json -r .externalDocs.EverVM)"} 11 | EVER_VM_REPO="https://raw.githubusercontent.com/tonlabs/ever-vm" 12 | EVER_VM_URL="${EVER_VM_REPO}/${EVER_VM_VERSION}/doc/tvm.tex" 13 | wget --quiet "${EVER_VM_URL}" 14 | ./.bin/laton -o static/tvm.pdf tvm.tex 15 | rm -f tvm.tex 16 | -------------------------------------------------------------------------------- /.build/website/script/sitmap.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const { 4 | XMLParser, 5 | XMLBuilder, 6 | XMLValidator, 7 | } = require('fast-xml-parser') 8 | 9 | function parseSitmap(sitemapPath, processorList, options = {}) { 10 | const data = fs.readFileSync(sitemapPath, 'utf-8') 11 | const parser = new XMLParser(options) 12 | let xml = parser.parse(data) 13 | for (const processor of processorList) { 14 | xml = processor(xml) 15 | } 16 | const builder = new XMLBuilder() 17 | let content = '' 18 | content += builder.build(xml).slice(21) 19 | fs.writeFileSync(sitemapPath, content) 20 | } 21 | 22 | const root = path.dirname(path.dirname(__filename)) 23 | const sitemapPath = path.join(root, 'build', 'sitemap.xml') 24 | 25 | parseSitmap(sitemapPath, [ 26 | (sitemap) => { 27 | sitemap.urlset.url = sitemap.urlset.url.map(it => { 28 | if (it.loc[it.loc.length - 1] != '/') { 29 | it.loc += '/' 30 | } 31 | return it 32 | }) 33 | return sitemap 34 | } 35 | ]) 36 | -------------------------------------------------------------------------------- /.build/website/sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creating a sidebar enables you to: 3 | - create an ordered group of docs 4 | - render a sidebar for each doc of that group 5 | - provide next/previous navigation 6 | 7 | The sidebars can be generated from the filesystem, or explicitly defined here. 8 | 9 | Create as many sidebars as you want. 10 | */ 11 | 12 | // @ts-check 13 | 14 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 15 | const sidebars = { 16 | tutorialSidebar: [ 17 | {type: 'autogenerated', dirName: '.'} 18 | ], 19 | // docs: { 20 | // About: ["intro"] 21 | // } 22 | // But you can create a sidebar manually 23 | /* 24 | tutorialSidebar: [ 25 | { 26 | type: 'category', 27 | label: 'Tutorial', 28 | items: ['hello'], 29 | }, 30 | ], 31 | */ 32 | }; 33 | 34 | module.exports = sidebars; 35 | -------------------------------------------------------------------------------- /.build/website/src/components/HomepageFeatures.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import clsx from 'clsx'; 3 | import styles from './HomepageFeatures.module.css'; 4 | import Link from '@docusaurus/Link'; 5 | import { main } from '../../link'; 6 | 7 | function Feature({title, description, link}) { 8 | return ( 9 |
10 | 11 |
12 |
13 |

{title}

14 |
15 |
16 |

{description}

17 |
18 |
19 | 20 |
21 | ); 22 | } 23 | 24 | export default function HomepageFeatures() { 25 | return ( 26 |
27 |
28 |
29 | {main.feature.map((props, idx) => ( 30 | 31 | ))} 32 |
33 |
34 |
35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /.build/website/src/components/HomepageFeatures.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .feature { 9 | margin-bottom: 2rem; 10 | } 11 | -------------------------------------------------------------------------------- /.build/website/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Any CSS included here will be global. The classic template 3 | * bundles Infima by default. Infima is a CSS framework designed to 4 | * work well for content-centric websites. 5 | */ 6 | 7 | /* You can override the default Infima variables here. */ 8 | :root { 9 | --ifm-color-primary: #937EFF; 10 | --ifm-color-primary-dark: #937EFF; 11 | --ifm-color-primary-darker: #6347F5; 12 | --ifm-color-primary-darkest: #210FB7; 13 | --ifm-color-primary-light: #C7BCFF; 14 | --ifm-color-primary-lighter: #FFD688; 15 | --ifm-color-primary-lightest: #FFFFAE; 16 | --ifm-code-font-size: 95%; 17 | } 18 | 19 | .docusaurus-highlight-code-line { 20 | background-color: rgba(0, 0, 0, 0.1); 21 | display: block; 22 | margin: 0 calc(-1 * var(--ifm-pre-padding)); 23 | padding: 0 var(--ifm-pre-padding); 24 | } 25 | 26 | html[data-theme='dark'] .docusaurus-highlight-code-line { 27 | background-color: rgba(0, 0, 0, 0.3); 28 | } 29 | -------------------------------------------------------------------------------- /.build/website/src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS files with the .module.css suffix will be treated as CSS modules 3 | * and scoped locally. 4 | */ 5 | 6 | .heroBanner { 7 | padding: 4rem 0; 8 | text-align: center; 9 | position: relative; 10 | overflow: hidden; 11 | background-repeat: no-repeat; 12 | background-position: top right; 13 | /*sample for image*/ 14 | /*background-image: -webkit-image-set(url(https://everscale.network/images/Backgrounds/Main/main-hero.png) 1x, url(https://everscale.network/images/Backgrounds/Main/main-hero@2x.png) 2x);*/ 15 | /*background-image: image-set(url(https://everscale.network/images/Backgrounds/Main/main-hero.png) 1x, url(https://everscale.network/images/Backgrounds/Main/main-hero@2x.png) 2x);*/ 16 | } 17 | 18 | @media (max-width: 768px) { 19 | .heroBanner { 20 | background-size: 150%; 21 | } 22 | } 23 | @media screen and (max-width: 966px) { 24 | .heroBanner { 25 | padding: 2rem; 26 | } 27 | } 28 | 29 | .buttons { 30 | display: flex; 31 | align-items: center; 32 | justify-content: center; 33 | padding-top: 2rem; 34 | } 35 | -------------------------------------------------------------------------------- /.build/website/src/theme/SearchBar/index.js: -------------------------------------------------------------------------------- 1 | import React, { useRef, useCallback, useState } from "react"; 2 | import classnames from "classnames"; 3 | import { useHistory } from "@docusaurus/router"; 4 | import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; 5 | import { usePluginData } from '@docusaurus/useGlobalData'; 6 | import useIsBrowser from "@docusaurus/useIsBrowser"; 7 | const Search = props => { 8 | const initialized = useRef(false); 9 | const searchBarRef = useRef(null); 10 | const [indexReady, setIndexReady] = useState(false); 11 | const history = useHistory(); 12 | const { siteConfig = {} } = useDocusaurusContext(); 13 | const isBrowser = useIsBrowser(); 14 | const { baseUrl } = siteConfig; 15 | const initAlgolia = (searchDocs, searchIndex, DocSearch) => { 16 | new DocSearch({ 17 | searchDocs, 18 | searchIndex, 19 | baseUrl, 20 | inputSelector: "#search_input_react", 21 | // Override algolia's default selection event, allowing us to do client-side 22 | // navigation and avoiding a full page refresh. 23 | handleSelected: (_input, _event, suggestion) => { 24 | const url = suggestion.url || "/"; 25 | // Use an anchor tag to parse the absolute url into a relative url 26 | // Alternatively, we can use new URL(suggestion.url) but its not supported in IE 27 | const a = document.createElement("a"); 28 | a.href = url; 29 | // Algolia use closest parent element id #__docusaurus when a h1 page title does not have an id 30 | // So, we can safely remove it. See https://github.com/facebook/docusaurus/issues/1828 for more details. 31 | 32 | history.push(url); 33 | } 34 | }); 35 | }; 36 | 37 | const pluginData = usePluginData('docusaurus-lunr-search'); 38 | const getSearchDoc = () => 39 | process.env.NODE_ENV === "production" 40 | ? fetch(`${baseUrl}${pluginData.fileNames.searchDoc}`).then((content) => content.json()) 41 | : Promise.resolve([]); 42 | 43 | const getLunrIndex = () => 44 | process.env.NODE_ENV === "production" 45 | ? fetch(`${baseUrl}${pluginData.fileNames.lunrIndex}`).then((content) => content.json()) 46 | : Promise.resolve([]); 47 | 48 | const loadAlgolia = () => { 49 | if (!initialized.current) { 50 | Promise.all([ 51 | getSearchDoc(), 52 | getLunrIndex(), 53 | import("./DocSearch"), 54 | import("./algolia.css") 55 | ]).then(([searchDocs, searchIndex, { default: DocSearch }]) => { 56 | if (searchDocs.length === 0) { 57 | return; 58 | } 59 | initAlgolia(searchDocs, searchIndex, DocSearch); 60 | setIndexReady(true); 61 | }); 62 | initialized.current = true; 63 | } 64 | }; 65 | 66 | const toggleSearchIconClick = useCallback( 67 | e => { 68 | if (!searchBarRef.current.contains(e.target)) { 69 | searchBarRef.current.focus(); 70 | } 71 | 72 | props.handleSearchBarToggle && props.handleSearchBarToggle(!props.isSearchBarExpanded); 73 | }, 74 | [props.isSearchBarExpanded] 75 | ); 76 | 77 | if (isBrowser) { 78 | loadAlgolia(); 79 | } 80 | 81 | return ( 82 |
83 | 93 | 110 |
111 | ); 112 | }; 113 | 114 | export default Search; 115 | -------------------------------------------------------------------------------- /.build/website/src/theme/SearchBar/lib/lunar-search.js: -------------------------------------------------------------------------------- 1 | import lunr from "@generated/lunr.client"; 2 | lunr.tokenizer.separator = /[\s\-/]+/; 3 | 4 | class LunrSearchAdapter { 5 | constructor(searchDocs, searchIndex) { 6 | this.searchDocs = searchDocs; 7 | this.lunrIndex = lunr.Index.load(searchIndex); 8 | } 9 | 10 | getLunrResult(input) { 11 | return this.lunrIndex.query(function (query) { 12 | const tokens = lunr.tokenizer(input); 13 | query.term(tokens, { 14 | boost: 10 15 | }); 16 | query.term(tokens, { 17 | wildcard: lunr.Query.wildcard.TRAILING 18 | }); 19 | }); 20 | } 21 | 22 | getHit(doc, formattedTitle, formattedContent) { 23 | return { 24 | hierarchy: { 25 | lvl0: doc.pageTitle || doc.title, 26 | lvl1: doc.type === 0 ? null : doc.title 27 | }, 28 | url: doc.url, 29 | _snippetResult: formattedContent ? { 30 | content: { 31 | value: formattedContent, 32 | matchLevel: "full" 33 | } 34 | } : null, 35 | _highlightResult: { 36 | hierarchy: { 37 | lvl0: { 38 | value: doc.type === 0 ? formattedTitle || doc.title : doc.pageTitle, 39 | }, 40 | lvl1: 41 | doc.type === 0 42 | ? null 43 | : { 44 | value: formattedTitle || doc.title 45 | } 46 | } 47 | } 48 | }; 49 | } 50 | getTitleHit(doc, position, length) { 51 | const start = position[0]; 52 | const end = position[0] + length; 53 | let formattedTitle = doc.title.substring(0, start) + '' + doc.title.substring(start, end) + '' + doc.title.substring(end, doc.title.length); 54 | return this.getHit(doc, formattedTitle) 55 | } 56 | 57 | getKeywordHit(doc, position, length) { 58 | const start = position[0]; 59 | const end = position[0] + length; 60 | let formattedTitle = doc.title + '
Keywords: ' + doc.keywords.substring(0, start) + '' + doc.keywords.substring(start, end) + '' + doc.keywords.substring(end, doc.keywords.length) + '' 61 | return this.getHit(doc, formattedTitle) 62 | } 63 | 64 | getContentHit(doc, position) { 65 | const start = position[0]; 66 | const end = position[0] + position[1]; 67 | let previewStart = start; 68 | let previewEnd = end; 69 | let ellipsesBefore = true; 70 | let ellipsesAfter = true; 71 | for (let k = 0; k < 3; k++) { 72 | const nextSpace = doc.content.lastIndexOf(' ', previewStart - 2); 73 | const nextDot = doc.content.lastIndexOf('.', previewStart - 2); 74 | if ((nextDot > 0) && (nextDot > nextSpace)) { 75 | previewStart = nextDot + 1; 76 | ellipsesBefore = false; 77 | break; 78 | } 79 | if (nextSpace < 0) { 80 | previewStart = 0; 81 | ellipsesBefore = false; 82 | break; 83 | } 84 | previewStart = nextSpace + 1; 85 | } 86 | for (let k = 0; k < 10; k++) { 87 | const nextSpace = doc.content.indexOf(' ', previewEnd + 1); 88 | const nextDot = doc.content.indexOf('.', previewEnd + 1); 89 | if ((nextDot > 0) && (nextDot < nextSpace)) { 90 | previewEnd = nextDot; 91 | ellipsesAfter = false; 92 | break; 93 | } 94 | if (nextSpace < 0) { 95 | previewEnd = doc.content.length; 96 | ellipsesAfter = false; 97 | break; 98 | } 99 | previewEnd = nextSpace; 100 | } 101 | let preview = doc.content.substring(previewStart, start); 102 | if (ellipsesBefore) { 103 | preview = '... ' + preview; 104 | } 105 | preview += '' + doc.content.substring(start, end) + ''; 106 | preview += doc.content.substring(end, previewEnd); 107 | if (ellipsesAfter) { 108 | preview += ' ...'; 109 | } 110 | return this.getHit(doc, null, preview); 111 | 112 | } 113 | search(input) { 114 | return new Promise((resolve, rej) => { 115 | const results = this.getLunrResult(input); 116 | const hits = []; 117 | results.length > 5 && (results.length = 5); 118 | this.titleHitsRes = [] 119 | this.contentHitsRes = [] 120 | results.forEach(result => { 121 | const doc = this.searchDocs[result.ref]; 122 | const { metadata } = result.matchData; 123 | for (let i in metadata) { 124 | if (metadata[i].title) { 125 | if (!this.titleHitsRes.includes(result.ref)) { 126 | const position = metadata[i].title.position[0] 127 | hits.push(this.getTitleHit(doc, position, input.length)); 128 | this.titleHitsRes.push(result.ref); 129 | } 130 | } else if (metadata[i].content) { 131 | const position = metadata[i].content.position[0] 132 | hits.push(this.getContentHit(doc, position)) 133 | } else if (metadata[i].keywords) { 134 | const position = metadata[i].keywords.position[0] 135 | hits.push(this.getKeywordHit(doc, position, input.length)); 136 | this.titleHitsRes.push(result.ref); 137 | } 138 | } 139 | }); 140 | hits.length > 5 && (hits.length = 5); 141 | resolve(hits); 142 | }); 143 | } 144 | } 145 | 146 | export default LunrSearchAdapter; 147 | -------------------------------------------------------------------------------- /.build/website/src/theme/SearchBar/lib/templates.js: -------------------------------------------------------------------------------- 1 | const prefix = 'algolia-docsearch'; 2 | const suggestionPrefix = `${prefix}-suggestion`; 3 | const footerPrefix = `${prefix}-footer`; 4 | 5 | /* eslint-disable max-len */ 6 | 7 | const templates = { 8 | suggestion: ` 9 | 16 |
17 | {{{category}}} 18 |
19 |
20 |
21 | {{{subcategory}}} 22 |
23 | {{#isTextOrSubcategoryNonEmpty}} 24 |
25 |
{{{subcategory}}}
26 |
{{{title}}}
27 | {{#text}}
{{{text}}}
{{/text}} 28 |
29 | {{/isTextOrSubcategoryNonEmpty}} 30 |
31 |
32 | `, 33 | suggestionSimple: ` 34 |
39 |
40 | {{^isLvl0}} 41 | {{{category}}} 42 | {{^isLvl1}} 43 | {{^isLvl1EmptyOrDuplicate}} 44 | 45 | {{{subcategory}}} 46 | 47 | {{/isLvl1EmptyOrDuplicate}} 48 | {{/isLvl1}} 49 | {{/isLvl0}} 50 |
51 | {{#isLvl2}} 52 | {{{title}}} 53 | {{/isLvl2}} 54 | {{#isLvl1}} 55 | {{{subcategory}}} 56 | {{/isLvl1}} 57 | {{#isLvl0}} 58 | {{{category}}} 59 | {{/isLvl0}} 60 |
61 |
62 |
63 | {{#text}} 64 |
65 |
{{{text}}}
66 |
67 | {{/text}} 68 |
69 |
70 | `, 71 | footer: ` 72 |
73 |
74 | `, 75 | empty: ` 76 |
77 |
78 |
79 |
80 |
81 | No results found for query "{{query}}" 82 |
83 |
84 |
85 |
86 |
87 | `, 88 | searchBox: ` 89 | 104 | 105 | 111 | `, 112 | }; 113 | 114 | export default templates; 115 | -------------------------------------------------------------------------------- /.build/website/src/theme/SearchBar/lunar-search.js: -------------------------------------------------------------------------------- 1 | import lunr from "@generated/lunr.client"; 2 | lunr.tokenizer.separator = /[\s\-/]+/; 3 | 4 | class LunrSearchAdapter { 5 | constructor(searchDocs, searchIndex, baseUrl = '/') { 6 | this.searchDocs = searchDocs; 7 | this.lunrIndex = lunr.Index.load(searchIndex); 8 | this.baseUrl = baseUrl; 9 | } 10 | 11 | getLunrResult(input) { 12 | return this.lunrIndex.query(function (query) { 13 | const tokens = lunr.tokenizer(input); 14 | query.term(tokens, { 15 | boost: 10 16 | }); 17 | query.term(tokens, { 18 | wildcard: lunr.Query.wildcard.TRAILING 19 | }); 20 | }); 21 | } 22 | 23 | getHit(doc, formattedTitle, formattedContent) { 24 | return { 25 | hierarchy: { 26 | lvl0: doc.pageTitle || doc.title, 27 | lvl1: doc.type === 0 ? null : doc.title 28 | }, 29 | url: doc.url, 30 | _snippetResult: formattedContent ? { 31 | content: { 32 | value: formattedContent, 33 | matchLevel: "full" 34 | } 35 | } : null, 36 | _highlightResult: { 37 | hierarchy: { 38 | lvl0: { 39 | value: doc.type === 0 ? formattedTitle || doc.title : doc.pageTitle, 40 | }, 41 | lvl1: 42 | doc.type === 0 43 | ? null 44 | : { 45 | value: formattedTitle || doc.title 46 | } 47 | } 48 | } 49 | }; 50 | } 51 | getTitleHit(doc, position, length) { 52 | const start = position[0]; 53 | const end = position[0] + length; 54 | let formattedTitle = doc.title.substring(0, start) + '' + doc.title.substring(start, end) + '' + doc.title.substring(end, doc.title.length); 55 | return this.getHit(doc, formattedTitle) 56 | } 57 | 58 | getKeywordHit(doc, position, length) { 59 | const start = position[0]; 60 | const end = position[0] + length; 61 | let formattedTitle = doc.title + '
Keywords: ' + doc.keywords.substring(0, start) + '' + doc.keywords.substring(start, end) + '' + doc.keywords.substring(end, doc.keywords.length) + '' 62 | return this.getHit(doc, formattedTitle) 63 | } 64 | 65 | getContentHit(doc, position) { 66 | const start = position[0]; 67 | const end = position[0] + position[1]; 68 | let previewStart = start; 69 | let previewEnd = end; 70 | let ellipsesBefore = true; 71 | let ellipsesAfter = true; 72 | for (let k = 0; k < 3; k++) { 73 | const nextSpace = doc.content.lastIndexOf(' ', previewStart - 2); 74 | const nextDot = doc.content.lastIndexOf('.', previewStart - 2); 75 | if ((nextDot > 0) && (nextDot > nextSpace)) { 76 | previewStart = nextDot + 1; 77 | ellipsesBefore = false; 78 | break; 79 | } 80 | if (nextSpace < 0) { 81 | previewStart = 0; 82 | ellipsesBefore = false; 83 | break; 84 | } 85 | previewStart = nextSpace + 1; 86 | } 87 | for (let k = 0; k < 10; k++) { 88 | const nextSpace = doc.content.indexOf(' ', previewEnd + 1); 89 | const nextDot = doc.content.indexOf('.', previewEnd + 1); 90 | if ((nextDot > 0) && (nextDot < nextSpace)) { 91 | previewEnd = nextDot; 92 | ellipsesAfter = false; 93 | break; 94 | } 95 | if (nextSpace < 0) { 96 | previewEnd = doc.content.length; 97 | ellipsesAfter = false; 98 | break; 99 | } 100 | previewEnd = nextSpace; 101 | } 102 | let preview = doc.content.substring(previewStart, start); 103 | if (ellipsesBefore) { 104 | preview = '... ' + preview; 105 | } 106 | preview += '' + doc.content.substring(start, end) + ''; 107 | preview += doc.content.substring(end, previewEnd); 108 | if (ellipsesAfter) { 109 | preview += ' ...'; 110 | } 111 | return this.getHit(doc, null, preview); 112 | 113 | } 114 | search(input) { 115 | return new Promise((resolve, rej) => { 116 | const results = this.getLunrResult(input); 117 | const hits = []; 118 | results.length > 5 && (results.length = 5); 119 | this.titleHitsRes = [] 120 | this.contentHitsRes = [] 121 | results.forEach(result => { 122 | const doc = this.searchDocs[result.ref]; 123 | const { metadata } = result.matchData; 124 | for (let i in metadata) { 125 | if (metadata[i].title) { 126 | if (!this.titleHitsRes.includes(result.ref)) { 127 | const position = metadata[i].title.position[0] 128 | hits.push(this.getTitleHit(doc, position, input.length)); 129 | this.titleHitsRes.push(result.ref); 130 | } 131 | } else if (metadata[i].content) { 132 | const position = metadata[i].content.position[0] 133 | hits.push(this.getContentHit(doc, position)) 134 | } else if (metadata[i].keywords) { 135 | const position = metadata[i].keywords.position[0] 136 | hits.push(this.getKeywordHit(doc, position, input.length)); 137 | this.titleHitsRes.push(result.ref); 138 | } 139 | } 140 | }); 141 | hits.length > 5 && (hits.length = 5); 142 | resolve(hits); 143 | }); 144 | } 145 | } 146 | 147 | export default LunrSearchAdapter; 148 | -------------------------------------------------------------------------------- /.build/website/src/theme/SearchBar/styles.css: -------------------------------------------------------------------------------- 1 | .search-icon { 2 | background-image: var(--ifm-navbar-search-input-icon); 3 | height: auto; 4 | width: 24px; 5 | cursor: pointer; 6 | padding: 8px; 7 | line-height: 32px; 8 | background-repeat: no-repeat; 9 | background-position: center; 10 | display: none; 11 | } 12 | 13 | .search-icon-hidden { 14 | visibility: hidden; 15 | } 16 | 17 | @media (max-width: 360px) { 18 | .search-bar { 19 | width: 0 !important; 20 | background: none !important; 21 | padding: 0 !important; 22 | transition: none !important; 23 | } 24 | 25 | .search-bar-expanded { 26 | width: 9rem !important; 27 | } 28 | 29 | .search-icon { 30 | display: inline; 31 | vertical-align: sub; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.build/website/src/theme/SearchBar/templates.js: -------------------------------------------------------------------------------- 1 | const prefix = 'algolia-docsearch'; 2 | const suggestionPrefix = `${prefix}-suggestion`; 3 | const footerPrefix = `${prefix}-footer`; 4 | 5 | const templates = { 6 | suggestion: ` 7 | 14 |
15 | {{{category}}} 16 |
17 |
18 |
19 | {{{subcategory}}} 20 |
21 | {{#isTextOrSubcategoryNonEmpty}} 22 |
23 |
{{{subcategory}}}
24 |
{{{title}}}
25 | {{#text}}
{{{text}}}
{{/text}} 26 |
27 | {{/isTextOrSubcategoryNonEmpty}} 28 |
29 |
30 | `, 31 | suggestionSimple: ` 32 |
37 |
38 | {{^isLvl0}} 39 | {{{category}}} 40 | {{^isLvl1}} 41 | {{^isLvl1EmptyOrDuplicate}} 42 | 43 | {{{subcategory}}} 44 | 45 | {{/isLvl1EmptyOrDuplicate}} 46 | {{/isLvl1}} 47 | {{/isLvl0}} 48 |
49 | {{#isLvl2}} 50 | {{{title}}} 51 | {{/isLvl2}} 52 | {{#isLvl1}} 53 | {{{subcategory}}} 54 | {{/isLvl1}} 55 | {{#isLvl0}} 56 | {{{category}}} 57 | {{/isLvl0}} 58 |
59 |
60 |
61 | {{#text}} 62 |
63 |
{{{text}}}
64 |
65 | {{/text}} 66 |
67 |
68 | `, 69 | footer: ` 70 |
71 |
72 | `, 73 | empty: ` 74 |
75 |
76 |
77 |
78 |
79 | No results found for query "{{query}}" 80 |
81 |
82 |
83 |
84 |
85 | `, 86 | searchBox: ` 87 | 102 | 103 | 109 | `, 110 | }; 111 | 112 | export default templates; 113 | -------------------------------------------------------------------------------- /.build/website/src/theme/SiteMetadata/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | import React from 'react'; 9 | import Head from '@docusaurus/Head'; 10 | import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; 11 | import useBaseUrl from '@docusaurus/useBaseUrl'; 12 | import {PageMetadata, useThemeConfig} from '@docusaurus/theme-common'; 13 | import { 14 | DEFAULT_SEARCH_TAG, 15 | useAlternatePageUtils, 16 | keyboardFocusedClassName, 17 | } from '@docusaurus/theme-common/internal'; 18 | import {useLocation} from '@docusaurus/router'; 19 | import SearchMetadata from '@theme/SearchMetadata'; 20 | 21 | // TODO move to SiteMetadataDefaults or theme-common ? 22 | // Useful for i18n/SEO 23 | // See https://developers.google.com/search/docs/advanced/crawling/localized-versions 24 | // See https://github.com/facebook/docusaurus/issues/3317 25 | function AlternateLangHeaders(): JSX.Element { 26 | const { 27 | i18n: {defaultLocale, localeConfigs}, 28 | } = useDocusaurusContext(); 29 | const alternatePageUtils = useAlternatePageUtils(); 30 | 31 | // Note: it is fine to use both "x-default" and "en" to target the same url 32 | // See https://www.searchviu.com/en/multiple-hreflang-tags-one-url/ 33 | return ( 34 | 35 | {Object.entries(localeConfigs).map(([locale, {htmlLang}]) => ( 36 | 45 | ))} 46 | 54 | 55 | ); 56 | } 57 | 58 | // Default canonical url inferred from current page location pathname 59 | function useDefaultCanonicalUrl() { 60 | const { 61 | siteConfig: {url: siteUrl}, 62 | } = useDocusaurusContext(); 63 | const {pathname} = useLocation(); 64 | return siteUrl + useBaseUrl(pathname); 65 | } 66 | 67 | // TODO move to SiteMetadataDefaults or theme-common ? 68 | function CanonicalUrlHeaders({permalink}: {permalink?: string}) { 69 | const { 70 | siteConfig: {url: siteUrl}, 71 | } = useDocusaurusContext(); 72 | const defaultCanonicalUrl = useDefaultCanonicalUrl(); 73 | 74 | let canonicalUrl = permalink 75 | ? `${siteUrl}${permalink}` 76 | : defaultCanonicalUrl; 77 | if (canonicalUrl[canonicalUrl.length - 1] != '/') { 78 | canonicalUrl += '/' 79 | } 80 | return ( 81 | 82 | 83 | 84 | 85 | ); 86 | } 87 | 88 | export default function SiteMetadata(): JSX.Element { 89 | const { 90 | i18n: {currentLocale}, 91 | } = useDocusaurusContext(); 92 | 93 | // TODO maybe move these 2 themeConfig to siteConfig? 94 | // These seems useful for other themes as well 95 | const {metadata, image: defaultImage} = useThemeConfig(); 96 | 97 | return ( 98 | <> 99 | 100 | 101 | {/* The keyboard focus class name need to be applied when SSR so links 102 | are outlined when JS is disabled */} 103 | 104 | 105 | 106 | {defaultImage && } 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | {/* 115 | It's important to have an additional element here, as it allows 116 | react-helmet to override default metadata values set in previous 117 | like "twitter:card". In same Head, the same meta would appear twice 118 | instead of overriding. 119 | */} 120 | 121 | {/* Yes, "metadatum" is the grammatically correct term */} 122 | {metadata.map((metadatum, i) => ( 123 | 124 | ))} 125 | 126 | 127 | ); 128 | } 129 | -------------------------------------------------------------------------------- /.build/website/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/.build/website/static/.nojekyll -------------------------------------------------------------------------------- /.build/website/static/img/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.build/website/static/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: deploy 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: actions/setup-node@v2 14 | with: 15 | node-version: '16.x' 16 | cache: 'yarn' 17 | cache-dependency-path: '**/yarn.lock' 18 | - run: | 19 | git remote set-url origin https://git:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git 20 | cd .build/website 21 | yarn install 22 | yarn build 23 | yarn cname 24 | yarn gh-pages --dist build --user "github-actions-bot " 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | APP_GA_MEASUREMENT_ID: ${{ secrets.APP_GA_MEASUREMENT_ID }} 28 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | test: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: actions/setup-node@v2 14 | with: 15 | node-version: '16.x' 16 | cache: 'yarn' 17 | cache-dependency-path: '**/yarn.lock' 18 | - run: cd .build/website && yarn install && yarn build 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | favicon* 7 | 8 | # Generated files 9 | .docusaurus 10 | .cache-loader 11 | 12 | # Misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | .idea/ 19 | 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | This agreement is for collaboration, it may not be detailed enough, if it is not clear how to do what you want, this is a normal situation, just ask your colleagues. 4 | ## Tech 5 | 6 | TBD 7 | 8 | ## Main flow 9 | 10 | ```shell 11 | git clone git@github.com:everscale-org/docs.git everscale-docs 12 | cd everscale-docs 13 | git checkout -b feature/name-of-feature origin/main 14 | ``` 15 | 16 | Coding and testing local see [README.md Develop](https://github.com/everscale-org/docs/blob/main/README.md#develop) 17 | 18 | > Git history: work log vs recipe https://www.bitsnbites.eu/git-history-work-log-vs-recipe/ 19 | 20 | Use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) 21 | 22 | ```shell 23 | git commit --message "feat: paypal payment for different users" 24 | ``` 25 | 26 | or 27 | 28 | ```shell 29 | git commit --message "fix: hide password display when searching for a user" 30 | ``` 31 | 32 | Push and create pull requests 33 | 34 | ```shell 35 | git push --set-upstream origin feature/name-of-feature 36 | ``` 37 | 38 | Follow by link: 39 | 40 | ```shell 41 | https://github.com/everscale-org/docs/pull/new/feature/name-of-feature 42 | ``` 43 | 44 | ## Update branch from main 45 | 46 | > A tidy, linear Git history https://www.bitsnbites.eu/a-tidy-linear-git-history/ 47 | 48 | Get the latest upstream changes and update the working branch: 49 | 50 | ```shell 51 | git fetch --prune origin 52 | git rebase --autostash --ignore-date origin/main 53 | ``` 54 | 55 | During the rebase, there may be conflicts, they need to be resolved and after the decision to continue the rebase: 56 | 57 | ```shell 58 | git rebase --continue 59 | ``` 60 | 61 | Upload the updated working branch to the repository, given that we changed the history, this should be done with the force option: 62 | 63 | ```shell 64 | git push --force --set-upstream origin feature/name-of-feature 65 | ``` 66 | 67 | More details can be found in the tutorial: [git rebase](https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase). 68 | -------------------------------------------------------------------------------- /docswrite.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 4 | 5 | See [.build/website/README.md](.build/website/README.md) 6 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Everscale Documentation 2 | 3 | [![CC BY-NC-SA 4.0][cc-by-nc-sa-image]][cc-by-nc-sa] 4 | 5 | [cc-by-nc-sa]: http://creativecommons.org/licenses/by-nc-sa/4.0/ 6 | [cc-by-nc-sa-image]: https://licensebuttons.net/l/by-nc-sa/4.0/88x31.png 7 | 8 | See https://docs.everscale.network/ 9 | 10 | Or create [issue](https://github.com/everscale-org/docs/issues/new) or ask a [question about contracts](https://stackoverflow.com/questions/ask?tags=everscale+solidity) or a [question about SDK](https://stackoverflow.com/questions/ask?tags=everscale+sdk) 11 | -------------------------------------------------------------------------------- /src/arch/05-basics.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Basics 3 | sidebar_position: 0 4 | description: Introduction to understand the basic terminology and concepts 5 | --- 6 | 7 | # Basics of Everscale Blockchain 8 | 9 | ## Blockchain structure 10 | 11 | At the moment, blockchain consists of 2 workchains. One of them (-1), a so-called masterchain, is needed for service contracts and validator contracts, another one (0) is for simple users. In the future, it is possible to add more simple workchains (1, 2, etc) to the blockchain. 12 | 13 | In turn, a workchain is split into shards (so-called shardchains). When the load is low, there are 16 shards. When it increases, shards split and when they decrease they merge. 14 | 15 | Blockchain is validated by validators. Part of them validate masterchain, others are split into groups and validate shardchains. Periodically, the global set of validators changes with elections. Within one election cycle, shardchain validators rotate as well. 16 | 17 | ## Account (contract) 18 | 19 | An account (contract) is identified by its full address consisting of a workchain and ID. Full information about the Account is stored in its state. 20 | An account can have some balance, a place for its code, a place for its data and many other fields. 21 | It can have 1 owner, many owners and no owners at all. 22 | Account ID is calculated during deploy from its initial code and data. 23 | 24 | In order to learn what Accounts are in detail, please follow [this page](40-accounts.md). 25 | 26 | ### About deploy 27 | 28 | Deploy — placing the code of the account onto the blockchain. 29 | 30 | You can not deploy an account's code if its balance is empty because deploy is paid out of that money. This is why any deploy operation must begin with sponsoring the account with some tokens. 31 | 32 | Because the account's ID is unequivocally calculated from code and data, this calculation can be done before the actual deploy. 33 | 34 | ### Address 35 | 36 | An Address is calculated from the initial contract's code and data that is attached to the deploy message. 37 | 38 | When a contract performs SETCODE operation, its address does not change. 39 | 40 | To calculate the contract address, you need to know its code and its initial data (public key of the owner is also stored in the data). 41 | 42 | ### About digital assets transfers 43 | 44 | Digital assets can be transferred from one account to another only by execution of the account's code. 45 | 46 | DO NOT transfer digital assets to the addresses where you can not deploy code because it will stay there forever. 47 | 48 | About fees 49 | 50 | There are several types of fees for operations with contracts. 51 | 52 | For example, commission for storage, execution, and message delivery. 53 | 54 | Please follow [this page](25-fee-calculation.md) for Fee calculation details. 55 | 56 | ### About get methods 57 | 58 | Get method is a method of the contract which doesn't change its state, so it can be executed locally on the client's machine for free. 59 | 60 | What shard my account is in right now? An account shard is defined by the first bits of its address and the current list of shards. 61 | 62 | Encode the hex shard prefix to binary format, discard the most right 1. You just got the shard mask. Put this mask on top of the account address, if the bits are equal — the account is in this shard. 63 | 64 | An account can change its shard depending on the load of the network. So, before calculating an account's shard, check the current list of shards. 65 | 66 | ## Message 67 | 68 | All interactions in Everscale are performed via messages. 69 | 70 | External inbound messages help deploy and call contracts from outside. 71 | 72 | Internal messages allow contracts to communicate with each other. 73 | 74 | External outbound messages are the events the contracts produce for the outside world. Use them to implement some off-chain logic — subscribe for these messages and perform some off-chain actions whenever you receive them. 75 | 76 | For example, a simple value transfer can be initiated with an external inbound message (by developers or a service) or with an internal message from another contract. This message will produce a transaction (read below) and an internal message with value transfer. 77 | 78 | In order to learn what Messages are in detail, please follow [this page](45-message.md). 79 | 80 | ## Transaction 81 | 82 | A transaction is the result of a contract execution. 83 | 84 | In general, a transaction is generated with one incoming message (external or internal) and can generate several outcoming messages (external or internal) as a result. 85 | 86 | The transaction can be successful or aborted. 87 | 88 | For example, a simple value transfer consists of 2 transactions — Sender's transaction which generated an internal message with a value transfer, and Recipient's transaction where it received the message with value and updated its balance. 89 | 90 | ## BOC (Bag of cells) 91 | 92 | It is a universal format for data packaging in Everscale. Every object — account, transaction, message, block is stored in the blockchain database as bocs. By the way, the boc of the block includes bocs of all messages and transactions that were executed in this block inside of it. 93 | 94 | ## TVM 95 | 96 | Turing-complete virtual machine for contract code execution. It works with data represented in boc format. TVM itself does not calculate any commissions and can be used on the client side for running the get methods of the contracts. TVM is used for debot engine execution on the client side as well. 97 | 98 | Also, TVM is used by validators together with higher level protocols, such as Transaction Executor, to additionally calculate commissions and perform other necessary checks. 99 | 100 | In order to learn what TVM is in detail, please follow [this link](10-tvm.md). 101 | 102 | ## Transaction Executor 103 | 104 | It takes the results of TVM, calculates fees, checks balances and other things. Used by validators to validate blocks. Can also be used on the client side to debug contract execution. 105 | 106 | In order to learn what Transaction Executor is in detail, please follow [this link](35-executor.md). 107 | 108 | In order to understand how Everscale blockchain works please follow [this page](../develop/intro.md). 109 | -------------------------------------------------------------------------------- /src/arch/10-tvm.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: The TVM, is the virtual machine used to execute smart-contract 3 | --- 4 | 5 | # TVM 6 | 7 | The primary purpose of the Telegram Open Network Virtual Machine (TON VM or TVM) is to execute smart-contract code in the TON Blockchain. TVM must support all operations required to parse incoming messages and persistent data, and to create new messages and modify persistent data. Now TVM, is used to execute smart-contract code in the masterchain(-1 workchain) and in the basechain(0 workchain). Other workchains may use other virtual machines alongside or instead of the TVM. 8 | 9 | The stack principle forms the foundation of TVM, ensuring its efficiency and ease of implementation. TVM also provides a variety of primitives for working with native data types for the TON Blockchain, such as TVM Cells. More information about the structure and operation principles of TVM can be found here – [Telegram Open Network Virtual Machine tvm.pdf](https://docs.everscale.network/tvm.pdf) is the original document designed by Nikolai Durov and modified by the Everscale Team to take into account the current changes in TVM in the Everscale blockchain. 10 | 11 | ## Additionally 12 | 13 | - [TVM Extended Instructions](https://tonlabs.notion.site/tonlabs/TVM-Extended-Instructions-f22fb9a10bec4f8cadd9757e7d6df51d) 14 | -------------------------------------------------------------------------------- /src/arch/37-logic-time.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Logical Time 3 | description: Logical Time and Message Delivery Guarantees 4 | --- 5 | 6 | # Logical Time and Message Delivery Guarantees 7 | 8 | This very complex topic (the complexity arises due to sharding), and there is no consensus in the community yet on what kind of guarantees we can count on. So everything described below has not yet been confirmed with documentation. 9 | 10 | The examples below are described for cases when all contracts are in the same workchain, but in unknown shards (in the same shard or different ones, it doesn’t matter). 11 | 12 | Guarantees of message delivery order are built on LT guarantees. And of course, everything is described in Nikolai’s WP, but so far there is no certainty that the Rust node is doing everything right. 13 | 14 | LT — Logical time. This is the logical time when a transaction or message was created. 15 | 16 | The main idea here is that the LT of an entity is always greater than the LT of all the entities on which it depends. 17 | 18 | That is, if the LT of the block in which the transaction occurs is 1, then the LT of the transaction of this block is at least 2. The LT of the first message created from this transaction is at least 3, the LT of the second is at least 4, and so on. 19 | 20 | ## Delivery order for two contracts 21 | 22 | When a contract receives incoming messages, it is guaranteed that it will receive them strictly in ascending order of the LT of those messages. That is, if we send two messages from the same transaction, the one that was sent first will be received first. If two messages are sent by different transactions, then the one that was sent first will be received first (the LT of the second transaction is greater than the first). 23 | 24 | ```plantuml 25 | actor Alice 26 | 27 | "Contrat A" as [A] 28 | "Contrat B" as [B] 29 | 30 | Alice -> A: External message 31 | A -> B: 1 Internal message 32 | A -> B: 2 Internal message 33 | ``` 34 | 35 | In this case, too, Int 1 will come first, but only if `Ext 1` happens before `Ext 2` (if you send two external messages at the same time or close in time, there is no guarantee regarding the order in which they will be added into the block). 36 | 37 | ```plantuml 38 | actor Alice 39 | 40 | "Contrat A" as [A] 41 | "Contrat B" as [B] 42 | 43 | Alice -> A: Ext 1 44 | A -> B: 1 Internal message 45 | ``` 46 | ```plantuml 47 | actor Alice 48 | 49 | "Contrat A" as [A] 50 | "Contrat B" as [B] 51 | 52 | Alice -> A: Ext 2 53 | A -> B: 2 Internal message 54 | ``` 55 | 56 | ## Complicated cases 57 | 58 | :::note 59 | There is no consensus on whether or not you can count on this, so **USE ONLY IF YOU UNDERSTAND WHAT YOU ARE DOING 100%**, otherwise you should only use delivery order guarantees for two contracts. 60 | 61 | (This may change after new consensus) 62 | ::: 63 | 64 | If we send two messages from contract `A`, and `message 1` is sent before `message 2`, then `message 1` will arrive earlier than any other message generated by `message 2`, as in the example below, `Int 1` will always arrive before `Int 3`. 65 | 66 | ```plantuml 67 | actor Alice 68 | 69 | "Contrat A" as [A] 70 | "Contrat B" as [B] 71 | "Contrat C" as [C] 72 | 73 | Alice -> A: Ext 1 74 | A -> C: Int 1 75 | A --> B: Int 2 76 | B -> C: Int 3 77 | ``` 78 | 79 | If you have more than 3 contracts, then the order of delivery is mostly undefined. 80 | 81 | For all other cases, you definitely shouldn’t count on this if you don’t consider yourself a super expert in LT and node operation. **Below I will demonstrate several cases where the delivery order is not defined.** 82 | 83 | ```plantuml 84 | actor Alice 85 | 86 | "Contrat A" as [A] 87 | "Contrat B" as [B] 88 | "Contrat C" as [C] 89 | "Contrat D" as [D] 90 | 91 | Alice -> A: Ext 92 | A --> C: 1 93 | A --> B: 2 94 | C --> D: 3/4 95 | B --> D: 3/4 96 | ``` 97 | 98 | Here the order is not defined, `G` can receive a message from any of the chains first. 99 | 100 | ```plantuml 101 | "Contract A" as [A] 102 | "Contract B" as [B] 103 | "Contract C" as [C] 104 | "Contract D" as [D] 105 | "Contract E" as [E] 106 | "Contract G" as [G] 107 | "Contract F" as [F] 108 | 109 | A --> F: 1 110 | A --> B: 2 111 | B --> C 112 | C --> D 113 | D --> E 114 | E --> G 115 | F --> G 116 | ``` 117 | 118 | This is a more complicated example. If `Ext 1` happens before `Ext 2`, but they occur close to each other in time, then `1` arrives before `3` and `4`, but we don’t know in which order `C` will receive messages `3` and `4`. 119 | 120 | ```plantuml 121 | actor Alice 122 | 123 | "Contrat A" as [A] 124 | "Contrat B" as [B] 125 | "Contrat C" as [C] 126 | 127 | Alice -> A: Ext 1 128 | A -> C: 1 129 | A --> B: 2 130 | B -> C: 3 131 | ``` 132 | 133 | ```plantuml 134 | actor Alice 135 | 136 | "Contrat A" as [A] 137 | "Contrat B" as [B] 138 | "Contrat C" as [C] 139 | 140 | Alice -> A: Ext 2 141 | A -> C: 4 142 | A --> B: 5 143 | B -> C: 6 144 | ``` 145 | -------------------------------------------------------------------------------- /src/arch/45-message.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Message 3 | description: Smart-contracts communicate between each other 4 | --- 5 | 6 | # Message 7 | 8 | In Everscale, smart-contracts communicate between each other and with non-blockchain applications by means of an asynchronous message passing. 9 | 10 | Technically, a message is a data structure encoding one of the following: 11 | - desired function call at a destination smart-contract, optionally attaching some coins. 12 | - event log record to signal external observers about some significant state being reached 13 | 14 | A message consists of: `header` and `body`. The header contains the information about the sender, receiver, value as well as the information required by the validator to apply the message to the block. The message body, in turn, comprises the payload of VM instructions that are necessary for the execution of the smart contract. 15 | 16 | There are three types of messages on Everscale: 17 | 18 | **Inbound external message** - a message sent from outside onto the Everscale blockchain. It can be sent by any actor outside the blockchain. So-called messages from nowhere. Inbound external messages initiate changes to the blockchain’s state. It is important to mention that external messages can not be value-bearing. They can only declare intent to transfer value to another account. 19 | 20 | **Internal message**: a message sent from one contract to another. Like an inbound external message, it updates the blockchain's state. Only internal messages can be value-bearing. 21 | 22 | **Outbound external message**: aka event - a message that can be emitted by a smart contract. Off-chain participants can subscribe to events within the Everscale network and receive them. 23 | 24 | ```rust 25 | pub struct Message { 26 | header: CommonMsgInfo, 27 | init: Option, 28 | body: Option, 29 | body_to_ref: Option, 30 | init_to_ref: Option, 31 | } 32 | ``` 33 | 34 | The last two fields `body_to_ref` and `init_to_ref` are used only for serialization purpose, hence not considered in this document. 35 | 36 | ## Message Header 37 | 38 | Any message has a message header: a data-structure defining, among other things, the message type and source and destination addresses. 39 | 40 | The message header defines its type. It is described by the following enumeration: 41 | 42 | ```rust 43 | pub enum CommonMsgInfo { 44 | IntMsgInfo(InternalMessageHeader), 45 | ExtInMsgInfo(ExternalInboundMessageHeader), 46 | ExtOutMsgInfo(ExtOutMessageHeader), 47 | } 48 | ``` 49 | 50 | ## Internal Message 51 | 52 | Within Everscale blockchain, smart-contracts communicate with each other by exchanging messages. Messages sent by smart-contracts are called internal. 53 | 54 | They are opposed to external messages that are sent by off-chain applications to smart-contracts. 55 | 56 | The message header of an internal message is defined as follows: 57 | 58 | ```rust 59 | pub struct InternalMessageHeader { 60 | pub ihr_disabled: bool, 61 | pub bounce: bool, 62 | pub bounced: bool, 63 | pub src: MsgAddressIntOrNone, 64 | pub dst: MsgAddressInt, 65 | pub value: CurrencyCollection, 66 | pub ihr_fee: Grams, 67 | pub fwd_fee: Grams, 68 | pub created_lt: u64, 69 | pub created_at: UnixTime32, 70 | } 71 | ``` 72 | 73 | #### InternalMessageHeader fields 74 | | Field | Description | 75 | |----------------|---------------------------------------------------------------| 76 | | `ihr_disabled` | IHR routing protocol disabled, always `true` | 77 | | `bounce` | Should the answer message be generated in case of an error | 78 | | `bounced` | Is this message was auto-generated by error handling | 79 | | `src` | Message source [address](40-accounts.md#account-address) | 80 | | `dst` | Message destination [address](40-accounts.md#account-address) | 81 | | `value` | Amount of coins attached to the message | 82 | | `ihr_fee` | IHR fee amount, always `0` | 83 | | `fwd_fee` | Message delivery fee amount | 84 | | `created_lt` | Message creation logic time | 85 | | `created_at` | Message creation time in Epoch | 86 | 87 | Some clarifications: 88 | - `bounced` flag is set when the message itself was auto-generated as a result of an error. If the message with _bounced_ flag leads to an error itself, the next bounced message will not be generated. 89 | - `value` is measured in Nano Evers ($10^{-9}$) 90 | - `reated_lt` is a monotonically increasing counter, thanks to this field, each new generated message is unique, even if the message payload is the same. The message creation logic time is also used to guarantee order of delivery. We do not dive deep into this question, because it is protocol-level details. 91 | 92 | ## External Message 93 | 94 | External messages are created outside of the blockchain and get sent through specially distinguished validator nodes called DApp Servers[^2]. 95 | 96 | External message header is defined as follows: 97 | 98 | ```rust 99 | pub struct ExternalInboundMessageHeader { 100 | pub src: MsgAddressExt, 101 | pub dst: MsgAddressInt, 102 | pub import_fee: Grams, 103 | } 104 | ``` 105 | 106 | - Fields `src` and `dst` are source and destination addresses. 107 | - Field `import_fee` should have been the value paid to the validator for processing an external message. But in the current node, this field is not used. Hence, the fee is not paid. We reported this issue to the developers. 108 | - The source address for an external message is always set to `AddrNone`. 109 | 110 | ```rust 111 | pub enum MsgAddressExt { 112 | AddrNone, 113 | AddrExtern(MsgAddrExt), 114 | } 115 | ``` 116 | 117 | The second variant `AddrExtern` is not supported currently. 118 | 119 | ## Events 120 | 121 | Event can be considered as a log record. It is used to signal external observers of reaching some significant state in a smart-contract. 122 | 123 | Usually, observers are external non-blockchain applications that constantly monitor blockchain state[^3]. Other smart-contracts are not able to catch events. 124 | 125 | ```rust 126 | pub struct ExtOutMessageHeader { 127 | pub src: MsgAddressIntOrNone, 128 | pub dst: MsgAddressExt, 129 | pub created_lt: u64, 130 | pub created_at: UnixTime32, 131 | } 132 | ``` 133 | 134 | ```rust 135 | pub enum MsgAddressIntOrNone { 136 | None, 137 | Some(MsgAddressInt) 138 | } 139 | ``` 140 | 141 | - [Transaction Executor](35-executor.md) automatically assigns the source address `src` to be equal to the smart-contract address emitting the event. 142 | - The destination address `dst` may contain any identifier. It is included for easier integration with off-chain applications, i.e. applications can monitor emitted events based on their destination address, and consume only those events destined to their custom identifier. 143 | - Fields `created_lt`, `created_at` defines the logical creation time and epoch creation time. 144 | 145 | ## Reference 146 | 147 | [^1]: In the original TON, message dichotomy is different: they distinguish 4 types of messages: `(inbound + outbound) * (internal + external)`. We find this dichotomy a bit tedious to use in practice 148 | [^2]: In the current protocol implementation, not all validator nodes process external messages. This is subject to change in the future protocol versions 149 | [^3]: For example, by sending GraphQL requests to the DApp-server 150 | -------------------------------------------------------------------------------- /src/arch/50-transactions.md: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | # Transactions 5 | 6 | Let’s once again recall that all interactions on Evercale network are performed via messages. Messages, in turn, create transactions that modify the account's state. 7 | 8 | ![](../img/tp-1.svg) 9 | 10 | ## Transaction 11 | 12 | A transaction is the result of an inbound message processing by a recipient account code. That is, when an account receives an inbound message, it leads to the computation of the account's new state and the possibility of generating one or more outbound messages with the account serving as the source. The inbound message and the previous state of the account serve as inputs for the transaction, while the generated outbound messages and the next state of the account serve as outputs. This relationship can be represented as a Directed Acyclic Graph (DAG). 13 | 14 | ![](../img/tp-2.svg) 15 | 16 | ## Transaction phases 17 | 18 | A transaction is composed of several phases. Each phase may either complete successfully or result in an error. In case of error, the next stage is not completed. 19 | 20 | **Storage phase** - is for the collection of storage payments for the account state (smart contract code and data). Throughout this phase, the smart contract may be frozen if its balance is insufficient to pay the storage fee. It is worth mentioning that there is no storage phase if the transaction is sent to deploy a new smart contract. 21 | 22 | **Credit phase** - adding the value of the internal message received to the account's balance. 23 | 24 | **Computing phase** - starts when the smart contract code is invoked inside an instance of TVM with appropriate parameters, including the inbound message and the account's persistent data. The result of this phase is an exit code, new persistent data, and an action list, which includes outbound messages to be sent. Also, it may end up creating a new account, uninitialized or active, or activating a previously uninitialized or frozen account. The gas fee for computation is deducted from the account balance. 25 | 26 | **Action phase** - starts when the actions from the actions list are performed if the smart contract is executed successfully (with exit code 0 or 1). Suppose, it is impossible to perform all the actions. For example, because of insufficient funds to transfer with an outbound message. In that case, the transaction is terminated, and the account state is rolled back. 27 | 28 | **Bounce phase** - starts when a transaction is terminated. That is, the inbound message has its bounce flag set. Respectively, there is an automatically generated outbound message, with the bounce flag clear, transferring the funds back to the sender. It takes the value of the original inbound message, deducts gas and forwarding fees and transfers the resulting amount to the newly generated message. 29 | 30 | ## Specification 31 | 32 | Read more about transactions execution in [Transaction executor Specification](35-executor.md#transaction) 33 | 34 | ## How to determine a successful transaction? 35 | 36 | It depends on the account state before and after the transaction (fields `orig_status` and `end_status`): 37 | 38 | - If the account was already deployed, i.e. if `(tx.orig_status == tx.end_status == active)` then you can use `tx.aborted` field. If it is `true`, then the transaction is not successful. 39 | 40 | - If the account was not yet deployed then 41 | 42 | - if `(orig_status == nonExist && end_status == uninit && aborted == true)` then transaction is successful. 43 | 44 | All the transactions executed on non-deployed accounts are aborted by definition but if we see the state has changed to `uninit`, it means that the transfer was successfully received. 45 | 46 | - if `(orig_status == uninit && end_status == uninit && aborted == true && in_message.bounce==false)`then transaction is successful. 47 | 48 | Non-bounced messages are successfully received by non-deployed accounts, though the transaction status is aborted. 49 | 50 | Instead of checking `tx.in_message.bounce==false` you can check if `tx.bounce.bounce_type<2` (tx.bounce.bounce_type==2(Ok) is equal to in_message.bounce==true) 51 | -------------------------------------------------------------------------------- /src/arch/55-security.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Security 3 | description: External messages pose threats 4 | --- 5 | 6 | # Smart Contract Security 7 | 8 | ## Replay Attack Protection 9 | 10 | All external messages must be protected against replay attacks. Otherwise, a malicious party can resend an external message obtained from blockchain and repeat a transaction for a smart contract. For example, a hacker can repeat a Token transfer and bring an account balance to zero. For internal messages the risk of replay attacks is irrelevant, as they only can be generated inside blockchain by other contracts. 11 | 12 | ## Implementation Options 13 | 14 | Different approaches to implementing replay attack protection exist. None of them is a silver bullet, but there are several indicators applied to compare and evaluate them: 15 | 16 | - Gas consumption 17 | - Storage fees 18 | - Race condition 19 | - Usability 20 | 21 | ## Sequence number 22 | 23 | This is a very simple protection option. It implies that each protected contract stores a counter (i.e. 32bit integer) that is initially set to zero. An external message is then accepted by the contract only under condition that it contains a number equal to the current contract counter value. Each time a new message is accepted, the contract counter value is incremented by one. 24 | 25 | Pros: 26 | 27 | - simple implementation in contracts 28 | - low gas and storage fees 29 | 30 | Cons: 31 | 32 | - To get the right sequence number off-chain, a client must request the contract state from blockchain before sending an external message. If the state is large, it can cause a network traffic overhead 33 | - Race condition issue that arises when there are multiple contract owners who can simultaneously call it. One owner can increment the contract counter value before this counter becomes available to the next owner 34 | - Less sensitive issue of a potential counter overflow in the future. In this case the TVM will throw an exception causing the owner to lose access to the contract 35 | 36 | ## Timestamp 37 | 38 | Another simple protection option is adding a timestamp to every external message. It can be a 64-bit value in unixtime format. The contract must store the timestamp of the last accepted external message. When a new external message comes, the contract verifies the message timestamp. It must to be bigger than the previous message timestamp and less then `now + interval`. The `interval` value is necessary, because now does not stand for the current time, but indicates creation time of the relevant block. The interval can be equal the block generation period or bigger. 39 | 40 | Pros: 41 | 42 | - Very simple implementation 43 | - No need to request account state before sending external messages 44 | 45 | Cons: 46 | 47 | - Race condition issues remains unresolved as in case of sequence number implementation 48 | - Client time must be synchronized with blockchain time 49 | 50 | ## Set of accepted messages 51 | 52 | Dictionary of randoms 53 | 54 | This option implies that every external message contains a random value, for example, a 32bit integer. A protected contract, in turn, stores previously used randoms in a dictionary, compares message randoms with it and rejects a message if there is a match detected. 55 | 56 | Pros: 57 | 58 | - No need to request account state before sending an external message 59 | - No race condition; simultaneous access to contract of multiple parties is supported. Collisions are still possible when multiple clients have the same random, but chances can be minimized. 60 | 61 | Cons: 62 | 63 | - Consumes a lot of gas for dictionary write/read operations. Note that the gas fee will increase in the future 64 | - High storage fees for storing dictionary 65 | 66 | Dictionary of messages with garbage collection 67 | This option implies that every external message contains an `expire-at` integer that defines the time when the message becomes invalid (i.e. expires). The contract, in turn, must store a dictionary with all recently accepted and not expired external messages. The key is a message hash, the value is the relevant `expire-at` integer. 68 | 69 | The contract then rejects all messages that are already present in its dictionary. To avoid persistent data increase, a protected contract can delete messages with the `expire-at` value less than `now` from its dictionary. 70 | 71 | Pros: 72 | - No need to request the account state before sending an external message 73 | - No race condition issues 74 | 75 | Cons: 76 | - Harder to implement compared to the above option with a dictionary of randoms 77 | - High gas fees caused by the need to access a dictionary 78 | - High storage fees, yet these can be reduced by deleting expired messages from the dictionary 79 | - Garbage collecting also involves some gas costs 80 | 81 | ## Sessions 82 | 83 | Before sending requests to contract, a user creates a session with a contract by sending a `create_session` external message. The message contains a new session ID, its expired-at time and a starting sequence number. The contract stores a session dictionary. 84 | 85 | After a session is created, the user adds the `session_id` and the next session sequence number to every external message. For every external message (not `create_session`) the contract checks that: 86 | 87 | - The message session ID exists in dictionary 88 | - The message sequence number is equal to the stored session number, and 89 | - The `now` value is less then the `expired-at` value for session 90 | 91 | - If all checks are passed successfully, the contract increments the stored sequence number for the session. In case of failure, the message is rejected. 92 | 93 | Also, expired sessions require some garbage collection. 94 | 95 | Pros: 96 | - No need to request the account state before sending an external message 97 | - No race condition issues 98 | - No collisions 99 | 100 | Cons: 101 | - Harder to implement compared to all the options covered above 102 | - High gas fees 103 | - High storage fees 104 | - Need to use garbage collecting 105 | - Unsuitable for simple single-user contracts 106 | 107 | ## Conclusion 108 | 109 | In EverX, we selected a lightweight and simple replay protection option, it will be implemented in the compiler by default and based on the `timestamp` approach. It is supposed to work well for single-user contracts, as well as for contracts without heavy race conditions. It is easy to use given that EverX SDK enables inserting a timestamp automatically on the client side. Also, there will be an option to redefine the default protection method by overloading a special contract function. This is how contract developers will be able to implement any protection option they seem fit. 110 | -------------------------------------------------------------------------------- /src/arch/70-workchains.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Workchains 3 | description: How the blockchain works on the block and queue level 4 | --- 5 | 6 | # How the blockchain works on the block and queue level 7 | 8 | This note is just for a general understanding of how the blockchain works, it’s not 100% accurate, we are waiting for a description from the writers of the node. This may change after a new consensus. 9 | 10 | There is a workchain `-1`, this is the master chain, it is validated by the validators with the largest stake. 11 | 12 | Contracts can be deployed in the `-1` workchain, but it is more expensive, and it was made mainly for governorship. (Probably in the future there will be no user contracts) 13 | 14 | There is a workchain `0`, where contracts are mostly located. More workchains will be launched in the future. 15 | 16 | Workchains are further divided into Processing threads. There is a workchain parameter that indicates the minimum number of processing threads, and currently it is `16` for a `0` workchain. 17 | 18 | Thread processing is an interesting concept. In ES, only computation is shared between the validators of the same workchain, but they all have the same storage. Let’s look at what that means and how it works. 19 | 20 | For example, we have 160 validators for the 0 workchain. They are randomly divided into 16 groups of 10 validators, and each gets its own Processing thread. All workchain contracts are also divided into 16 groups, simply by address ranges. (0.00 - 0:08, 0:08 - 0.18, etc.). 21 | 22 | Each group of validators executes transactions only for their group of smart contracts, and releases blocks of their processing thread. 23 | 24 | But at the same time, they are constantly downloading blocks of other processing threads in order to see their outgoing and incoming message queues. At the same time, blocks are not a list of transactions that need to be rolled up, but a list of incoming messages + a state delta. So, when you download a block of another processing thread, you do not have to do computation in order to update your state. You’re just rolling state changes. 25 | 26 | How roughly works: 27 | 28 | 1. The Masterchain generates block 1. 29 | 2. All threads download the last master block. 30 | 3. Threads create their own block and register it in the master block. 31 | 4. The masterchain generates block 2, which contains the hashes of all blocks of threads that have registered in it. 32 | 5. All threads download masterblock 2. 33 | 6. All threads look at the hashes of the registered blocks of other threads, and download them all. 34 | 7. All threads generate a block. 35 | 8. This process gets repeated. 36 | 37 | Message delivery guarantees also work in this way. When you create a message, it is placed on that thread’s outgoing queue: 38 | 39 | 1. Thread A generates a message for the contract that is in thread B, and creates a block with a new outgoing message in the outgoing queue. 40 | 2. Thread A is registered in the master block. 41 | 3. The masterchain generates a block. 42 | 4. Thread B downloads the master block, and downloads the block of thread A registered there. 43 | 5. Thread B sees the message in thread A and imports it into its inbound queue. (When a message is imported, it is immediately executed (transaction starts) If there is not enough gas for a transaction in the current block, then the message is simply not imported, and waits for its turn in another block. At the same time, there is a message import order, so that validators will not be able to ignore it forever). 44 | 6. Thread B creates a block with a message in the incoming queue, and registers with the master. 45 | 7. Thread A downloads the block in which it sees its message in thread B’s incoming queue and removes the message from its outgoing queue since it was delivered successfully. 46 | 8. Generally, thread A generates a block, then registers it in the master block. Then thread B downloads it, sees that thread A has removed it from its outgoing queue, and deletes it from its incoming one. 47 | 48 | In fact, sharding in this blockchain is the sharding of computational resources. And the data is the same for everyone, with the expectation that all validators have gigabit channels, and we rest only on computation. 49 | 50 | If some processing thread is heavily loaded with the last N blocks, then it will split into two, and new processing threads can also split in turn. Then when the load drops, they all merge. 51 | -------------------------------------------------------------------------------- /src/arch/80-multithreading.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Multithreading 3 | description: How the blockchain works on the block and queue level 4 | --- 5 | 6 | # Multithreading and Message Queues 7 | 8 | ## How the blockchain works on the block and queue level 9 | 10 | This note is just for a general understanding of how the blockchain works, it’s not 100% accurate, we are waiting for a description from the writers of the node. This may change after a new consensus. 11 | 12 | There is a workchain `-1`, this is the master chain, it is validated by the validators with the largest stake. 13 | 14 | Contracts can be deployed in the `-1` workchain, but it is more expensive, and it was made mainly for governorship. (Probably in the future there will be no user contracts) 15 | 16 | There is a workchain `0`, where contracts are mostly located. More workchains will be launched in the future. 17 | 18 | Workchains are further divided into Processing threads. There is a workchain parameter that indicates the minimum number of processing threads, and currently it is `16` for a `0` workchain. 19 | 20 | Thread processing is an interesting concept. In ES, only computation is shared between the validators of the same workchain, but they all have the same storage. Let’s look at what that means and how it works. 21 | 22 | For example, we have 160 validators for the 0 workchain. They are randomly divided into 16 groups of 10 validators, and each gets its own Processing thread. All workchain contracts are also divided into 16 groups, simply by address ranges. (0.00 - 0:08, 0:08 - 0.18, etc.). 23 | 24 | Each group of validators executes transactions only for their group of smart contracts, and releases blocks of their processing thread. 25 | 26 | But at the same time, they are constantly downloading blocks of other processing threads in order to see their outgoing and incoming message queues. At the same time, blocks are not a list of transactions that need to be rolled up, but a list of incoming messages + a state delta. So, when you download a block of another processing thread, you do not have to do computation in order to update your state. You’re just rolling state changes. 27 | 28 | How roughly works: 29 | 30 | 1. The Masterchain generates block 1. 31 | 2. All threads download the last master block. 32 | 3. Threads create their own block and register it in the master block. 33 | 4. The masterchain generates block 2, which contains the hashes of all blocks of threads that have registered in it. 34 | 5. All threads download masterblock 2. 35 | 6. All threads look at the hashes of the registered blocks of other threads, and download them all. 36 | 7. All threads generate a block. 37 | 8. This process gets repeated. 38 | 39 | Message delivery guarantees also work in this way. When you create a message, it is placed on that thread’s outgoing queue: 40 | 41 | 1. Thread A generates a message for the contract that is in thread B, and creates a block with a new outgoing message in the outgoing queue. 42 | 2. Thread A is registered in the master block. 43 | 3. The masterchain generates a block. 44 | 4. Thread B downloads the master block, and downloads the block of thread A registered there. 45 | 5. Thread B sees the message in thread A and imports it into its inbound queue. (When a message is imported, it is immediately executed (transaction starts) If there is not enough gas for a transaction in the current block, then the message is simply not imported, and waits for its turn in another block. At the same time, there is a message import order, so that validators will not be able to ignore it forever). 46 | 6. Thread B creates a block with a message in the incoming queue, and registers with the master. 47 | 7. Thread A downloads the block in which it sees its message in thread B’s incoming queue and removes the message from its outgoing queue since it was delivered successfully. 48 | 8. Generally, thread A generates a block, then registers it in the master block. Then thread B downloads it, sees that thread A has removed it from its outgoing queue, and deletes it from its incoming one. 49 | 50 | In fact, sharding in this blockchain is the sharding of computational resources. And the data is the same for everyone, with the expectation that all validators have gigabit channels, and we rest only on computation. 51 | 52 | If some processing thread is heavily loaded with the last N blocks, then it will split into two, and new processing threads can also split in turn. Then when the load drops, they all merge. 53 | -------------------------------------------------------------------------------- /src/arch/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 5, 3 | "label": "Architecture", 4 | "link": { 5 | "title": "Architecture", 6 | "slug": "arch", 7 | "type": "generated-index" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/arch/consensus/00-introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This document was created when EverX started to reverse engineer a consensus protocol from publicly released source code of Telegram node as part of EverX Node implementation. 4 | 5 | We decided to release this document after the author of the protocol, Dr. Nikolai Durov, released a consensus outline 6 | 👉 https://test.ton.org/catchain.pdf and we highly recommend everybody read the original. 7 | 8 | In this research, we wanted to help other engineers and the general public to gain a better understanding of the underlying protocol, to provide more context by comparing it to other protocols and give more details about practical aspects of Catchain. 9 | 10 | Everscale consensus (dabbed Catchain by its author) is a Proof-of-stake consensus algorithm from a family of Byzantine Fault Tolerant (BFT) algorithms. It includes the consensus algorithm as well as a protocol for message exchange between validator nodes in a network. 11 | 12 | BFT consensus is based on Byzantine Generals agreement and describes a problem of reaching a consensus in distributed system when each network participant does not have an information about the whole network and may not trust any of its participants. 13 | 14 | Blockchain consensus is a classical example of BFT problem as none of the block producers can be trusted or reachable at any given moment. Consensus lies at the core of any blockchain as it allows network nodes to agree on the next block in the blockchain without trusting each other. 15 | 16 | There are generally two classes of POS consensus algorithms. First (CBC Casper, Ouroboros, etc.) when block generation is very easy but forks are allowed with subsequent process of complex agreement on their resolution among the network participants. Catchain belongs to another class — the class of algorithms where block generation agreement is hard but forks are rare or impossible (PBFT, Tendermint, Algorand etc.) 17 | 18 | From a life-cycle perspective, the Catchain consensus includes the following stages: 19 | - stake-based validator elections 20 | - validation session startup 21 | - several block generation rounds 22 | 23 | Each block generation round has limited time and consists of several attempts. So, if validators fail to agree during all available attempts, the round is skipped and the new block is not committed to the blockchain. In the course of a round, validators exchange messages about block candidates generated by collators, validate these candidates, select vote candidates, vote for them and finally commit the elected block to the blockchain. 24 | 25 | To prevent consensus monopolization, the algorithm uses a round-robin role transfer from validator to the validator. So each round and each attempt several validators are assigned to generate blocks and one validator is assigned to propose a block for voting. As validators change roles from an attempt to attempt, the consensus mechanism cannot be blocked by a failure to get a decision from the majority of validators. The key idea here is to make sure that 2/3 of validator votes for a particular block are actually cast. The 2/3 cutoff threshold is a theoretical value that allows making sure that the decision via consensus is made. 26 | 27 | To improve the overall network performance, partial cross-node message synchronization is used. It means that any validator only interacts with a randomly selected subset of validators and uses data obtained from them to make a decision during a validation round. This data also includes aggregated transitive data received from other validators and signed by their signatures. -------------------------------------------------------------------------------- /src/arch/consensus/10-comparison.md: -------------------------------------------------------------------------------- 1 | # Comparison with other solutions 2 | 3 | In order to better understand the Catchain, the EverX team researched similar blockchain consensus algorithms, as this makes code reverse engineering much simpler. 4 | 5 | Everscale consensus overall idea is quite similar to PBFT schemes (PBFT, Tendermint, Algorand). The same three-step phase pattern (Block approval, Voting, Pre-committing) may be found in all of them with slight variations. Let us compare some features of some of these protocols with Catchain: 6 | 7 | ## PBFT 8 | 9 | Oldest of this family of protocols, first described in 1999 by Miguel Castro and Barbara Liskov [4]. 10 | 11 | - Slot leader is re-elected only if it does not perform well. In comparison, Catchain changes leader each round in determenistic fashion. 12 | - One round of block voting requires O(n²) messages (where n = number of nodes). Each node sends a message to all other. Catchain uses a special protocol which greatly reduces the number of messages: the outgoing messages are sent to a small number of neighbors (5 is a default number) and then those neighbors resend them further. 13 | 14 | ## Tendermint 15 | 16 | The closest algorithm to Catchain of all discussed in this chapter, described in [3]. 17 | 18 | - As in Catchain, the proposer node is selected in a round-robin fashion each turn. 19 | - Tendermint requires only local clocks to compute timeouts. This is different from Catchain, which require globally synchronous clocks. This scheme may make Catchain vulnerable to “eclipse” attack: by manipulating NTP messages one may make a node completely out of sync (blockchain will remain correct, but this particular node will not be able to vote and propose its blocks). 20 | - A gossip message-propagation algorithm is implemented, which allows reducing the number of messages to O(n log n) for each voting. Catchain has Catchain overlay protocol for broadcasting messages, which does a similar thing. 21 | 22 | ## Algorand 23 | 24 | - A smaller subset of voters is elected at each step (a “committee”). These elections are held according to a determined, but secret procedure (only a user knows that she is selected to participate in the committee, but she may prove it to others). Only these committee members participate in voting; thanks to cryptographic measures in place, it does not compromise security. 25 | - Requires no synchronous clocks, only the timeout delay should be equal among the nodes. 26 | - Algorand also uses gossip message-propagation algorithm, like Catchain. The authors claim that each node, participating in voting process, sends exactly one message during each voting stage. 27 | 28 | ## Ouroboros, CBC Casper 29 | 30 | - These consensus algorithms [5][6] are quite different: they prefer to build multiple block chains, and forks are made easily. At any given moment there is a set of valid chains, and the algorithms guarantee that any valid transaction is present in any of these chains after generation of R blocks (where R depends on configuration and may be rather big). 31 | 32 | This algorithm type requires a lot fewer synchronization messages, yet it takes more resources to handle multiple parallel chains; also new transactions becomes publicly available much later. -------------------------------------------------------------------------------- /src/arch/consensus/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 2, 3 | "label": "Consensus", 4 | "link": { 5 | "title": "Consensus", 6 | "slug": "arch/consensus", 7 | "type": "generated-index" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/arch/consensus/img/0_5C1TuB_hyZiHnYLI.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/src/arch/consensus/img/0_5C1TuB_hyZiHnYLI.webp -------------------------------------------------------------------------------- /src/arch/consensus/img/0__qmtJKNeq-aBuQU8.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/src/arch/consensus/img/0__qmtJKNeq-aBuQU8.webp -------------------------------------------------------------------------------- /src/arch/networking/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 1, 3 | "label": "Networking", 4 | "link": { 5 | "title": "Networking", 6 | "slug": "arch/networking", 7 | "type": "generated-index" 8 | } 9 | } -------------------------------------------------------------------------------- /src/arch/networking/dht.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # DHT - Distributed Hash Table 6 | 7 | In fact, it is a distributed key-value database, where each network participant can save something. In Everscale, it is used to locate nodes in the network. 8 | 9 | The implementation of DHT in Everscale is similar to that of Kademlia used in IPFS. Any member of the network can run a DHT node, to generate keys and store data. To do this, it is needed to generate a random ID and inform other nodes about it. 10 | 11 | To determine in which node to save data, a special algorithm to determine the distance (it is not about geographic location) between the node and the key is used. The algorithm is pretty straightforward: it is just needed to take both the ID of the node and the ID of the key, and perform the XOR operation. The smaller the resulting value, the closer the node is. The task is to keep the key as close to the nodes as possible. This way, other network participants can use the algorithm to find a node that can provide data about the key. 12 | 13 | ## DHT nodes 14 | 15 | Each DHT node has a 256-bit DHT address. Contrary to ADNL addresses, a DHT address should not change often. In case it is changed too often, other nodes would not be able to locate the keys they are searching for. 16 | 17 | It is expected that the value of key `K` will be stored on `S` Kademlia-nearest nodes to `K`. 18 | 19 | Kademlia distance = 256-bit key `XOR` 256-bit DHT node address. 20 | 21 | `S` is a small parameter, for example `S = 7`, which is required in order to improve the reliability of DHT. If we were to keep the key only on one node. The nearest one to `K`. The value of the respective key would be lost if that single node goes offline. 22 | 23 | ## Kademlia routing table 24 | 25 | Each node in DHT usually keeps a Kademlia routing table. It is comprised of 256 buckets (from 0 to 255). 26 | 27 | The `i`-th bucket incorporates the information about some known nodes, a fixed number of the “best” nodes and maybe some extra candidates that find themselves at a Kademlia distance from `2^i` to `2^(i+1) − 1` from the node’s address `a`. 28 | 29 | The information includes: **DHT addresses, IP addresses and UDP ports**. Also, there is some other information such as the **time** and the **delay** of the last ping. 30 | 31 | When a Kademlia node learns about any other Kademlia node as a result of some query, it places it into a suitable bucket of its routing table. First, as a candidate, then, if some of the “best” nodes in that bucket fail, for instance, do not respond to ping queries for a long time, they can be replaced by some of these candidates. In this way, the Kademlia routing table stays populated. 32 | 33 | ## Key-value pairs 34 | 35 | Everscale DHT allows key-value pairs addition and editing. 36 | 37 | It should be mentioned that **updating rules** can vary. In some instances, it is just the replacement of the old value with the new one. It is applicable in case the new value is signed by the owner. The signature, in turn, must be kept as part of the value. It is to be checked later by other nodes after they obtain the value of the key. In other instances, the old value somehow affects the new value. For instance, it can contain a sequence number and the old value is overwritten only if the new sequence number is larger. This is done in order to prevent replay attacks. 38 | 39 | The purpose of Everscale DHT is not only for storing IP Addresses of ADNL nodes. Besides this, it has many other applications, such as, the storage of: 40 | 41 | - Lists of addresses of nodes included in an overlay subnetwork 42 | - ADNL Addresses of Everscale services 43 | - ADNL addresses of accounts of the Everscale blockchain 44 | -------------------------------------------------------------------------------- /src/arch/networking/networking.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 0 3 | --- 4 | 5 | # Networking 6 | 7 | Everscale uses its own peer-to-peer network protocols. 8 | We use these protocols to propagate new blocks, send and collect transaction candidates and so on. 9 | 10 | While the networking demands of single-blockchain projects, such as Bitcoin or Ethereum, can be met quite easily. One essentially needs to construct a peer-to-peer network and then propagate all new blocks and transaction candidates via a [gossip](https://en.wikipedia.org/wiki/Gossip_protocol) protocol. 11 | 12 | Multi-blockchain projects, such as Everscale, are much more demanding. One must be able to subscribe to updates of only some workchains, not necessarily all of them. 13 | -------------------------------------------------------------------------------- /src/arch/networking/overlay.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Overlay 6 | 7 | Everscale is a multi-blockchain platform. That is, its architecture is built in such a way that a lot of chains can exist simultaneously and even independently. With this, there is a constant need for updates on the network. For instance, full nodes could require updates for new blocks of some chains. All chains in the network, including the masterchain, communicate via their own overlay. To join it, it is needed to find the nodes that are already in it, and start exchanging data with them. 8 | 9 | Overlay subnetworks can be **public** to which anyone can connect, and **private** to which additional credentials are needed. The credentials, in turn, are known only to a certain number of people. 10 | 11 | :::tip Tip 12 | 13 | For public overlays you can find nodes using DHT 14 | 15 | ::: 16 | 17 | ## ADNL in comparison with Overlay networks 18 | 19 | Everscale overlay networks usually do not send datagrams to other arbitrary nodes as happens in ADNL. Alternatively, there are some **semi-permanent links** established between certain nodes (called **neighbors**) with respect to the overlay network. The messages are usually forwarded along these links. For instance, from a node to one of its neighbors. 20 | 21 | :::tip Tip 22 | 23 | Each overlay subnetwork has a 256-bit network identifier. Usually, it is equal to a SHA256 of the description of the overlay network—a TL-serialized object 24 | 25 | ::: 26 | 27 | Overlay subnetworks work according to a special [gossip](https://en.wikipedia.org/wiki/Gossip_protocol) protocol. 28 | -------------------------------------------------------------------------------- /src/arch/networking/rldp.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # RLDP 6 | 7 | Reliable Large Datagram Protocol runs on top of ADNL UDP. It is designed for transmitting big data and includes Forward Error Correction (FEC) algorithms. They are used to replace packet receipt confirmations by the other party. This opens the possibility to transfer data between network components more efficiently. Although, with high traffic consumption. 8 | 9 | RLDP is largely used in the Everscale infrastructure. For example, to download blocks from other nodes and transfer data to them or to make requests to Everscale sites. 10 | 11 | ## Protocol 12 | 13 | To exchange data, RLDP uses the following TL structures: 14 | 15 | ``` 16 | fec.raptorQ data_size:int symbol_size:int symbols_count:int = fec.Type; 17 | fec.roundRobin data_size:int symbol_size:int symbols_count:int = fec.Type; 18 | fec.online data_size:int symbol_size:int symbols_count:int = fec.Type; 19 | 20 | rldp.messagePart transfer_id:int256 fec_type:fec.Type part:int total_size:long seqno:int data:bytes = rldp.MessagePart; 21 | rldp.confirm transfer_id:int256 part:int seqno:int = rldp.MessagePart; 22 | rldp.complete transfer_id:int256 part:int = rldp.MessagePart; 23 | 24 | rldp.message id:int256 data:bytes = rldp.Message; 25 | rldp.query query_id:int256 max_answer_size:long timeout:int data:bytes = rldp.Message; 26 | rldp.answer query_id:int256 data:bytes = rldp.Message; 27 | ``` 28 | 29 | The serialized structure is wrapped in an `adsl.message.custom` TL schema and sent over ADNL UDP. The big data is transmitted via transfers. A random `transfer_id` is generated while the data itself is processed by the FEC algorithm. The received pieces are wrapped in the `rldp.MessagePart` structure and sent to the recipient until the recipient returns `rldp.complete`. When the recipient collects the pieces of `rldp.MessagePart` needed to assemble a complete message the following has to be done: connecting them all together, decoding them using FEC and deserializing the resulting byte array into one of the `rldp.query` or `rldp.answer` structures - depending on the type of TL ID prefix. 30 | 31 | ### FEC 32 | 33 | Valid **Forward Error Correction** algorithms to use with RLDP are Round Robin, Online, and Raptor. Currently, Raptor is used for data exchange. 34 | 35 | #### Raptor 36 | 37 | The essence of **RaptorQ** is that the data is divided into so-called symbols - blocks of the same, predetermined size.4 38 | 39 | Blocks, in turn, serve to create matrices, to which discrete mathematical operations are applied. This allows us to create an almost infinite number of characters from the same data. All characters are mixed, and, thanks to this, it is possible to recover lost packets without requesting additional data from the server. This is accomplished by sending fewer packets than it would be if we were to send the same pieces in the cycle. 40 | 41 | The generated symbols are sent to the recipient until he says that all data has been received and restored by applying the same discrete operations. 42 | 43 | ## RLDP-HTTP 44 | 45 | HTTP (wrapped in RLDP) is used to interact with Everscale sites. The hoster places his site on any HTTP web server and raises the rldp-http proxy next to it. All requests from the Everscale network come via the RLDP protocol to the proxy, and the proxy already reassembles the request into regular HTTP and calls the web server locally. 46 | 47 | :::tip Tip 48 | 49 | The user on his side locally (ideally) raises a proxy, for example Tonutils Proxy, and uses .ton, all traffic is wrapped in reverse order, requests go to the local proxy, and it sends them via RLDP to the remote TON site. 50 | 51 | ::: 52 | 53 | HTTP inside RLDP is implemented using TL structures: 54 | 55 | ``` 56 | http.header name:string value:string = http.Header; 57 | http.payloadPart data:bytes trailer:(vector http.header) last:Bool = http.PayloadPart; 58 | http.response http_version:string status_code:int reason:string headers:(vector http.header) no_payload:Bool = http.Response; 59 | 60 | http.request id:int256 method:string url:string http_version:string headers:(vector http.header) = http.Response; 61 | http.getNextPayloadPart id:int256 seqno:int max_chunk_size:int = http.PayloadPart; 62 | ``` -------------------------------------------------------------------------------- /src/arch/networking/tl.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # TL 6 | 7 | TL (Type Language) is used for describing data structures. To structure data, [TL schemes](https://github.com/ton-blockchain/ton/tree/master/tl/generate/scheme) are used. TL operates with 32-bit blocks. Accordingly, the size of the data in TL should be a multiple of 4 bytes. If the size of the object is not a multiple of 4, we need to add the required number of zero bytes to achieve multiplicity. The Little Endian order is always used to encode numbers. 8 | 9 | TL can be studied in more detail in the [Telegram documentation](https://core.telegram.org/mtproto/TL). 10 | 11 | ### Encoding bytes in TL 12 | 13 | To encode an array of bytes, we first need to determine its size. If it is less than 254 bytes, then encoding with 1 byte is used as size. If it is larger, then `0xFE` is written as the first byte, as an indicator of a large array, and then 3 bytes of size follow it. 14 | 15 | For example, we encode an array `[0xAA, 0xBB]`, its size is 2. We use 1 byte of size and then we write the data ourselves, we get `[0x02, 0xAA, 0xBB]`. That's it! However, we see that the final size is 3 and not a multiple of 4 bytes, then we need to add 1 byte of padding so that there is 4. We get: `[0x02, 0xAA, 0xBB, 0x00]`. 16 | 17 | If we need to encode an array whose size is, for example, 396, we proceed as follows: 396 >= 254, which means we use 3 bytes to encode the size and 1 byte of the increased size indicator, we get: `[0xFE, 0x8C, 0x01, 0x00, array bytes]`, 396+4 = 400, which is a multiple of 4 and does not need to be adjusted. 18 | 19 | ### Non-obvious rules of serialization 20 | 21 | Often, a prefix of 4 bytes is written before the scheme itself - its ID. The schema ID is a CRC32 with an IEEE table from the schema text, while characters such as `;` and brackets `()` are removed from the text. Serialization of a scheme with an ID prefix is called boxed. This allows the parser to determine which scheme is in front of it if several options are possible. 22 | 23 | How to determine whether to serialize as boxed or not? If our schema is part of another schema, then we need to see how the field type is specified. If it is specified explicitly, then we serialize without a prefix. If not explicitly (there are many such types), then we need to serialize as boxed. Example: 24 | 25 | ``` 26 | pub.unenc data:bytes = PublicKey; 27 | pub.ed25519 key:int256 = PublicKey; 28 | pub.aes key:int256 = PublicKey; 29 | pub.overlay name:bytes = PublicKey; 30 | ``` 31 | 32 | We have such types. If `PublicKey` is specified in the schema, for example, `adnl.node` `id:PublicKey addr_list:adnl.AddressList = adnl.Node`, then it is not explicitly specified and we need to serialize with the ID prefix (boxed). And if it were specified like this: `adsl.node id:pub.ed25519 addr_list:all.address List = add.Node`, then it would be explicit, and the prefix would not be needed. -------------------------------------------------------------------------------- /src/contribute/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 10, 3 | "label": "Contribute", 4 | "link": { 5 | "title": "Contribute", 6 | "slug": "contribute", 7 | "type": "generated-index" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/contribute/getting-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 0 3 | --- 4 | 5 | # Getting started 6 | 7 | Since Everscale was created on the principles of decentralization, the management and development of the network are completely decentralized thanks to its community. 8 | 9 | This section provides ways to improve the network by bringing something new to Everscale. 10 | 11 | ## Everscale Grants 12 | 13 | Everscale Grants is a campaign that aims to attract promising IT projects that can contribute to the Everscale ecosystem's growth. 14 | 15 | Approved projects receive not only financial but also technical and marketing support. 16 | 17 | The formation and distribution of grants are handled by DeFi Alliance. 18 | 19 | DeFi Alliance is a business combination that creates the necessary infrastructure to attract teams and projects, raises liquidity from other projects in Everscale, and builds partnerships with large companies with large amounts of liquidity. 20 | 21 | To apply, use the form on the [Everscale Grants page](https://everscale.network/grants) on the [network's website](https://everscale.network/) or Everscale DeFi Alliance [corresponding page](https://everalliance.org/apply-for-grant/) of their [official website](https://everalliance.org/). 22 | 23 | 24 | ## EVER DAO 25 | 26 | [EVER DAO](https://everdao.net) is a decentralized governance platform that allows EVER (wEVER) token holders to vote on proposals relating to the Everscale network. Community members can express their will and opinions on significant network events in a transparent and verifiable way. 27 | 28 | To participate in voting, you must have a certain stake WEVER, which will be equivalent to the strength of your vote. 29 | 30 | 31 | ## Octus Bridge DAO 32 | 33 | [Octus Bridge](https://octusbridge.io/bridge) is a cross-chain solution that allows you to move liquidity between Everscale and many other chains. 34 | 35 | Octus Bridge also has its native BRIDGE token. 36 | 37 | BRIDGE token holders can vote on certain operational decisions of the Octus Bridge platform to make the bridge better. The voting protocol is a real smart contract that is allowed to make changes to other smart contracts. 38 | 39 | There are now more than 23 relays of particular importance in the [Bridge DAO](https://app.octusbridge.io/governance) structure. Any user with at least 100,000 BRIDGE tokens can become a relay. 40 | -------------------------------------------------------------------------------- /src/develop/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 2, 3 | "label": "Build", 4 | "link": { 5 | "title": "Build", 6 | "slug": "develop", 7 | "type": "generated-index" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/develop/account-abstraction.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | title: "Account Abstraction" 4 | --- 5 | 6 | ## On the differences between Ethereum and Everscale approaches to Account Abstraction 7 | 8 | The EIP-4337, also known as an Account Abstraction (AA) was recently deployed on the Ethereum mainnet. In the Everscale blockchain, we believe in the idea of AA as a key enabler for extended wallet functionality, better security, and UX. 9 | 10 | However, due to the desire to deploy it without changes to the core protocol, the original Ethereum AA design is a bit complicated and comes with a separate alt-mempool, bundler nodes, and EntryPoint contract. 11 | 12 | Everscale comes with natively built-in "AA batteries", which makes the dev experience with AA much easier to pick up, especially for newbies. Let's dive deeper into how Everscale's AAs work. 13 | 14 | ### No AA and EOA. Just A 15 | 16 | The Value, be it a native coin or TIP-3 token, can only flow as an effect of smart contract code execution. For us, the notion of EOA shouldn't exist per se, and all Accounts are "abstract". 17 | 18 | ### Lifecycle of an Account 19 | 20 | The Account is deployed with some initial state (code + data). 21 | 22 | The TVM comes with instructions to access and modify Accounts' code, state, send Messages, deploy new Accounts, and more. 23 | 24 | Executing the code in the TVM is invoked by an inbound Message. Both Account-to-Account and User-2-Account Messages are possible. 25 | 26 | ### No EntryPoint 27 | 28 | Users interact with Accounts via sending External Messages. They also may want to use key pairs or session keys to authorize External Messages. As there are no EOAs, all External Messages carry no value. 29 | 30 | When External Message is processed by an Account, the TVM gives some small portion of "credit gas". The developer can use it to perform certain logic before accepting a Message. 31 | 32 | Using the Accounts' own balance requires the "accept" to be done explicitly with a corresponding TVM instruction. 33 | 34 | To reject the External Message, an Account should just not accept it. Rejected External Messages are never included in blocks. 35 | 36 | Thus, each Account is an EntryPoint itself. 37 | 38 | ### Content Addressable Account Spaces 39 | 40 | Each Account is content-addressable: the Account address is deterministically derived from its initial code and state. 41 | 42 | Imagine A1 sends the Message to A2. If such a message includes A1's initial data, A2 can check if A1 has the same code. For that, it will take its own initial code + A1's data and derive the expected address for A1. 43 | 44 | This approach to auth enables developers to build secure systems with address-based access control rules without the need to maintain access control lists explicitly. 45 | 46 | ### Upgradeability 47 | 48 | On EVM, to implement upgradeability for a given A1 you need to deploy at least one additional A2 for your A1. Each upgrade will require at least 1 new Account to be deployed. This approach is well-adopted and known as **Upgradeable Proxy Pattern**. 49 | 50 | On TVM, there is `SETCODE` instruction, which allows Account to upgrade itself with any code, that it can take from inbound Message, or its own storage. Accounts' address remains unchanged, and the Upgrade requires no extra deployments. 51 | 52 | ### Smart Contract Wallets 53 | 54 | One of the key motivations for AA is to put the ownership model in the developers' hands to implement (code is a law). 55 | 56 | With greater power comes great responsibility, and cooking AAs right is important. The best practices and audited templates for AAs are yet to come into the EVM ecosystem. 57 | 58 | At Everscale, there is a [formally verified implementation](https://github.com/EverSurf/multisig2) for singlesig / multisig + the Upgradable version, that enables one to build any logic and plug it on top (keeping the address unchanged) -------------------------------------------------------------------------------- /src/develop/actor-model.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Actor model 6 | 7 | Let's consider one smart contract. 8 | 9 | In Everscale, it is a *thing* with properties like address, code, data, balance and others. In other words, it is an object which has some *storage* and *behavior*. That behavior has the following pattern: 10 | 11 | - a contract gets a message 12 | - contract handles that event by executing its code in TVM 13 | - contract modifies its own properties (code, data and others) 14 | - contract optionally generates outgoing messages (which may include deployments of other contracts) 15 | - contract goes into standby mode until the next event occurs 16 | 17 | A combination of these steps is called a **transaction**. It is important that events are handled one by one, thus *transactions* are strictly ordered and cannot interrupt each other. 18 | 19 | This pattern is well known and called `Actor Model`. -------------------------------------------------------------------------------- /src/develop/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 0 3 | --- 4 | 5 | # Intro 6 | 7 | To start your developer journey with Everscale, some important concepts should be understood first. 8 | 9 | The first one is the mechanism of Dynamic Multithreading, which allows the network to scale as the load increase. 10 | 11 | :::info 12 | 13 | The Dynamic Multithreading is part of Everscale's approach to **Infinite Scalability**. Please follow [here](overview/infinite-scalability.md) to dive deeper. 14 | 15 | ::: 16 | 17 | Shortly speaking, a single workchain can split to shardchains dynamically, and a different subsets of accounts are assigned to different threads, running in parallel. 18 | 19 | To take advantage from that in your Smart Contracts, you can't simply use the same approach as in Ethereum development (where we allow a single smart contract to store lot of data). 20 | 21 | This leads us to the Distributed Programming approach. 22 | 23 | ## Distributed Programming approach 24 | 25 | Instead of writing contracts in which the state can continuously grow, we write distributed systems of smart contracts. For example TIP-3 token standard is designed as a system of main `TokenRoot` contract, which stores metadata, and has a function to deploy a separate smart-contract called `TokenWallet` for each token owner (that is what a wallet is) and can send tokens directly among contracts without a central hub. 26 | 27 | :::info Important concept 28 | 29 | In Everscale, each contract address is a uniquely computed value. A contract address is a hash of the contract code and initial data (initial data is a value of static variables, and not what you pass to the constructor, since in Everscale the constructor is a function that you call after the deployment of the contract in one transaction). 30 | 31 | This is a very important pattern of distributed programming (as it is understood in Everscale). Knowing the code of a contract, and its initial data you can make sure that you are being called by a contract with the same parents as your own. Or, knowing the contract code and its initial data, you can compute the address of a contract on the fly and send messages to it. 32 | 33 | ::: 34 | 35 | By creating small contracts for a single system (like in TIP-3 token) we solve a number of issues: 36 | 37 | * All contracts end up in different shards which distributes the load evenly throughout the network. 38 | * Contract states are very small. Validators can load them very quickly from a disk. 39 | * Storage fee. If we had one contract with a huge hash map, then it would have to pay a large fee for its storage, and it is not clear who should pay and how for this storage. If there are many accounts with small balances that their owners no longer need, then naturally they will not pay for its storage, and the rest of the holders of this token will have to pay for all of the “remainders.” So that smart contract programmers do not have to think about how to force users to pay for storage or clean up old data inside the contract, Everscale has allowed each user to deploy their own contract. Each user determines how long they will pay for storage and can always adjust these parameters. 40 | 41 | ## Contract Deployment 42 | 43 | The concept about deterministic address calculations, described above, is also tied to how contracts are deployed in Everscale. The contract can naturally be deployed by another contract. But what should we do if we want to deploy a contract from outside? 44 | 45 | To do this, we have to take the contract code and its initial data, and compute its future address. 46 | 47 | After that, we simply send money there, with a bounce flag = false. And the money just stays on the address, which has no initialized code. 48 | 49 | Then we send a special external message to this address with the code and initial data, and we say “Look, here we have the code and initial data, the hash of which gives us this address, initialize it please” and the network initializes the contract. -------------------------------------------------------------------------------- /src/develop/recipes/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 6, 3 | "label": "Frontend and Backend recipes", 4 | "link": { 5 | "title": "Frontend and Backend recipes", 6 | "slug": "develop/recipes", 7 | "type": "generated-index" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/develop/recipes/connect-wallet.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | import Tabs from '@theme/Tabs'; 6 | import TabItem from '@theme/TabItem'; 7 | 8 | # Connect Wallet 9 | 10 | This is the most basic routine when you start working with any blockchain. 11 | 12 | And of course we have a way to do it in Everscale. In this section, we cover how to integrate with both EVER Wallet and Surf Keeper web-extensions. 13 | 14 | ### Check if the extension is available 15 | 16 | We always start our interaction with the wallet by checking if the user has a wallet installed: 17 | 18 | 19 | 20 | 21 | ```typescript 22 | import {hasEverscaleProvider} from 'everscale-inpage-provider'; 23 | const isEverWalletInstalled = await hasEverscaleProvider(); 24 | ``` 25 | 26 | 27 | 28 | 29 | 30 | ```typescript 31 | import {hasSurfKeeperProvider} from 'surf-keeper-provider'; 32 | const isSurfKeeperInstalled = await hasSurfKeeperProvider(); 33 | ``` 34 | 35 | 36 | 37 | 38 | If the user doesn't have a wallet installed, ask him to install. 39 | 40 | ### Initialize Provider 41 | 42 | Next, we initialize the provider and retrieve its current state: 43 | 44 | 45 | 46 | 47 | ```typescript 48 | import { ProviderRpcClient } from 'everscale-inpage-provider'; 49 | const ever = new ProviderRpcClient(); 50 | // We may want to await for the extension to be fully initialized 51 | // await ever.ensureInitialized(); 52 | // Get current provider state 53 | const currentProviderState = await ever.getProviderState(); 54 | ``` 55 | 56 | The response should look like following (the values of parameters may change depending on version and selected network): 57 | 58 | ```json 59 | { 60 | "version": "0.3.12", 61 | "numericVersion": 3012, 62 | "networkId": 31337, 63 | "selectedConnection": "localnet", 64 | "supportedPermissions": [ 65 | "basic", 66 | "accountInteraction" 67 | ], 68 | "permissions": {}, 69 | "subscriptions": {} 70 | } 71 | ``` 72 | 73 | 74 | 75 | 76 | ```typescript 77 | import { ProviderRpcClient } from '@eversurf/surfkeeper-provider'; 78 | const rpc = new ProviderRpcClient(); 79 | 80 | // To check whether api is available await for 81 | // rpc.ensureInitialized(); 82 | // connectStatus will return you the same result as `connect` 83 | // described in the next block if connnect was already granted 84 | const connect = await rpc.connectStatus(); 85 | ``` 86 | 87 | The response should look like following (the values of parameters may change depending on version and selected network): 88 | 89 | ```json 90 | { 91 | "isConnected": "true", 92 | "address": "0x00...00", 93 | "publicKey": "" 94 | } 95 | ``` 96 | 97 | 98 | 99 | ### Login and logout 100 | 101 | Login flow is quite different for each wallet: 102 | 103 | 104 | 105 | 106 | To login, we ask a user for permissions to interact with one of the accounts available in his wallet. Two permissions are supported. These are: 107 | 108 | - `basic` - allows the site to retrieve data from the blockchain and use the API to decrypt transactions. 109 | - `accountInteraction` - allows the page to prompt the user for transactions and perform other interactions such as signing a message. 110 | 111 | Asking the user for permission (connect the wallet): 112 | 113 | ```typescript 114 | // Subscribe to new permissions 115 | (await ever.subscribe('permissionsChanged')).on('data', permissions = > { 116 | // You can monitor changes in permissions there 117 | console.log('permissions from subscription', permissions); 118 | }); 119 | // The provider has several events to subscribe to 120 | // connected, disconnected, networkChanged, permissionsChanged, loggedOut 121 | 122 | // Or you can get new permissions there 123 | const permissions = await ever.requestPermissions({ 124 | permissions: ['basic', 'accountInteraction'] 125 | }); 126 | ``` 127 | 128 | The response should look like following (may vary depending on the wallet address, public key, and wallet contract type) 129 | 130 | ```json 131 | { 132 | "accountInteraction": { 133 | "address": "0:3036eb00ab5e3e6824d564b53c4e37f999e8d3db2cb1d878db1d20ae3a5408b6", 134 | "publicKey": "8eea533b840a598af3975d139926ba7f3888d3226f8597732227fe0fbf3875ac", 135 | "contractType": "SafeMultisigWallet" 136 | }, 137 | "basic": true 138 | } 139 | ``` 140 | 141 | You may want to provide “logout” and “change account” features in your app, using following interface: 142 | 143 | ```typescript 144 | // To disconnect, you can use 145 | await ever.disconnect(); 146 | // or changeAccount 147 | await ever.changeAccount(); 148 | ``` 149 | 150 | 151 | 152 | 153 | 154 | To interact with one's account we request permission to connect a page to the extension. It is as simple as: 155 | 156 | ```typescript 157 | const connectResponse = await rpc.connect(); 158 | ``` 159 | 160 | > **_NOTE:_** By this time extension should be initialized and be logged in into user's account. 161 | 162 | The response should look like following: 163 | 164 | ```json 165 | { 166 | "isConnected": "true", 167 | "address": "0x00...00", 168 | "publicKey": "" 169 | } 170 | ``` 171 | 172 | You may want to provide disconnect option in your app, using following interface: 173 | 174 | ```typescript 175 | await rpc.disconnect(); 176 | ``` 177 | The response should look like following: 178 | 179 | ```json 180 | { 181 | "isConnected": "false", 182 | } 183 | ``` 184 | 185 | 186 | 187 | 188 | 189 | ### NetworkId check 190 | 191 | After we got the permissions, we can interact with the wallet and retrieve data from the blockchain. You may want to render different thing for differend networks (mainnet / testnet). 192 | 193 | Let’s assume our target contract is deployed in the testnet. We want to check the networkId to ensure, that we are connected correctly. 194 | 195 | 196 | 197 | 198 | ```typescript 199 | // Subscribe to network changed event 200 | const networkSubscriber = await ever.subscribe('networkChanged'); 201 | networkSubscriber.on('data', (event) => { 202 | // track changes in the network id 203 | if (event.networkId === 2) { 204 | // We are on the testnet now 205 | } else { 206 | // Still not on the testnet 207 | } 208 | }); 209 | // You can use await networkSubscriber.unsubscribe(); to cancel the subscription 210 | const currentProviderState = await ever.getProviderState(); 211 | if (currentProviderState.networkId !== 2) { 212 | // Ask user to change the network 213 | } else { 214 | // Everything is okay 215 | } 216 | ``` 217 | 218 | 219 | -------------------------------------------------------------------------------- /src/develop/recipes/ever-sdk-guides/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 1, 3 | "label": "EVER SDK Guides", 4 | "link": { 5 | "title": "EVER SDK Guides", 6 | "slug": "develop/tutorial/ever-sdk-guides", 7 | "type": "generated-index" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/develop/recipes/ever-sdk-guides/other-sdk-guides.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | description: Explore guides for EVER SDK 4 | --- 5 | 6 | # Other EVER SDK Guides 7 | 8 | This is a list of detailed guides for EVER SDK 9 | 10 | * EVER SDK Installation 11 | * [Add SDK to your App](https://docs.everos.dev/ever-sdk/guides/installation/add_sdk_to_your_app) 12 | * EVER SDK Configuration 13 | * [Endpoint Configuration](https://docs.everos.dev/ever-sdk/guides/configuration/endpoint-configuration) 14 | * [Message Expiration](https://docs.everos.dev/ever-sdk/guides/configuration/message_expiration) 15 | * [Message Retry](https://docs.everos.dev/ever-sdk/guides/configuration/retry_message) 16 | * [Config Reference](https://docs.everos.dev/ever-sdk/guides/configuration/configure_sdk) 17 | * Work with contracts in EVER SDK 18 | * [Add Contract to your App](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/add_contract_to_your_app) 19 | * [Use your own Giver](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/custom_giver) 20 | * [Deploy Contract](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/deploy) 21 | * [Run Contract on-chain](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/run_onchain) 22 | * [Run ABI Get Method](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/run_abi_get_method) 23 | * [Run Fift Get Method](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/run_fift_get_method) 24 | * [Query/Subscribe for messages(events)](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/work_with_events) 25 | * [Decode Messages(Event)](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/decode_message) 26 | * [External Signing](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/external_signing) 27 | * [Emulate Transaction](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/emulate_transaction) 28 | * [Estimate Fees](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/estimate_fees) 29 | * [Validate address, convert address](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/validate_address_convert_address) 30 | * [Monitor messages](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/monitor-messages) 31 | * [Trace message processing with REMP](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/trace-message-processing-with-remp) 32 | * Crypto fucntions in EVER SDK 33 | * [Mnemonics and Keys](https://docs.everos.dev/ever-sdk/guides/crypto/mnemonics_and_keys) 34 | * Queries and subscriptions in EVER SDK 35 | * [Use-cases](https://docs.everos.dev/ever-sdk/guides/queries_and_subscriptions/use-cases) 36 | * [How to work with net module](https://docs.everos.dev/ever-sdk/guides/queries_and_subscriptions/how-to-work-with-net-module) 37 | * [net.query syntax](https://docs.everos.dev/ever-sdk/guides/queries_and_subscriptions/raw_query) 38 | * [Data pagination](https://docs.everos.dev/ever-sdk/guides/queries_and_subscriptions/data-pagination) 39 | * [Subscribe to Updates](https://docs.everos.dev/ever-sdk/guides/queries_and_subscriptions/subscribe_to_updates) 40 | * [Query Collection](https://docs.everos.dev/ever-sdk/guides/queries_and_subscriptions/query_collection) 41 | * [Aggregate Collection](https://docs.everos.dev/ever-sdk/guides/queries_and_subscriptions/aggregate_collection) -------------------------------------------------------------------------------- /src/develop/recipes/img/ew01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/src/develop/recipes/img/ew01.png -------------------------------------------------------------------------------- /src/develop/recipes/img/ew02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/src/develop/recipes/img/ew02.png -------------------------------------------------------------------------------- /src/develop/recipes/img/ew03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/src/develop/recipes/img/ew03.png -------------------------------------------------------------------------------- /src/develop/recipes/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 0 3 | --- 4 | 5 | # Intro 6 | 7 | In this series of examples we will figure out basic steps you need to follow to build a UI around any smart contract and perform various routines common for both frontend and backend parts of any application. We expect a reader to have basic experience with JS. 8 | 9 | For React developers, there is an [example](https://github.com/mnill/everscale-crash-course-token-dice-frontend) of a React App built around Everscale smart-contracts. 10 | 11 | Before we start, please make sure you've read through basic theory that we put under the [Build](/develop) section of this documentation, especially the [Smart Contracts, ABI and Messages](/develop/sc-abi-messages.md) article. 12 | 13 | Also, be aware that we borrow some code samples from the full [Everscale Development Guide](https://everscale.guide/), so don’t hesitate to check that out if you want to dive deeper into the context. -------------------------------------------------------------------------------- /src/develop/recipes/write-data.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 7 3 | --- 4 | 5 | import Tabs from '@theme/Tabs'; 6 | import TabItem from '@theme/TabItem'; 7 | 8 | # Write data to blockchain 9 | 10 | To put something in the Everscale blockchain, you need to send an external message to some account. Depending on a use-case and smart-contract logic, you may also want the account (usually it will be a users' Wallet smart-contract) to act as a proxy and forward your message to other contract. In this article, we describe both cases 11 | 12 | ## Send External Message 13 | 14 | 15 | 16 | 17 | 18 | ```typescript 19 | // Encode the message with `touch` function call 20 | const params = { 21 | send_events: false, 22 | message_encode_params: { 23 | address, 24 | abi, 25 | call_set: { 26 | function_name: 'touch', 27 | input: {} 28 | }, 29 | // There is no pubkey key check in the contract 30 | // so we can leave it empty. Never use this approach in production 31 | // because anyone can call this function 32 | signer: { type: 'None' } 33 | } 34 | } 35 | // Call `touch` function 36 | let response = await client.processing.process_message(params); 37 | console.log(`Сontract run transaction with output ${response.decoded.output}, ${response.transaction.id}`); 38 | ``` 39 | 40 | 41 | 42 | 43 | ```typescript 44 | // Encode the message with `touch` function call 45 | const params = { 46 | abi = { 47 | type: 'Contract', 48 | value: contract.abi 49 | }, 50 | address, 51 | call_set: { 52 | function_name: 'touch', 53 | input: {} 54 | }, 55 | // There is no pubkey key check in the contract 56 | // so we can leave it empty. Never use this approach in production 57 | // because anyone can call this function 58 | signer: { type: 'None' } 59 | } 60 | 61 | // Create external inbound message with `touch` function call 62 | const encode_touch_result = await client.abi.encode_message(params); 63 | 64 | // Send `touch` call message to the network 65 | // See more info about `send_message` here 66 | // https://github.com/tonlabs/ever-sdk/blob/master/docs/mod_processing.md#send_message 67 | shard_block_id = (await client.processing.send_message({ 68 | message: encode_touch_result.message, 69 | send_events: true 70 | },logEvents 71 | )).shard_block_id; 72 | console.log(`Touch message was sent.`); 73 | ``` 74 | 75 | 76 | 77 | 78 | ```typescript 79 | // Create Contract wrapper using ABI and an address 80 | const example = new provider.Contract(contractABI, contractAddress); 81 | // Send the external message `touch` to the contract 82 | await example.methods.touch({}).sendExternal({ 83 | publicKey: `0x...` // you can get the pubkey from keystore, which is set up either manually or provided by the browser extension 84 | }); 85 | console.log('Message sent'); 86 | ``` 87 | 88 | 89 | 90 | 91 | ## Encode and send Internal Message 92 | 93 | 94 | 95 | 96 | ```typescript 97 | // Create Contract wrapper using ABI and an address 98 | const example = new provider.Contract(contractABI, contractAddress); 99 | // Send the external message `touch` to the contract 100 | await example.methods.touch({}).send({ 101 | address:
, // you can get the address from AccountStorage, which is set up either manually or provided by the browser extension 102 | amount: // you should attach non-zero value of native currency to pay at least foraward, compute and storage fees of destination contract. 103 | }); 104 | console.log('Message sent'); 105 | ``` 106 | 107 | 108 | 109 | 110 | ## Links 111 | 112 | Explore the full guides to writing data to blockchain in Ever SDK here: 113 | 114 | https://docs.everos.dev/ever-sdk/guides/work_with_contracts/deploy 115 | 116 | https://docs.everos.dev/ever-sdk/guides/work_with_contracts/run_onchain 117 | 118 | Advanced guide for working with Surf keeper provider is [here](surf-wallet-advanced.md). 119 | 120 | 121 | If you use `everscale-inpage-provider`, see more docs and guides here: 122 | 123 | https://docs.broxus.com -------------------------------------------------------------------------------- /src/develop/sc-abi-messages.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Smart Contracts, ABI and Messages 6 | 7 | Frontend developers used to build a UI around some machinery called “backend”, that can be accessed via an API. The common practice in software development is to have some schema definitions, usually built with tool called swagger. 8 | 9 | In blockchain development, the “backend” thing is called a smart contract. It is usually being built with Solidity language, and also has schema definition called an Abstract Binary Interface, or ABI. In most cases, a frontend developer doesn’t need to bother his mind with understanding the smart-contract code. But it is crucial to understand the ABI to interact with a smart contract. 10 | 11 | Let’s see how an ABI looks like, and what can we underfstand from it without reading the smart contract itself. 12 | 13 |
14 | ABI 15 | 16 | ```json5 17 | { 18 | // Major version of ABI standart 19 | "ABI version": 2, 20 | // Full version of ABI 21 | // Can be – 2.0, 2.1, 2.2, 2.3 22 | version: "2.3", 23 | // Headers, specifying SDK which additional fields to attach to external message 24 | // Defined in the contract code, there are: 25 | // pragma AbiHeader time; 26 | // pragma AbiHeader pubkey; 27 | // pragma AbiHeader expire; 28 | header: [ 29 | "time", "pubkey", "expire" 30 | ], 31 | // Description of callable function signatures 32 | // both internal and external messages 33 | functions: [ 34 | { 35 | "name": "constructor", 36 | "inputs": [], 37 | "outputs": [] 38 | }, 39 | { 40 | "name": "get", 41 | "inputs": [], 42 | "outputs": [{"name":"value0","type":"uint256"}] 43 | }, 44 | { 45 | "name": "getInternal", 46 | "inputs": [ 47 | {"name":"answerId","type":"uint32"} 48 | ], 49 | "outputs": [ 50 | {"name":"value0","type":"uint256"} 51 | ] 52 | }, 53 | { 54 | "name": "set", 55 | "inputs": [{"name":"_value","type":"uint256"}], 56 | "outputs": [] 57 | } 58 | ], 59 | // A description of the events that a contract can create 60 | events: [ 61 | { 62 | "name": "VariableChanged", 63 | "inputs": [{"name":"new_value","type":"uint256"}], 64 | "outputs": [] 65 | } 66 | ], 67 | // A list of static variables that must be specified to deploy the contract 68 | data: [ 69 | {"key":1,"name":"owner","type":"address"} 70 | // There are also three hidden variables that SDK will set by itself 71 | // _pubkey, _timestamp, _constructorFlag 72 | ], 73 | // a list of all variables, so that you can 74 | // download the contract state and decode it 75 | fields: [ 76 | {"name":"_pubkey","type":"uint256"}, // tvm.pubkey() 77 | {"name":"_timestamp","type":"uint64"}, // set by SDK 78 | {"name":"_constructorFlag","type":"bool"}, // set by SDK 79 | {"name":"owner","type":"address"}, 80 | {"name":"variable","type":"uint256"} 81 | ] 82 | } 83 | ``` 84 | 85 |
86 | 87 | An ABI describes how we pack the data into a TOC (Tree Of Cells) - the fundamental internal data structure of Everscale blockchain. We need that to encode the message according to Everscale standard and send it to the blockchain. 88 | 89 | Any message have a body for the function call. Let's look at an example function from abi: 90 | 91 | ```json 92 | { 93 | "name": "set", 94 | "inputs": [{"name":"_value","type":"uint256"}], 95 | "outputs": [] 96 | } 97 | ``` 98 | 99 | In the Recipes section, we provide snippets for `ever-sdk-js`, `surf-keeper-provider` and `everscale-inpage-provider` libraries, where we use ABI to interact with smart-contracts. It’s important to understand what happens under the hood, so lets summarize: we want to encode the payload, construct the message to some contract and send it over the RPC to a blockhain. 100 | 101 | Usually you will connect your dApp to existing smart contract system, deployed on-chain by a smart-contract developer. We assume that you have an ABI an address of one or several contracts. 102 | 103 | In further examples we will learn how to perform common routines. 104 | -------------------------------------------------------------------------------- /src/develop/smart-contracts/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 5, 3 | "label": "Smart Contracts", 4 | "link": { 5 | "title": "Smart Contracts", 6 | "slug": "develop/smart-contracts", 7 | "type": "generated-index" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/develop/smart-contracts/locklift-setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Locklift Environment setup 6 | 7 | 8 | ## Locklift 9 | 10 | To improve the development experience, you will need tools and utilities to compile, deploy and test your Everscale contracts. 11 | 12 | Let's consider Locklift as an example tool. It is a development environment like Hardhat or Truffle and it uses the specified TON Solidity Compiler to build all project contracts. 13 | 14 | With Locklift, you get: 15 | - Network management for working with any networks (main, test, local, ...) 16 | - Automated contract testing 17 | - Handy wrappers around Everscale smart contracts 18 | - Custom givers support 19 | - Keys management 20 | - External script runner that executes scripts within a specified environment 21 | 22 | To install Locklift, run the following command line: 23 | 24 | ```shell 25 | npm install -g locklift 26 | ``` 27 | 28 | ## Local node 29 | 30 | :::info 31 | You need to have a [docker](https://www.docker.com/) runtime to continue with this. 32 | ::: 33 | 34 | If Locklift is like a Hardhat development environment tool, then local-node is Ganache- like a local blockchain that is designed for dApp debugging and testing. To run local- node you need to follow this command: 35 | 36 | ```shell 37 | docker run -d --name local-node -e USER_AGREEMENT=yes -p80:80 tonlabs/local-node 38 | ``` 39 | 40 | The container exposes the specified 80 port with Nginx which proxies requests to /graphql to GraphQL API. Check out the local explorer at http://localhost/ and GraphQL playground at http://localhost/graphql 41 | 42 | 43 | Once we are all set, the next thing to do is to initialize your first project. 44 | 45 | ## Initialize new project 46 | 47 | Run the following command line: 48 | 49 | ```shell 50 | locklift init --path sample-project 51 | ``` 52 | 53 | This command initializes a new Locklift project, filled with samples: 54 | 55 | ``` 56 | ├── locklift.config.ts 57 | ├── tsconfig.json 58 | ├── package.json 59 | ├── package-lock.json 60 | │ 61 | ├── contracts 62 | │ └── Sample.tsol 63 | ├── scripts 64 | │ └── 1-deploy-sample.ts 65 | ├── test 66 | │ └── sample-test.ts 67 | ``` 68 | 69 | You can see that your smart contract `Sample.tsol` appeared in the `sample-project/contracts` directory. 70 | 71 | ## Configuration 72 | 73 | The configuration file is called `locklift.config.ts`. Here's how the basic layout for local node looks like (note, that your config may contain more networks, but the way they are configured is the same): 74 | 75 |
76 | Default locklift.config.ts layout 77 | 78 | ```typescript 79 | import { LockliftConfig } from "locklift"; 80 | import { FactorySource } from "./build/factorySource"; 81 | declare global { 82 | const locklift: import("locklift").Locklift; 83 | } 84 | 85 | const LOCAL_NETWORK_ENDPOINT = process.env.NETWORK_ENDPOINT || "http://localhost/graphql"; 86 | const DEV_NET_NETWORK_ENDPOINT = process.env.DEV_NET_NETWORK_ENDPOINT || "https://devnet-sandbox.evercloud.dev/graphql"; 87 | const VENOM_TESTNET_ENDPOINT = process.env.VENOM_TESTNET_ENDPOINT || "https://jrpc-testnet.venom.foundation/rpc"; 88 | const VENOM_TESTNET_TRACE_ENDPOINT = process.env.VENOM_TESTNET_TRACE_ENDPOINT || "https://gql-testnet.venom.foundation/graphql"; 89 | // Create your own link on https://dashboard.evercloud.dev/ 90 | const MAIN_NET_NETWORK_ENDPOINT = process.env.MAIN_NET_NETWORK_ENDPOINT || "https://mainnet.evercloud.dev/XXX/graphql"; 91 | const config: LockliftConfig = { 92 | compiler: { 93 | // Specify path to your TON-Solidity-Compiler 94 | // path: "/mnt/o/projects/broxus/TON-Solidity-Compiler/build/solc/solc", 95 | // Or specify version of compiler 96 | version: "0.62.0", 97 | // Specify config for extarnal contracts as in exapmple 98 | // externalContracts: { 99 | // "node_modules/broxus-ton-tokens-contracts/build": ['TokenRoot', 'TokenWallet'] 100 | // } 101 | }, 102 | linker: { 103 | // Specify path to your stdlib 104 | // lib: "/mnt/o/projects/broxus/TON-Solidity-Compiler/lib/stdlib_sol.tvm", 105 | // // Specify path to your Linker 106 | // path: "/mnt/o/projects/broxus/TVM-linker/target/release/tvm_linker", 107 | // Or specify version of linker 108 | version: "0.15.48", 109 | }, 110 | networks: { 111 | local: { 112 | // Specify connection settings for https://github.com/broxus/everscale-standalone-client/ 113 | connection: { 114 | id: 1, 115 | group: "localnet", 116 | type: "graphql", 117 | data: { 118 | endpoints: [LOCAL_NETWORK_ENDPOINT], 119 | latencyDetectionInterval: 1000, 120 | local: true, 121 | }, 122 | }, 123 | // This giver is default local-node giverV2 124 | giver: { 125 | // Check if you need provide custom giver 126 | address: "0:ece57bcc6c530283becbbd8a3b24d3c5987cdddc3c8b7b33be6e4a6312490415", 127 | key: "172af540e43a524763dd53b26a066d472a97c4de37d5498170564510608250c3", 128 | }, 129 | tracing: { 130 | endpoint: LOCAL_NETWORK_ENDPOINT, 131 | }, 132 | keys: { 133 | // Use everdev to generate your phrase 134 | // !!! Never commit it in your repos !!! 135 | // phrase: "action inject penalty envelope rabbit element slim tornado dinner pizza off blood", 136 | amount: 20, 137 | }, 138 | }, 139 | 140 | // ... (configs for other networks go here) 141 | ``` 142 | 143 |
144 | 145 | For the avoidance of doubt, it’s important that we go through each of the parameters: 146 | 147 | `compiler.version` - the version of the solidity compiler binary 148 | 149 | `linker.version` - the version of the TVM-linker binary 150 | 151 | `networks` - specify which networks are available for deployment and testing. 152 | 153 | `networks.[NETWORK_NAME].keys.phrase` - if you leave this field value empty - a new random seed will be generated each time you're running locklift. 154 | 155 | Or specify it explicitly - fill the `phrase` field with a mnemonic phrase. 156 | 157 | ## Build 158 | 159 | You can run tests and start to develop your amazing projects. To do this, you need to run the following command. The command uses the specified TON Solidity compiler and TVM linker to build all project contracts: 160 | 161 | ```shell 162 | npx locklift build 163 | ``` 164 | 165 | Now, let’s proceed with testing the sample contract. 166 | 167 | ## Run Tests 168 | 169 | This command runs the project Mocha tests, `test` folder by default. The `locklift` object will be set up and included automatically, you don't need to import it manually. 170 | 171 | ```shell 172 | npx locklift test -n local 173 | ``` 174 | 175 | ## Invoke Scripts 176 | 177 | There is a common practice to keep various scripts within the same environment where the samrt contracts and tests live. Such scripts may perform deployment, configuration, data collection or and smart-contract upgrade routines. 178 | 179 | Let's run the sample deployment script within locklift environment (make sure your local node container is up and running) 180 | 181 | ```shell 182 | npx locklift run -s scripts/1-deploy-sample.ts -n local 183 | ``` 184 | 185 | If you succeeded with all steps above, you should see the address, where the `Sample.tsol` is deployed. 186 | -------------------------------------------------------------------------------- /src/develop/smart-contracts/use-fungible-tokens.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Deploy TIP-3 Token 6 | 7 | One of the most popular use cases for Everscale is the creation of custom tokens using the TIP-3 standard. TIP-3 tokens are fungible tokens that follow a set of rules and standards, making them compatible with a variety of wallets, exchanges, and other Everscale-based services. 8 | 9 | TIP-3 provides the following functionalities: 10 | - transfer tokens from one account to another 11 | - get the current token balance of an account 12 | - get the total supply of the token available on the network 13 | - mint and burn tokens 14 | 15 | The TIP-3 standard is made up of a set of interfaces, contracts, and utilities that work together to facilitate the creation and management of tokens. They include: 16 | 17 | - `TIP3TokenRoot`: is an interface that defines the minimal required functionality for a TIP-3 compliant token root contract. It includes functions for querying the name, symbol, number of decimals, total supply, and wallet code of the token. These functions are used for display purposes and do not affect the contract's arithmetic. 18 | 19 | - `ITokenRoot`: the interface for the token root contract that stores general information about the token, such as the name, symbol, decimals, and total supply. 20 | 21 | - `TokenRootBase`: is an implementation of the TIP-3 Token Standard for the Everscale blockchain. It provides the minimal required functionality for a token root contract, including storing general information about the token such as name, symbol, decimals, and total supply. 22 | 23 | To get started with developing your token, you can inspect the Everscale source code for [TIP-3 token implementation here](https://github.com/broxus/tip3). Then you need to install and set up your [smart contract development environment](#todo-add). 24 | 25 | Next, you follow the steps below: 26 | 27 | ## Install Dependencies 28 | 29 | To install dependencies, add TIP-3 implementation repository as a `devDependencies` in the corresponding section of the `package.json` file. 30 | 31 | ```json 32 | { 33 | "devDependencies": { 34 | "tip3": "git://github.com/broxus/tip3#v5" 35 | } 36 | } 37 | ``` 38 | 39 | Then run following command to install dependency: 40 | 41 | ```shell 42 | npm i 43 | ``` 44 | 45 | Specify installed contracts to the `externalContracts` section of `locklift.config.ts`, by providing a path to contracts artifacts (`.abi.json` files, `.tvc` files, etc., most commonly placed in a `build` folder of smart contracts projects) and contract names array. 46 | 47 | ```typescript 48 | const config: LockliftConfig = { 49 | compiler: { 50 | // ... 51 | externalContracts: { 52 | "node_modules/tip3/build": ["TokenRoot", "TokenWallet"], 53 | }, 54 | }, 55 | // ... 56 | } 57 | ``` 58 | 59 | ## Compile Contract 60 | 61 | Next, the contracts need to be compiled to ensure that artifacts are created. To do this, run the following: 62 | 63 | ```shell 64 | npx locklift build 65 | ``` 66 | 67 | ## Deploy 68 | 69 | After compiling the contract, we move to deploy. Firstly, we make a new deploy script in the `scripts` directory for the `TokenRoot` contract: 70 | 71 |
72 | scripts/01-deploy-token-root.ts 73 | 74 | ```typescript 75 | import { Address, getRandomNonce, toNano, zeroAddress } from "locklift" 76 | import BigNumber from "bignumber.js" 77 | async function main() { 78 | const signer = (await locklift.keystore.getSigner("0"))! 79 | // Address of initial token supply recipient (write your own) 80 | const initialSupplyTo = new Address("0:7542...") 81 | // Address of token owner (write your own) 82 | const rootOwner = new Address("0:7542...") 83 | // Name of the token 84 | const name = "First Everscale Token" 85 | // Symbol of the token 86 | const symbol = "FET" 87 | // How many token will be issued instantly after deploy 88 | const initialSupply = 0 89 | // The number of decimals the token uses 90 | const decimals = 18 91 | // If true, disables token minting 92 | const disableMint = false 93 | // If true, disables token burning by root 94 | const disableBurnByRoot = false 95 | // If true, pauses token burning 96 | const pauseBurn = false 97 | 98 | /* 99 | Returns compilation artifacts based on the .sol file name 100 | or name from value config.externalContracts[pathToLib]. 101 | */ 102 | const TokenWallet = locklift.factory.getContractArtifacts("TokenWallet") 103 | 104 | /* 105 | Deploy the TIP-3 Token Root contract. 106 | @params deployWalletValue: Along with the deployment of the root token, 107 | the wallet will be automatically deployed to the owner. 108 | This is the amount of EVERs that will be sent to the wallet. 109 | */ 110 | const { contract: tokenRoot } = await locklift.factory.deployContract({ 111 | contract: "TokenRoot", 112 | publicKey: signer.publicKey, 113 | initParams: { 114 | // this field should be zero address if deploying with public key (see source code) 115 | deployer_: zeroAddress, 116 | randomNonce_: getRandomNonce(), 117 | rootOwner_: rootOwner, 118 | name_: name, 119 | symbol_: symbol, 120 | decimals_: decimals, 121 | walletCode_: TokenWallet.code, 122 | }, 123 | constructorParams: { 124 | initialSupplyTo: initialSupplyTo, 125 | initialSupply: new BigNumber(initialSupply).shiftedBy(decimals).toFixed(), 126 | deployWalletValue: toNano(1), 127 | mintDisabled: disableMint, 128 | burnByRootDisabled: disableBurnByRoot, 129 | burnPaused: pauseBurn, 130 | remainingGasTo: zeroAddress, 131 | }, 132 | value: toNano(5), 133 | }); 134 | console.log(${name}: ${tokenRoot.address}) 135 | } 136 | 137 | main() 138 | .then(() => process.exit(0)) 139 | .catch(e => { 140 | console.log(e) 141 | process.exit(1) 142 | }); 143 | ``` 144 |
145 | 146 | Finally, we can deploy a new token to local network. For this, make sure the local node is running, if not - run the following command: 147 | 148 | ```shell 149 | docker run -d --name local-node -e USER_AGREEMENT=yes -p80:80 tonlabs/local-node 150 | ``` 151 | 152 | Then run the deploy script: 153 | 154 | ```shell 155 | npx locklift run -s ./scripts/01-deploy-token.ts -n local 156 | ``` 157 | 158 | If you succeeded with all steps above, you should see the address, where the `TokenRoot` contract is deployed. 159 | -------------------------------------------------------------------------------- /src/develop/tools-overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Developer Tools Overview 6 | 7 | ### Wallets 8 | - [Ever Surf](https://ever.surf/) 9 | - [Ever Wallet](https://everwallet.net) 10 | 11 | ### API 12 | - [Evercloud](https://evercloud.dev) ([docs](https://docs.evercloud.dev)) - Evercloud provides TVM networks developers with scalable GraphQL endpoints. Supports Everscale mainnet, devnet, fld-testnet, TON mainnet, Venom testnet. 13 | 14 | ### Blockchain Explorers 15 | - [Ever Live](https://ever.live) ([devnet](https://net.ever.live) [fld](https://fld.ever.live) [rfld](https://rfld.ever.live)) 16 | - [Everscan](https://everscan.io) ([devnet](https://testnet.everscan.io)) 17 | 18 | ### Tools for developers 19 | - [TON Solidity Compiler](https://github.com/tonlabs/TON-Solidity-Compiler) ([reference](https://github.com/tonlabs/TON-Solidity-Compiler/blob/master/API.md)) - Port of the Solidity smart-contract compiler generating TVM bytecode for TON blockchain. Can be installed within Everdev or Locklift environments as well, or compiled manually. 20 | 21 | - [Everdev CLI](https://github.com/tonlabs/everdev) ([Quick start](smart-contracts/everdev.md) | [docs](https://docs.everos.dev/everdev)) - Everdev is a Node.js package with CLI interface that allows to set up developer environment and develop on TVM compatible blockchains (Everscale, Venom, TON, Gosh, etc). 22 | 23 | - [Locklift](https://github.com/broxus/locklift) - development environment, analogous to Hardhat. 24 | 25 | - [Bytie](https://ever.bytie.moe) - smart contracts interaction playground and useful devtools 26 | 27 | ### TON Solidity Compiler IDE integrations 28 | 29 | - [VSCode TON Solidity Compiler plugin 1](https://marketplace.visualstudio.com/items?itemName=everscale.solidity-support) 30 | - [VSCode TON Solidity Compiler plugin 2](https://marketplace.visualstudio.com/items?itemName=mytonwallet.ton-solidity-extension) 31 | - [JetBrains TON Solidity Compiler plugin](https://plugins.jetbrains.com/plugin/20696-t-sol) 32 | 33 | ### Libraries for developers 34 | - [JavaScript Ever SDK](https://github.com/tonlabs/ever-sdk-js) ([docs](https://docs.everos.dev/ever-sdk)) - Client Library built for Everscale, Venom blockchain, TON, Gosh for Web, Node.js and React Native platforms 35 | - [Rust Ever SDK](https://github.com/tonlabs/ever-sdk) - Rust Client Library (core) for DApp development in TVM blockchains (Everscale, TON, Venom Blockchain, etc). Bindings to multiple languages available. 36 | - [Surf Keeper JS Provider](https://github.com/EverSurf/surfkeeper-provider) 37 | - [EVER Wallet JS Provider](https://github.com/broxus/everscale-inpage-provider/) 38 | - [Alternative NodeJS Client](https://github.com/broxus/everscale-standalone-client) 39 | 40 | 41 | ### Node-related repos 42 | - [Evernode dApp Server](https://github.com/tonlabs/evernode-ds) - a community (open source) version of Evernode Platform (client supernode with GraphQL API) for TVM blockchains that exposes GraphQL API. 43 | - [Local Node](https://github.com/tonlabs/evernode-se) - local blockchain for contract and Dapp testing, exposing GraphQL API. Can be installed and managed within Everdev environment 44 | - [Light Node](https://github.com/broxus/ton-indexer) - Lightweight node implementation 45 | - [Everscale Node](https://github.com/tonlabs/ever-node) - Validator and Full Node implementation 46 | - [Nodekeeper](https://github.com/broxus/nodekeeper) - All-in-one node management tool 47 | - [everscale-network](https://github.com/broxus/everscale-network) - minimal implementation of the Everscale network protocol 48 | -------------------------------------------------------------------------------- /src/develop/tvmcell-data-structure.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # TVMCell Data structures 6 | 7 | Everything in Everscale is stored in cells. A cell is a data structure containing: 8 | 9 | - up to **1023 bits** of data (not bytes!) 10 | - up to **4 references** to other cells 11 | 12 | Bits and references are not intermixed (they are stored separately). Circular references are forbidden: for any cell, none of its descendant cells can have this original cell as reference. 13 | 14 | Thus, all cells constitute a directed acyclic graph (DAG). 15 | 16 | A cell is an opaque object optimized for compact storage. 17 | 18 | In particular, it deduplicates data: if there are several eqivalent sub-cells referenced in different branches, their content is only stored once. However, opaqueness means that a cell cannot be modified or read directly. 19 | 20 | Thus, there are 2 additional flavors of the cells: 21 | 22 | - *Builder* for partially constructed cells, for which fast operations for appending bitstrings, integers, other cells and references to other cells can be defined. 23 | - *Slice* for 'dissected' cells representing either the remainder of a partially parsed cell or a value (subcell) residing inside such a cell and extracted from it via a parsing instruction. 24 | - *Continuation* for cells containing op-codes (instructions) for internal use in TVM 25 | 26 | Any object in Everscale (message, message queue, block, whole blockchain state, contract code and data) serializes to a cell. 27 | 28 | The process of serialization is described by a TL-B scheme: a formal description of how this object can be serialized into *Builder* or how to parse an object of a given type from the *Slice*. 29 | 30 | TL-B for cells is the same as TL or ProtoBuf for byte-streams. -------------------------------------------------------------------------------- /src/img/multi-round-elections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/src/img/multi-round-elections.png -------------------------------------------------------------------------------- /src/img/what_concepts_were_used_before_operating_systems.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/src/img/what_concepts_were_used_before_operating_systems.jpg -------------------------------------------------------------------------------- /src/overview/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 1, 3 | "label": "Overview", 4 | "link": { 5 | "title": "Overview", 6 | "slug": "overview", 7 | "type": "generated-index" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/overview/concepts.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Glossary 6 | 7 | ### **Accounts** 8 | 9 | This is the place for storing EVERs . Besides storage, users with an account are able to deposit and transfer Ever. The account record stores account address and account balance. Accounts are ultimately stored in TVM. For more information about Accounts please consult [this page](../arch/40-accounts.md). 10 | 11 | ### **Blockchain** 12 | 13 | The chain of all blocks that have been added to the Everscale network throughout the history of the network. Each block has a reference to the previous block. Thus, it permits us to maintain a sequence of all blocks in the chain. 14 | 15 | ### **Blocks** 16 | 17 | There is a very high number of transactions on the Everscale network. Due to this, transactions are grouped in blocks. Each block counts hundreds of transactions. 18 | 19 | ### **Ever** 20 | 21 | Ever is the native cryptocurrency of Everscale. Besides being an investment opportunity for users, it has multiple uses inside as well as outside the Everscale network. 22 | 23 | ### **Everscale** 24 | 25 | Decentralised blockchain network that comprises many leading applications and services. Everscale has powerful developer tools, such as compilers for Solidity and C++, API, an SDK that includes client libraries for 13 programming languages and other convenient instruments designed for developers to build outstanding blockchain applications. 26 | 27 | ### **Messages** 28 | 29 | All interactions in Everscale are performed via messages. 30 | 31 | External inbound messages help deploy and call contracts from outside. Internal messages allow contracts to communicate with each other. 32 | 33 | External outbound messages are the events the contracts produce for the outside world. Use them to implement some off-chain logic - subscribe for these messages and perform some off-chain actions whenever you receive them. 34 | 35 | For example, simple value transfer can be initiated with an external inbound message (by a human or some service) or with internal message from another contract. This message will produce a transaction (read below) and an internal message with value transfer. 36 | 37 | For detailed information about Messages please consult [this page](../arch/45-message.md) 38 | 39 | ### **Nodes** 40 | 41 | Nodes are ordinary computers on which the Everscale program is running. Each node is connected to other nodes, which allows to come to a consensus, which is a special mechanism by which information about the correctness of transactions on the network is checked. The Everscale network is the aggregate of all Everscale nodes and their communications. 42 | 43 | ### **Shards** 44 | 45 | Shards in Everscale are used for solving the classical issue faced by blockchains, which is low throughput. Sharding is merely partitioning of data in a database, in our case in the Everscale blockchain. 46 | 47 | Due to sharding, Everscale achieved one of the highest transactions per second rate available out there. For detailed information about how sharding works please consult [this page](differences-from-evm.md). 48 | 49 | ### **Smart contracts** 50 | 51 | SMs are a kind of algorithm, or program that runs on Everscale or other blockchains, like Ethereum, which was the first to come up with the idea of smart contracts. They work in accordance with a prescribed set of rules that are programmed by developers. When all conditions prescribed in the contract are met, the contract is executed. 52 | 53 | For more information about smart contracts please consult [this page](../develop/smart-contracts/) 54 | 55 | ### **TVM** 56 | 57 | TVM is the virtual machine used to execute smart-contract code in the masterchain and in the basic workchain. 58 | 59 | Any user can request the execution of arbitrary code on the TVM. 60 | 61 | For more information about TVM please consult [this page](../arch/10-tvm.md) 62 | 63 | ### **Transactions** 64 | 65 | A transaction is the result of a contract execution. In general, a transaction is generated with one incoming message (external or internal) and can generate several outcoming messages (external or internal) as a result. Any user can broadcast a transaction request to the Everscale network from a node. 66 | 67 | ### **Transaction Executorexecu** 68 | 69 | Takes results of TVM, calculates fees, checks balance and other things. Used by validators to validate blocks. Can also be used on the client side to debug contract execution. 70 | 71 | For detailed information about Transaction executor please consult [this page](../arch/35-executor.md) 72 | -------------------------------------------------------------------------------- /src/overview/img/CDBC.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/src/overview/img/CDBC.jpg -------------------------------------------------------------------------------- /src/overview/img/Enterprise.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/src/overview/img/Enterprise.jpg -------------------------------------------------------------------------------- /src/overview/img/Everscale_s-parallel-smart-contracts-execution_1-50.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/src/overview/img/Everscale_s-parallel-smart-contracts-execution_1-50.gif -------------------------------------------------------------------------------- /src/overview/img/Two_spheres2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/src/overview/img/Two_spheres2.jpg -------------------------------------------------------------------------------- /src/overview/img/everscale-banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/src/overview/img/everscale-banner.jpg -------------------------------------------------------------------------------- /src/overview/img/evervseth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/src/overview/img/evervseth.jpg -------------------------------------------------------------------------------- /src/overview/img/network-architecture.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/everscale-org/docs/a60b85bdeabe24202fd8b0c482252c7d098abdc3/src/overview/img/network-architecture.gif -------------------------------------------------------------------------------- /src/overview/infinite-scalability.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Infinite scalability 6 | 7 | ![](img/Two_spheres2.jpg) 8 | 9 | Everscale’s infinite scalability has been envisioned in its architecture since its inception. It is achieved by means of dynamic sharding, described in detail in the [technical whitepaper](https://everscale.network/files/Everscale_Whitepaper.pdf). The reason for scalability was primarily dictated by the blockchain's goal to accommodate a billion or even more users. Consequently, such a large customer base requires a high volume of transaction processing per second. 10 | 11 | This approach comes in contrast to the one Ethereum took, resorting to scalability just recently. The decision to scale was triggered by capacity limitations and high transaction costs. However, despite strong efforts, Ethereum is not yet successful. There are many solutions being researched and tested, such as rollups and different sharding approaches. The results remain to be seen in practice. 12 | 13 | ## The Approach to Infinite Scalability 14 | 15 | :::info 16 | 17 | Everscale scales the network via a combination of both data sharding (workchains) and execution sharding (threads). 18 | 19 | ::: 20 | 21 | The Everscale network is split into data shards called workchains. Each election cycle, the global set of validators rotate and are assigned to a workchain. Validators store data and process transactions only for their assigned workchain. As long as validators download blocks of other workchains and update their state based on the changes that occurred, all workchains can run in conjunction. 22 | 23 | As of now, Everscale is comprised of two global shards: the **masterchain** and the **main workchain**. Everscale’s architecture can potentially accommodate up to 2^32 workchains. Each newly created workchain can have its own configuration parameters, virtual machine, and native currency, 24 | 25 | ![](img/network-architecture.gif) 26 | 27 | The **masterchain** is for the synchronization of messages and transaction execution. That is to say, for a multi-chain network to securely operate, the nodes need to reach a consensus. On Everscale, all workchain **block proofs** are posted to the masterchain. The blocks of the masterchain contain the latest block hashes of all other chains in the network. The **main workchain**, on the other hand, consists of smart contracts and is used for transactions. Each workchain, on its part, is split into execution shards called **threads**. Threads contain a chunk of the network’s total number of smart contracts. Validators rotate through the assigned threads and process the transactions only in their thread. The number of threads varies from 1 to 256, depending on the network activity. Such a multithreading approach allows for parallel execution of smart contracts by subgroups of validators that share the same data. 28 | 29 | ![](img/Everscale_s-parallel-smart-contracts-execution_1-50.gif) 30 | 31 | The need to resort to such a technical solution was dictated by several constraints. Namely, the first one arises when there is a need to send a lot of messages between servers. At a certain point, the internet connection could run out. Although data sharding solves this issue, it leaves the second problem, the lack of processing power. For this reason, multithreading, in the form of parallel execution, is fundamental for network scalability. 32 | 33 | ## Everscale’s threading in a nutshell. 34 | 35 | - In case of a significant increase in the network load, some shards can be assigned to the neighboring validators. 36 | - The shards (workchains) offer low transaction fees while at the same time providing the security of Everscale (masterchain). 37 | - Each election cycle the global set of validators rotate and are assigned to a shard (workchain). 38 | - In the near future, there will be the possibility to deploy multiple multi-threaded shards (workchains). 39 | 40 | At the start of 2023, Everscale is still one of the few infinitely scalable blockchains. It is technically ready to process millions of transactions per second, far outpacing both centralized services, like Visa, and decentralized projects that still research different ways to increase their throughput. 41 | -------------------------------------------------------------------------------- /src/overview/lore.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # The Lore 6 | 7 | **Everscale’s chronicle** 8 | 9 | **2017** 10 | 11 | - Pavel Durov developed the concept of TON - Telegram Open Network. The project is inextricably linked with Telegram Messenger, with plans to integrate the Gram cryptocurrency. 12 | 13 | **2018** 14 | 15 | - [TON virtual machine](https://docs.everscale.network/arch/tvm) is delivered.-TON blockchain is launched. The network is 70% ready and most of the components are finalized. 16 | 17 | **2019** 18 | 19 | - EverX (ex. TON Labs) launches the first EVER blockchain with proof of authority consensus algorithm (PoA). 20 | - EverX launches the alpha version of TON OS. 21 | - TON portal for developers with official project specifications is opened - [https://test.ton.org/](https://test.ton.org/). 22 | - The U.S. Securities and Exchange Commission (SEC) demands a ban on the issuance of Gram. The SEC, in its report, recognizes Gram as a security (not a commodity or utility token) and that Gram's issue itself violates securities laws.EverX launches its own TON testnet. 23 | 24 | **2020** 25 | 26 | - The SEC interrogates Pavel Durov about TON ICO. The interrogation took place in Dubai, UAE. The American regulator is trying to find out why Durov launched the ICO, how much money he spent on Telegram and TON, and why the Gram token is not a security. Durov replied that the money was needed to buy equipment and maintain the blockchain platform and that Gram was a utility token, not a security. Telegram challenges the U.S. court ban on transferring Gram tokens to investors. The court of the Southern District of New York State in a preliminary decision agrees with the SEC's opinion that the project's cryptocurrency is a security. The U.S. authorities claim that investors purchased coins to sell on the secondary market to earn money. 27 | - Pavel Durov announced on his Telegram channel that he is closing the TON blockchain project. According to Pavel Durov, Telegram's participation in TON development is over. He urged users not to trust money or data to projects that use the name of the messenger or the platform.EverX participates in the community launch of the Free TON blockchain as the core developer. 28 | - Free TON Community, composed of developers and potential TON users, launches the Free TON blockchain platform. Instead of Gram, participants get tokens called TON Crystal. To become a community member, you need to sign the Free TON Declaration of Decentralization. 29 | 30 | **2021** 31 | 32 | - Everscale achieves world record throughput - 64,000 transactions per second. 33 | - Free TON announces the ecosystem rebrand to Everscale. The new brand identity comes as the network prepares to migrate from C++ to the Rust programming language, enabling unmatched scalability and throughput capable of bringing the world on-chain. 34 | 35 | **2022** 36 | 37 | - REMP (reliable external messaging protocol) is in the active R&D phase. REMP support is included in the Everscale SDK. 38 | - The introduction of a set of economic measures to help EVER get into the top 10 by Coinmarketcap. 39 | - The partnership with DA5 to launch the Philippine blockchain remittance service - marking the first step in Everscale’s rollout of products on the Asian market. 40 | - The establishment of new development priorities - CBDCs and enterprise solutions. Everscale aims to achieve a high market share in these promising niches. 41 | 42 | **2023** 43 | 44 | - The partnership with Venom - a blockchain licensed by Abu Dhabi Global Market (ADGM). 45 | - **More partnerships, integrations, and technical upgrades coming.** 46 | -------------------------------------------------------------------------------- /src/overview/overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | slug: "contents" 4 | --- 5 | 6 | # Documentation overview 7 | 8 | ## Welcome 9 | 10 | This is the introductory section where you can learn Everscale’s basic concepts, infinite scalability as well as comparisons with Ethereum, Cosmos and Avalanche. 11 | 12 | - [Infinite scalability](infinite-scalability.md) 13 | - [Differences from EVM](differences-from-evm.md) 14 | - [The Lore](lore.md) 15 | - [Glossary](concepts.md) 16 | 17 | ## Build 18 | 19 | Get familiar with Everscale’s developer tools and start building. Also, please find the guides to install the IDE and write your first smart contract with Everscale. 20 | 21 | - [Intro](../develop/intro.md) 22 | - [Developer Tools Overview](../develop/tools-overview.md) 23 | - [Smart Contracts](../develop/smart-contracts/) 24 | - [Recipes for Backend and Frontend devs](../develop/recipes) 25 | 26 | ## Validator and full node infrastructure 27 | 28 | Learn Everscale’s validation in case you want to be a validator or just familiarize yourself with the technology. 29 | 30 | - [Validator and Full Node Infrastructure](../validate.md) 31 | 32 | ## Specifications 33 | 34 | Learn about incoming external messages tracing via the REMP protocol. Also, study Everscale's token standards, DePools and others. 35 | 36 | - [Standards](../standard/) 37 | - [ABI](../spec/10-abi.md) 38 | - [dePool Specification](../spec/20-depool-specification.md) 39 | 40 | ## Architecture 41 | 42 | Learn Everscale's peer-to-peer protocols. Among others, they are used to propagate new blocks as well as send and collect transaction candidates. 43 | 44 | - [Networking](../arch/networking/) 45 | - [Consensus](../arch/consensus/) 46 | - [TL-B and BoC](../arch/07-tlb-and-boc.md) 47 | - [TVM](../arch/10-tvm.md) 48 | - [Network Fees](../arch/25-fee-calculation.md) 49 | - [Gas Calculation](../arch/30-managing-gas.md) 50 | - [Executor](../arch/35-executor.md) 51 | - [Logical Time and Message Delivery Guarantees](../arch/37-logic-time.md) 52 | - [Account](../arch/40-accounts.md) 53 | - [Message](../arch/45-message.md) 54 | - [Transaction](../arch/50-transactions.md) 55 | - [Workchains](../arch/70-workchains.md) 56 | - [Multithreading and Message Queues](../arch/80-multithreading.md) 57 | -------------------------------------------------------------------------------- /src/spec/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 4, 3 | "label": "Specifications", 4 | "link": { 5 | "title": "Specifications", 6 | "slug": "spec", 7 | "type": "generated-index" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/standard/TIP-1/2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 1.2 MYCODE 3 | sidebar_position: 2 4 | description: Returns the Cell with the current code of the smartcontract 5 | slug: /standard/TIP-1.2 6 | --- 7 | 8 | # MYCODE (TIP-1.2) 9 | 10 | `F82A` — `MYCODE (- s)` — returns the Cell with the current code of the smartcontract. Equivalent to `GETPARAM 10`. Smartcontract has own code which cell representation can be obtained by this instruction. 11 | -------------------------------------------------------------------------------- /src/standard/TIP-1/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 1, 3 | "label": "TIP-1 TVM Opcode", 4 | "link": { 5 | "slug": "standard/TIP-1", 6 | "description": "For discussing changes to existing and suggesting new opcodes for the virtual machine", 7 | "title": "TIP-1 TON Virtual Machine Opcode", 8 | "type": "generated-index" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/standard/TIP-3/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 3, 3 | "label": "TIP-3 FT" 4 | } 5 | -------------------------------------------------------------------------------- /src/standard/TIP-3/core-description.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Core description 3 | sidebar_position: 0 4 | slug: /standard/TIP-3 5 | --- 6 | 7 | # Fungible Token 8 | 9 | ## Abstract 10 | 11 | The following standard describes the basic idea about distributed fungible token architecture. 12 | 13 | ## Motivation 14 | 15 | The suggested standard differs considerably from Ethereum ERC20 and other smart contract token standards with single registry due to its distributed nature related to Everscale blockchain particularities. Given that Everscale has a storage fee, using an existing ERC20 standard design would cause excessive maintenance costs. Also, ERC20 is somewhat incompatible with the sharding architecture. Therefore, a Distributed Token standard is preferable. 16 | 17 | The ERC20 sharding implementation (with an idea to simply shard its registry) has drawbacks mainly related to complicated and expansive management. TIP-3 is fully distributed and implies separate storage of each user’s balance. 18 | 19 | ## Architecture 20 | 21 | General information about token is stored in the [token root](#token-root) contract. Each token holder has its own instance of [token wallet](#token-wallet) contract. Token transfers SHOULD be implemented in P2P fashion, between sender and receiver token wallets. 22 | 23 | ### Token root 24 | 25 | Token root contract stores the general information about the token, e.g. name, symbol, decimals, token wallet code and so on. 26 | 27 | ### Token wallet 28 | 29 | Each token holder has its own instance of token wallet contract. Transfer happens in a decentralized fashion - sender token wallet SHOULD send the specific message to the receiver token wallet. Since token wallets have the same code, it's easy for receiver token wallet to check the correctness of sender token wallet. 30 | 31 | ## References 32 | 33 | - [EIP-20: Token Standard](https://eips.ethereum.org/EIPS/eip-20) 34 | - [Everscale Forum - TIP3](https://forum.freeton.org/t/tip-3-distributed-token-or-ton-cash/64) 35 | - [Reference implementation by Broxus](https://github.com/broxus/ton-eth-bridge-token-contracts) 36 | -------------------------------------------------------------------------------- /src/standard/TIP-4/4.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 4.4. On-chain storage 3 | sidebar_position: 4 4 | slug: /standard/TIP-4.4 5 | --- 6 | 7 | # Non-Fungible Token On-chain storage (TIP-4.4) 8 | Requires: [TIP-4.1](1.md) 9 | Requires: [TIP-6.1](./../TIP-6/1.md) 10 | 11 | ## Abstract 12 | Using the Storage contract, you can store NFT-related bytes in blockchain 13 | 14 | ## Motivation 15 | Fault tolerance. If off-chain services are unavailable, the user will view NFT-related bytes, because it is stored on-chain. 16 | 17 | ## Specification 18 | The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119) 19 | 20 | ## Contracts 21 | * `Collection` - [TIP4.1](1.md) contract that minted token and store `Storage` contract code 22 | * `NFT` - [TIP4.1](1.md) contract that store token information and `Storage` contract address 23 | * `Storage` - contract that store token byte content. Storage is independent. Storage doesn’t store `NFT` address because `NFT` contract address can be changed by burning and redeployment from another collection. 24 | 25 | ## Collection 26 | Every [TIP-4.1](1.md) `Collection` contract must implement `TIP4_4Collection` 27 | ```solidity 28 | pragma ton-solidity >= 0.58.0; 29 | 30 | interface TIP4_4Collection { 31 | function storageCode() external view responsible returns (TvmCell code); 32 | function storageCodeHash() external view responsible returns (uint256 codeHash); 33 | function resolveStorage(address nft) external view responsible returns (address addr); 34 | } 35 | ``` 36 | **NOTE** The [TIP-6.1](../TIP-6/1.md) identifier for this interface is `0x6302A6F8` 37 | 38 | ### TIP4_4Collection.storageCode() 39 | ```solidity 40 | function storageCode() external view responsible returns (TvmCell code); 41 | ``` 42 | * `code` (`TvmCell`) - storage contract code 43 | 44 | ### TIP4_4Collection.storageCode() 45 | ```solidity 46 | function storageCodeHash() external view responsible returns (uint256 hash); 47 | ``` 48 | * `hash` (`uint256`) - storage contract code hash 49 | 50 | ### TIP4_4Collection.resolveStorage() 51 | ```solidity 52 | function resolveStorage(address nft) external view responsible returns (address addr); 53 | ``` 54 | * `nft` (`address`) - token contract address 55 | * `addr` (`address`) - storage contract address 56 | 57 | ## NFT 58 | Every [TIP-4.1](1.md) `NFT` contract must implement `TIP4_4NFT` 59 | ```solidity 60 | pragma ton-solidity >= 0.58.0; 61 | 62 | interface TIP4_4NFT { 63 | function onStorageFillComplete(address gasReceiver) external; 64 | function getStorage() external view responsible returns (address addr); 65 | } 66 | ``` 67 | **NOTE** The [TIP-6.1](../TIP-6/1.md) identifier for this interface is `0x009DC09A` 68 | 69 | ### TIP4_4NFT.onStorageFillComplete() 70 | ```solidity 71 | function onStorageFillComplete(address gasReceiver) external; 72 | ``` 73 | * `gasReceiver` (`address`) - address of contract that receive all remaining contract balance then last chunk filled 74 | Calling the `Storage.fill()` on storage contract that fills the last chunk should call `TIP4_4NFT.onStorageFillComplete()` on token contract 75 | 76 | ### TIP4_4NFT.getStorage() 77 | ```solidity 78 | function getStorage() external view responsible returns (address addr); 79 | ``` 80 | * `addr` (`address`) - storage contract address 81 | 82 | ## Storage 83 | Every `Storage` contract must implement `TIP4_4Storage` 84 | ```solidity 85 | pragma ton-solidity >= 0.58.0; 86 | 87 | interface TIP4_4Storage { 88 | function fill(uint32 id, bytes chunk, address gasReceiver) external; 89 | function getInfo() external view responsible returns ( 90 | address nft, 91 | address collection, 92 | string mimeType, 93 | mapping(uint32 => bytes) content, 94 | string contentEncoding 95 | ); 96 | } 97 | ``` 98 | **NOTE** The [TIP-6.1](../TIP-6/1.md) identifier for this interface is `0x204D6296` 99 | 100 | ### TIP4_4Storage.fill() 101 | ```solidity 102 | function fill(uint32 id, bytes chunk, address gasReceiver) external; 103 | ``` 104 | * `id` (`uint32`) - chunk number. From `0` to `4 294 967 295` 105 | * `bytes` (`chunk`) - data. Max size of data is limited by external message payload size. Maximum size external message payload size is `16KB` at 2022-03-18. 106 | * `gasReceiver` (`address`) - address of contract that receive all remaining contract balance then last chunk filled. 107 | 108 | ### TIP4_4Storage.getInfo() 109 | ```solidity 110 | function getInfo() external view responsible returns ( 111 | address nft, 112 | address collection, 113 | string mimeType, 114 | mapping(uint32 => bytes) chunks, 115 | string contentEncoding 116 | ); 117 | ``` 118 | 119 | * `nft` (`address`) - token contract address 120 | * `collection` (`address`) - collection token contract address 121 | * `mimeType` (`string`) - [MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) are defined and standardized in IETF's [RFC 6838](https://datatracker.ietf.org/doc/html/rfc6838) 122 | * `content` (`mapping(uint32 => bytes)`) - byte content. Maximum content size is `4 294 967 295 chunks * chunk size`. Max size of data is limited by external message payload size. Maximum size external message payload size is `16KB` at 2022-03-18 Maximum content size is `4 294 967 295 * 16KB ≈ 69TB` at 2022-03-18. 123 | * `contentEncoding` (`string`) - Was it compressed by any algorithm. If it was compressed with [zstd](https://github.com/tonlabs/ever-sdk/blob/master/docs/reference/types-and-methods/mod_utils.md#compress_zstd) contentEncoding need to be `zstd`, all other need to be like [http content encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding) 124 | 125 | ## Visualization 126 | ### Legend 127 | ![Legend](img/legend1.svg) 128 | ![Legend](img/legend2.svg) 129 | 130 | ### `NFT` minting with `Storage` 131 | ![Storage](img/storage1.svg) 132 | 133 | ### `Storage` filling 134 | ![Storage](img/storage2.svg) 135 | 136 | ### `Storage` with `Index` 137 | How to interaction [on-chain indexes](3.md) and `Storage` contracts 138 | ![Storage](img/storage3.svg) 139 | -------------------------------------------------------------------------------- /src/standard/TIP-4/5.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 4.5. NFT Licensing 3 | sidebar_position: 4 4 | slug: /standard/TIP-4.5 5 | --- 6 | 7 | # Non-Fungible Licensing (TIP-4.5) 8 | Requires: [TIP-4.1](1.md) 9 | Requires: [TIP-6.1](./../TIP-6/1.md) 10 | 11 | ## Abstract 12 | 13 | The NFT License Standart is a standard set of functions for retrieving license information. This interface allows external callers to access the license URI and the license name associated with a specific entity. The preferred but not mandatory method of storing license links is using IPFS. A collection of NFT licenses can be obtained via a [link](https://github.com/a16z/a16z-contracts). 14 | 15 | ## Motivation 16 | 17 | This standard was developed based on the previous version of the ["CantBeEvil"](https://github.com/everscale-org/docs/blob/6198a3be3428841b47d7072d87b10854aca6b879/src/standard/TIP-4/5.md) standard. The new "NFT Licensing" standard offers you more freedom and flexibility in using licenses for your NFT tokens, allowing you to choose any license that reflects your vision and protects your rights, provided that a link to it is provided. 18 | 19 | ## Specification 20 | 21 | The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119). 22 | 23 | 24 | ### TIP4_5 25 | ```solidity 26 | pragma ever-solidity >= 0.61.2; 27 | 28 | interface ITIP4_5 { 29 | function getLicenseURI() external view responsible returns (string); 30 | function getLicenseName() external view responsible returns (string); 31 | } 32 | ``` 33 | 34 | **NOTE** The [TIP-6.1](../TIP-6/1.md) identifier for this interface is `0x8A1EB91` (with responsible) and `0x1E4848D4` (without responsible). 35 | 36 | ### TIP4_5.getLicenseURI() 37 | ```solidity 38 | function getLicenseURI() external view responsible returns (string); 39 | ``` 40 | 41 | Returns the license URI. The license URI represents the location or identifier that can be used to access the full details of the license, such as terms and conditions, permissions, and restrictions. 42 | 43 | ### TIP4_5.getLicenseName() 44 | ```solidity 45 | function getLicenseName() external view responsible returns (string); 46 | ``` 47 | 48 | Returns the name or title of the license. The license name provides a concise and descriptive representation of the license type or category. 49 | -------------------------------------------------------------------------------- /src/standard/TIP-4/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 4, 3 | "label": "TIP-4 NFT" 4 | } 5 | -------------------------------------------------------------------------------- /src/standard/TIP-4/core-description.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Core description 3 | sidebar_position: 0 4 | slug: /standard/TIP-4 5 | --- 6 | 7 | # Non-Fungible Token 8 | 9 | ## Abstract 10 | 11 | The following standard describes the basic idea of distributed non-fungible token architecture. 12 | 13 | ## Motivation 14 | 15 | The suggested standard differs considerably from Ethereum ERC721 and other smart contract token standards with single registry because of its distributed nature related to Everscale blockchain particularities. 16 | Given that Everscale has a storage fee, TIP4 is fully distributed and implies separate storage of each NFT. 17 | 18 | ## Architecture 19 | 20 | General information about NFT collection is stored in the NFT collection contract. Each NFT deployed in separate smart contracts and links to NFT collection contract Smart contract architecture based on: 21 | 22 | - Consider asynchronous type of Everscale blockchain. Use callbacks and asynchronous getters; 23 | - Standardizes one NFT - one smart contract. 24 | - Gas fee management practicals. 25 | - Use [TIP-6.1](./../TIP-6/1.md) 26 | 27 | ## (Status:Review) [Non-Fungible Token (TIP-4.1)](./../TIP-4/1.md) 28 | General information about NFT collection and NFT tokens. All NFT must implement [TIP-4.1](./../TIP-4/1.md) 29 | 30 | ## (Status:Review) [Non-Fungible Token JSON Metadata (TIP-4.2)](./../TIP-4/2.md) 31 | General information about NFT metadata. [TIP-4.2](./../TIP-4/2.md) is optional, but can be used for displaying NFT on marketplaces, wallets and web. 32 | 33 | ## (Status:Review) [On-chain indexes (TIP-4.3)](./../TIP-4/3.md) 34 | On-chain Indexes solves easy and fast searching any data in blockchain. [TIP-4.3](./../TIP-4/3.md) is optional, but can be use for find all your NFT with one [dApp](https://main.ton.dev/graphql) query. 35 | 36 | ## (Status:Draft) [On-chain storage (TIP-4.4)](./../TIP-4/4.md) 37 | Using the Storage contract, you can store NFT-related bytes in blockchain. [TIP-4.4](./../TIP-4/4.md) is optional, but can be used for fault tolerance. If off-chain services are unavailable, the user will view NFT-related bytes, because it is stored on-chain. 38 | 39 | ## (Status:Draft) [Don't Be Evil NFT licensing (TIP-4.5)](./../TIP-4/5.md) 40 | The standard adds the support of [Can't Be Evil NFT licenses](https://github.com/a16z/a16z-contracts) [introduced](https://a16zcrypto.com/introducing-nft-licenses/) by [Andreessen.Horowitz](https://a16z.com). [TIP-4.5](./../TIP-4/5.md) is optional, but can be used for clarifying the legal basis of NFT usage by the owner. 41 | 42 | ## (Status:Draft) [Upgradeable NFT (TIP-4.6)](./../TIP-4/6.md) 43 | The standard describes the operation of upgradeable NFT contracts. [TIP-4.6](./../TIP-4/6.md) is optional, but can be used for changing NFT code in case an error is found in it or there is a need to add new functionality. 44 | 45 | **Implementation** 46 | 47 | [grandbazar.io](https://github.com/grandbazar-io/everscale-tip4.6-contracts) implementation 48 | 49 | 50 | ## Authors 51 | | Author | Command | 52 | |-------------------------------------------------|------------------------------------------| 53 | | [Aleksand Aleksev](mailto:rualekseev@gmail.com) | [grandbazar.io](https://grandbazar.io) | 54 | | Aleksandr Khramtsov | [broxus](https://broxus.com/) | 55 | | Vladislav Ponomarev | [broxus](https://broxus.com/) | 56 | | [Andrey Nedobylskiy](https://t.me/nedobylskiy) | [svoi.dev](https://svoi.dev) | 57 | | [Anton Platonov](https://t.me/SuperArmor) | community member | 58 | | [Nikita](https://t.me/kokkekpek) | [numiz.org](https://numiz.org/) | 59 | | [Oleg Varnov](https://t.me/id_xz) | [numiz.org](https://numiz.org/) | 60 | | Slava Semenchuk | [scalepunks.com](https://scalepunks.com) | 61 | 62 | 63 | ## Implementation 64 | 65 | [itgold](https://github.com/itgoldio/everscale-tip) implementation 66 | 67 | - MIT licensed. 68 | - A library of modular, reusable smart contracts. 69 | - Samples and tests [here](https://github.com/itgoldio/everscale-tip-samples) 70 | 71 | ## References 72 | 73 | - [Ethereum EIP-721](https://eips.ethereum.org/EIPS/eip-721) 74 | - [Solana v1.2.0](https://docs.metaplex.com/token-metadata/specification) 75 | - [TON NFT](https://github.com/ton-blockchain/TIPs/issues/62), [TON DATA](https://github.com/ton-blockchain/TIPs/issues/64) 76 | - [Tezos TZIP12](https://gitlab.com/tezos/tzip/-/blob/master/proposals/tzip-12/tzip-12.md) 77 | -------------------------------------------------------------------------------- /src/standard/TIP-5/core-description.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Core description 3 | sidebar_position: 0 4 | slug: /standard/TIP-5 5 | [//]: # (draft: true) 6 | --- 7 | 8 | # URI scheme 9 | 10 | ## Abstract 11 | 12 | This TIP proposes a URI scheme for making payments and transfers in EVER, fungible and non-fungible tokens. 13 | 14 | ## Motivation 15 | 16 | Payment URIs has become widely adopted since the introduction of Bitcoin’s improvement proposals [BIP-20](https://github.com/bitcoin/bips/blob/master/bip-0020.mediawiki), [21](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki), [70](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki), [71](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki), and [72](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki). For instance, most modern mobile wallets support the scanning of QR codes containing encoded bitcoin payment links. 17 | 18 | The purpose of this URI scheme is to enable users to easily make payments and transfers in EVER, fungible and non-fungible tokens by simply clicking links on web pages or scanning QR Codes. -------------------------------------------------------------------------------- /src/standard/TIP-6/1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 1. Interface Detection 3 | sidebar_position: 1 4 | slug: /standard/TIP-6.1 5 | --- 6 | 7 | # Standard Interface Detection Interface (TIP-6.1) 8 | 9 | ## Simple summary 10 | 11 | Creates a standard method to publish and detect what interfaces a smart contract implements. 12 | 13 | ## Abstract 14 | 15 | Herein, we standardize the following: 16 | 17 | - How interfaces are identified 18 | - How a contract will publish the interfaces it implements 19 | 20 | ## Motivation 21 | 22 | For some “standard interfaces” like the token interface, it is sometimes useful to query whether a contract supports the interface and if yes, which version of the interface, in order to adapt the way in which the contract is to be interacted with. This proposal standardizes the concept of interfaces and standardizes the identification (naming) of interfaces. 23 | 24 | ## Specification 25 | 26 | ### How interfaces are identified 27 | 28 | For this standard, an interface is a set of function selectors as defined by the Solidity ABI. This a subset of Solidity’s concept of interfaces and the interface keyword definition which also defines return types, mutability and events. 29 | 30 | We define the interface identifier as the XOR of all function selectors in the interface. This code example shows how to calculate an interface identifier: 31 | 32 | #### Solidity 33 | 34 | ```solidity 35 | interface Solidity101 { 36 | function hello() external pure; 37 | function world(int) external pure; 38 | } 39 | 40 | contract Selector { 41 | function calculateSelector() public view returns (bytes4) { 42 | Solidity101 i; 43 | return bytes4(tvm.functionId(i.hello) ^ tvm.functionId(i.world)); 44 | } 45 | } 46 | ``` 47 | 48 | #### How a Contract will Publish the Interfaces it Implements 49 | 50 | A contract that is compliant with TIP6.1 shall implement the following interface: 51 | 52 | #### Solidity 53 | 54 | ```solidity 55 | interface TIP6 { 56 | /// @notice Query if a contract implements an interface 57 | /// @param interfaceID The interface identifier, as specified in TIP6.1 58 | /// @dev Interface identification is specified in TIP6.1. 59 | /// @return `true` if the contract implements `interfaceID` and 60 | /// `interfaceID` is not 0xffffffff, `false` otherwise 61 | function supportsInterface(bytes4 interfaceID) external view responsible returns (bool); 62 | } 63 | ``` 64 | 65 | The interface identifier for this interface is `0x3204EC29`. You can calculate this by running `tvm.functionId('supportsInterface(bytes4)')`; or using the Selector contract above. 66 | 67 | Therefore, the implementing contract will have a `supportsInterface` function that returns: 68 | 69 | - `true` when `interfaceID` is `0x3204EC29` (TIP6.1 interface) 70 | - `false` when `interfaceID` is `0xffffffff` 71 | - `true` for any other `interfaceID` this contract implements 72 | - `false` for any other `interfaceID` 73 | 74 | ## References 75 | 76 | - [EIP-165: Standard Interface Detection](https://eips.ethereum.org/EIPS/eip-165) 77 | -------------------------------------------------------------------------------- /src/standard/TIP-6/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 6, 3 | "label": "TIP-6" 4 | } 5 | -------------------------------------------------------------------------------- /src/standard/TIP-6/core-description.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Core description 3 | sidebar_position: 0 4 | slug: /standard/TIP-6 5 | --- 6 | 7 | # Standard Interface Detection 8 | 9 | ## Abstract 10 | 11 | Smart contracts in Everscale can implement a wide variety of functionality - wallets, tokens, exchanges and so on. 12 | We need a standard way to determine the type of smart contract without relying on knowledge of its internal structure. -------------------------------------------------------------------------------- /src/standard/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "position": 4, 3 | "label": "Standards", 4 | "link": { 5 | "title": "Standards", 6 | "slug": "standard", 7 | "type": "generated-index" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/standard/workflow.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: What is TIP? 3 | sidebar_position: 0 4 | --- 5 | 6 | # What is TIP? (TIP-0) 7 | 8 | TIP — Trustless Improvement Proposal (TIPs) describe standards for the Everscale blockchain. They may include anything that the community considers in need of improvement or standardization. That can be specifications for core protocol, description of interfaces, smart contract standards and so on. 9 | 10 | I propose a more relaxed structure more closely resembling Bitcoin BIPs but with quite different proccess (see below). 11 | 12 | Each TIP should have the following parts (which are heavily copy-pasted from BIP requirements): 13 | 14 | - Preamble — Headers containing metadata about the TIP; 15 | - Abstract — A short (~200 word) description of the technical issue being addressed; 16 | - Copyright — The TIP must be explicitly licensed under acceptable copyright terms; 17 | - Specification — The technical specification should describe the syntax and semantics of any new feature; 18 | - The specification should be detailed enough to allow competing, interoperable implementations; 19 | - Motivation — The motivation is critical for TIPs that want to change the Everscale protocol. It should clearly explain why the existing protocol is inadequate to address the problem that the TIP solves; 20 | - Rationale — The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work. The rationale should provide evidence of consensus within the community and discuss important objections or concerns raised during discussion; 21 | - Backwards compatibility — All TIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The TIP must explain how the author proposes to deal with these incompatibilities; 22 | 23 | Each TIP should pass the following process of acceptance: 24 | 25 | `Proposal` → `Discussion` → `Community Voting` → `Reference Implementations Contest` → `Final TIP with Reference Implementations` 26 | 27 | - Reference implementation — The reference implementation must be completed before any TIP is given status `Final`, but it need not be completed before the TIP is accepted. It is better to finish the specification and rationale first and reach consensus on it before writing code. The final implementation must include test code and documentation appropriate for the Everscale protocol. 28 | -------------------------------------------------------------------------------- /src/welcome.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 0 3 | slug: / 4 | --- 5 | 6 | # Welcome to Everscale 7 | 8 | 9 | 10 | This is the starting point for Everscale documentation. Here you will find the guidance necessary to start developing on the network. 11 | 12 | ## To begin with 13 | 14 | Since you landed on this page you most likely want to learn Everscale’s tech and start developing with us. This entails you will need to create a wallet and hold some EVERs, the native token of Everscale. Below, we gathered the resources you will undoubtedly need to comfortably manage your EVER tokens. 15 | 16 | 1. **Create a Wallet** 17 | 18 | - [https://everwallet.net/](https://everwallet.net/) 19 | - [https://ever.surf/](https://ever.surf/) 20 | - [https://everspace.app/](https://everspace.app/) 21 | 22 | This is the place where you will store your EVER tokens while interacting with Everscale. 23 | 24 | 2. **Buy or Sell EVERs** 25 | 26 | One window for all DEX and CEX platforms where EVER token is listed on. 27 | 28 | [https://everkit.org/coin](https://everkit.org/coin) 29 | 30 | 3. **Exchange tokens** 31 | 32 | 33 | [https://flatqube.io/](https://flatqube.io/) 34 | 35 | 36 | With FlatQube you can easily exchange your tokens or use a multitude of earning opportunities, including liquid staking. 37 | 38 | 4. **Track transactions** 39 | 40 | 41 | - [https://everscan.io/](https://everscan.io/) 42 | - [https://ever.live](https://ever.live) 43 | 44 | 45 | With the help of these explorers, you can search and view all transactions, addresses, tokens and other activities on the Everscale blockchain and its test networks. 46 | 47 | 5. **Move tokens across chains** 48 | 49 | 50 | [https://octusbridge.io/](https://octusbridge.io/) 51 | 52 | Octus Bridge allows you to instantly transfer your tokens to several popular networks in both directions. 53 | 54 | :::info 55 | 56 | After having studied how to manage your EVERs, please move to the overview of Everscale’s documentation via [this link](overview/overview.md). 57 | 58 | ::: 59 | --------------------------------------------------------------------------------