From 9279c2a071810a432a2e1362d3f27a22dd600d6c Mon Sep 17 00:00:00 2001 From: Ben-Rey Date: Fri, 9 Feb 2024 12:30:22 +0000 Subject: [PATCH] deploy: 2b104302f2ed71a780cf7c12081cdbdb8781fda3 --- 404.html | 4 ++-- .../{02918e2b.0ca8b141.js => 02918e2b.c3242b7d.js} | 2 +- assets/js/0303d204.60644a50.js | 1 + assets/js/0303d204.9ac17590.js | 1 - assets/js/0512b022.3aaf600e.js | 1 - assets/js/0512b022.7edea0d5.js | 1 + .../{0734719f.e3287971.js => 0734719f.becb4c98.js} | 2 +- .../{082a8033.c9e8936c.js => 082a8033.353e47a1.js} | 2 +- assets/js/10d3671b.1dd2d8a5.js | 1 - assets/js/10d3671b.aac0aec8.js | 1 + .../{13601854.fac1bb19.js => 13601854.8b81edd3.js} | 2 +- assets/js/14161a26.690cf56f.js | 1 + assets/js/14161a26.6b096048.js | 1 - assets/js/1d3e2afe.4d0ca5b8.js | 1 + assets/js/1d3e2afe.ae7f2f1d.js | 1 - assets/js/21529a4e.3994a2b5.js | 1 - assets/js/21529a4e.dccd2915.js | 1 + assets/js/233a18d6.6631165d.js | 1 + assets/js/233a18d6.b65d48aa.js | 1 - assets/js/239c5dbf.4f55c85b.js | 1 + assets/js/239c5dbf.d70b5a3f.js | 1 - assets/js/256be1ac.0319165e.js | 1 + assets/js/256be1ac.a97c2cab.js | 1 - assets/js/2580cc57.5e752695.js | 1 + assets/js/2580cc57.7351d524.js | 1 - assets/js/28d23288.afed3aba.js | 1 - assets/js/28d23288.bfb73dae.js | 1 + assets/js/28eb6811.45a8763e.js | 1 - assets/js/28eb6811.6b87d377.js | 1 + assets/js/2e7e0665.787d2ced.js | 1 - assets/js/2e7e0665.fc80f398.js | 1 + .../{31043fb2.6b93b161.js => 31043fb2.e5aac349.js} | 2 +- assets/js/330b5f37.1715192e.js | 1 + assets/js/330b5f37.572c352d.js | 1 - assets/js/34fddb0a.308abfcc.js | 1 + assets/js/34fddb0a.8a38eca2.js | 1 - assets/js/383e51e1.911d7d6e.js | 1 - assets/js/383e51e1.bd681953.js | 1 + assets/js/3b5bba7a.466cf864.js | 1 + assets/js/3b5bba7a.6d798214.js | 1 - assets/js/3e4cab72.060c45ba.js | 1 + assets/js/3e4cab72.62a5425c.js | 1 - assets/js/45c0e8c1.df809bd5.js | 1 - assets/js/45c0e8c1.f330b96d.js | 1 + assets/js/46afc4b0.636d48de.js | 1 + assets/js/46afc4b0.c4c468c2.js | 1 - assets/js/47c2a5ff.29678642.js | 1 + assets/js/47c2a5ff.fd92e495.js | 1 - assets/js/533eedc9.2e3095c3.js | 1 - assets/js/533eedc9.fac6aeae.js | 1 + assets/js/59fee8c2.226f36a1.js | 1 - assets/js/59fee8c2.fd0f9413.js | 1 + .../{5ec7f8bd.2767532a.js => 5ec7f8bd.548303dc.js} | 2 +- assets/js/60246af2.8bbe4530.js | 1 - assets/js/60246af2.ec91afad.js | 1 + .../{65a48c1c.3c754403.js => 65a48c1c.49928ef0.js} | 2 +- .../{68a358ec.28a5c862.js => 68a358ec.325eea62.js} | 2 +- assets/js/6900ad03.21057a29.js | 1 - assets/js/6900ad03.aa8206c0.js | 1 + assets/js/6ed436f8.8b9b076e.js | 1 - assets/js/6ed436f8.d46943c5.js | 1 + .../{717b6d43.5cab6579.js => 717b6d43.8a9278ff.js} | 2 +- .../{786c2353.0a80bef8.js => 786c2353.a56dc889.js} | 2 +- .../{81356911.0ed7f2f9.js => 81356911.c10d9a68.js} | 2 +- assets/js/86001517.0e282e74.js | 1 + assets/js/86001517.953457f4.js | 1 - assets/js/96daec60.0cb8247a.js | 1 + assets/js/96daec60.955a220e.js | 1 - assets/js/aae87ff3.62bbca3a.js | 1 + assets/js/aae87ff3.e4bdb9e2.js | 1 - assets/js/ae42d3c5.341e5f02.js | 1 + assets/js/ae42d3c5.49edffb7.js | 1 - .../{af6fbf3d.1aa6f226.js => af6fbf3d.2b5f9048.js} | 2 +- assets/js/afc6f80d.06b96232.js | 1 + assets/js/afc6f80d.b9fbe904.js | 1 - assets/js/b0e553de.c4ef4ba8.js | 1 - assets/js/b0e553de.ce4bda73.js | 1 + assets/js/b564223c.81e18ea4.js | 1 + assets/js/b564223c.99e8aad5.js | 1 - assets/js/ba31b44f.9a000ef9.js | 1 + assets/js/ba31b44f.dc992478.js | 1 - assets/js/bbd40d9c.075b8ace.js | 1 + assets/js/bbd40d9c.631613cb.js | 1 - assets/js/bc47a922.08a112ed.js | 1 + assets/js/bc47a922.b377557f.js | 1 - assets/js/c332032b.96c3e559.js | 1 - assets/js/c332032b.9f002d0e.js | 1 + assets/js/c59c9eb2.1a1a153d.js | 1 - assets/js/c59c9eb2.d8d79186.js | 1 + .../{cab0926f.a2384583.js => cab0926f.5771f764.js} | 2 +- .../{cc31dfa8.3579740f.js => cc31dfa8.5468af17.js} | 2 +- .../{d9062d8c.9afee93b.js => d9062d8c.298779ed.js} | 2 +- .../{dba7919e.aba4f578.js => dba7919e.629e0f1f.js} | 2 +- assets/js/dbc90ee5.4d6e339b.js | 1 - assets/js/dbc90ee5.f96089a3.js | 1 + assets/js/ded851bf.076fe68c.js | 1 - assets/js/ded851bf.62b54c52.js | 1 + assets/js/e56aa218.4da5957a.js | 1 + assets/js/e56aa218.a946a3e9.js | 1 - assets/js/e58c5506.2d3a81c2.js | 1 + assets/js/e58c5506.c79e777d.js | 1 - assets/js/e7d3f44b.17f7c68c.js | 1 - assets/js/e7d3f44b.1a9fb41d.js | 1 + assets/js/eae7922f.1de17331.js | 1 - assets/js/eae7922f.88adf2af.js | 1 + assets/js/f27bf80f.9866de5c.js | 1 - assets/js/f27bf80f.e91497b2.js | 1 + .../{f4993782.9c401e51.js => f4993782.a288acc3.js} | 2 +- .../{f5aa9287.91e92931.js => f5aa9287.a86e16b3.js} | 2 +- .../{fae30412.ece11059.js => fae30412.ab27e23f.js} | 2 +- assets/js/fb34ae5b.0dd9a780.js | 1 + assets/js/fb34ae5b.b1a550d1.js | 1 - ...me~main.4a8cfd9a.js => runtime~main.55ca36c1.js} | 2 +- blog.html | 4 ++-- blog/archive.html | 4 ++-- blog/first-blog-post.html | 4 ++-- blog/long-blog-post.html | 4 ++-- blog/mdx-blog-post.html | 4 ++-- blog/tags.html | 4 ++-- blog/tags/docusaurus.html | 4 ++-- blog/tags/facebook.html | 4 ++-- blog/tags/hello.html | 4 ++-- blog/tags/hola.html | 4 ++-- blog/welcome.html | 4 ++-- docs/build/api/grpc.html | 6 +++--- docs/build/api/jsonrpc.html | 6 +++--- docs/build/api/providers.html | 6 +++--- docs/build/hello-world-dapp.html | 6 +++--- docs/build/home.html | 6 +++--- docs/build/massa-web3.html | 13 ++++--------- docs/build/massa-web3/backend-usage-massa-web3.html | 6 +++--- docs/build/massa-web3/dapp-usage-massa-web3.html | 12 ++++++------ docs/build/massa-web3/massa-web3-utils.html | 6 +++--- docs/build/networks-faucets/local-network.html | 6 +++--- docs/build/networks-faucets/public-networks.html | 6 +++--- docs/build/smart-contract/intro.html | 6 +++--- docs/build/smart-contract/prerequisites.html | 6 +++--- docs/build/smart-contract/sdk.html | 6 +++--- docs/build/smart-contract/webassembly-module.html | 6 +++--- docs/build/standards.html | 6 +++--- docs/build/tooling-versions.html | 6 +++--- docs/build/wallet/community-wallets.html | 6 +++--- docs/build/wallet/intro.html | 6 +++--- docs/build/wallet/massa-wallet.html | 6 +++--- docs/build/wallet/wallet-provider.html | 6 +++--- docs/learn/architecture/basic-concepts.html | 6 +++--- docs/learn/architecture/consensus-quality.html | 6 +++--- docs/learn/architecture/node-architecture.html | 6 +++--- docs/learn/architecture/operation-lifecycle.html | 6 +++--- docs/learn/asc/intro.html | 6 +++--- docs/learn/asc/massa-asc.html | 6 +++--- docs/learn/asc/use-cases.html | 6 +++--- docs/learn/bootstrap.html | 6 +++--- docs/learn/decentralized-web.html | 6 +++--- docs/learn/gas.html | 6 +++--- docs/learn/home.html | 6 +++--- docs/learn/introduction.html | 6 +++--- docs/learn/operation-format-execution.html | 6 +++--- docs/learn/storage-costs.html | 6 +++--- docs/learn/tokenomics.html | 6 +++--- .../browse-decentralized-application.html | 6 +++--- docs/massaStation/faq.html | 6 +++--- docs/massaStation/guidelines.html | 6 +++--- docs/massaStation/hello-world-plugin.html | 6 +++--- docs/massaStation/home.html | 6 +++--- docs/massaStation/install.html | 6 +++--- docs/massaStation/manual-install.html | 6 +++--- docs/massaStation/massa-wallet/account-backup.html | 6 +++--- .../massaStation/massa-wallet/account-creation.html | 6 +++--- docs/massaStation/massa-wallet/account-restore.html | 6 +++--- .../massa-wallet/asset-monitoring-and-history.html | 6 +++--- docs/massaStation/massa-wallet/getting-started.html | 6 +++--- .../massa-wallet/transaction-management.html | 6 +++--- docs/massaStation/modules.html | 6 +++--- docs/massaStation/troubleshooting.html | 6 +++--- docs/massaStation/uninstall.html | 6 +++--- docs/node/all-configs.html | 6 +++--- docs/node/check_status.html | 6 +++--- docs/node/community-resources.html | 6 +++--- docs/node/faq.html | 6 +++--- docs/node/home.html | 6 +++--- docs/node/install.html | 6 +++--- docs/node/routability.html | 6 +++--- docs/node/run.html | 6 +++--- docs/node/stake.html | 6 +++--- docs/node/update.html | 6 +++--- docs/node/wallet.html | 6 +++--- docs/tutorial/home.html | 6 +++--- docs/tutorial/trading-bot.html | 6 +++--- index.html | 4 ++-- search.html | 4 ++-- 191 files changed, 293 insertions(+), 298 deletions(-) rename assets/js/{02918e2b.0ca8b141.js => 02918e2b.c3242b7d.js} (74%) create mode 100644 assets/js/0303d204.60644a50.js delete mode 100644 assets/js/0303d204.9ac17590.js delete mode 100644 assets/js/0512b022.3aaf600e.js create mode 100644 assets/js/0512b022.7edea0d5.js rename assets/js/{0734719f.e3287971.js => 0734719f.becb4c98.js} (75%) rename assets/js/{082a8033.c9e8936c.js => 082a8033.353e47a1.js} (58%) delete mode 100644 assets/js/10d3671b.1dd2d8a5.js create mode 100644 assets/js/10d3671b.aac0aec8.js rename assets/js/{13601854.fac1bb19.js => 13601854.8b81edd3.js} (57%) create mode 100644 assets/js/14161a26.690cf56f.js delete mode 100644 assets/js/14161a26.6b096048.js create mode 100644 assets/js/1d3e2afe.4d0ca5b8.js delete mode 100644 assets/js/1d3e2afe.ae7f2f1d.js delete mode 100644 assets/js/21529a4e.3994a2b5.js create mode 100644 assets/js/21529a4e.dccd2915.js create mode 100644 assets/js/233a18d6.6631165d.js delete mode 100644 assets/js/233a18d6.b65d48aa.js create mode 100644 assets/js/239c5dbf.4f55c85b.js delete mode 100644 assets/js/239c5dbf.d70b5a3f.js create mode 100644 assets/js/256be1ac.0319165e.js delete mode 100644 assets/js/256be1ac.a97c2cab.js create mode 100644 assets/js/2580cc57.5e752695.js delete mode 100644 assets/js/2580cc57.7351d524.js delete mode 100644 assets/js/28d23288.afed3aba.js create mode 100644 assets/js/28d23288.bfb73dae.js delete mode 100644 assets/js/28eb6811.45a8763e.js create mode 100644 assets/js/28eb6811.6b87d377.js delete mode 100644 assets/js/2e7e0665.787d2ced.js create mode 100644 assets/js/2e7e0665.fc80f398.js rename assets/js/{31043fb2.6b93b161.js => 31043fb2.e5aac349.js} (56%) create mode 100644 assets/js/330b5f37.1715192e.js delete mode 100644 assets/js/330b5f37.572c352d.js create mode 100644 assets/js/34fddb0a.308abfcc.js delete mode 100644 assets/js/34fddb0a.8a38eca2.js delete mode 100644 assets/js/383e51e1.911d7d6e.js create mode 100644 assets/js/383e51e1.bd681953.js create mode 100644 assets/js/3b5bba7a.466cf864.js delete mode 100644 assets/js/3b5bba7a.6d798214.js create mode 100644 assets/js/3e4cab72.060c45ba.js delete mode 100644 assets/js/3e4cab72.62a5425c.js delete mode 100644 assets/js/45c0e8c1.df809bd5.js create mode 100644 assets/js/45c0e8c1.f330b96d.js create mode 100644 assets/js/46afc4b0.636d48de.js delete mode 100644 assets/js/46afc4b0.c4c468c2.js create mode 100644 assets/js/47c2a5ff.29678642.js delete mode 100644 assets/js/47c2a5ff.fd92e495.js delete mode 100644 assets/js/533eedc9.2e3095c3.js create mode 100644 assets/js/533eedc9.fac6aeae.js delete mode 100644 assets/js/59fee8c2.226f36a1.js create mode 100644 assets/js/59fee8c2.fd0f9413.js rename assets/js/{5ec7f8bd.2767532a.js => 5ec7f8bd.548303dc.js} (81%) delete mode 100644 assets/js/60246af2.8bbe4530.js create mode 100644 assets/js/60246af2.ec91afad.js rename assets/js/{65a48c1c.3c754403.js => 65a48c1c.49928ef0.js} (53%) rename assets/js/{68a358ec.28a5c862.js => 68a358ec.325eea62.js} (63%) delete mode 100644 assets/js/6900ad03.21057a29.js create mode 100644 assets/js/6900ad03.aa8206c0.js delete mode 100644 assets/js/6ed436f8.8b9b076e.js create mode 100644 assets/js/6ed436f8.d46943c5.js rename assets/js/{717b6d43.5cab6579.js => 717b6d43.8a9278ff.js} (53%) rename assets/js/{786c2353.0a80bef8.js => 786c2353.a56dc889.js} (67%) rename assets/js/{81356911.0ed7f2f9.js => 81356911.c10d9a68.js} (67%) create mode 100644 assets/js/86001517.0e282e74.js delete mode 100644 assets/js/86001517.953457f4.js create mode 100644 assets/js/96daec60.0cb8247a.js delete mode 100644 assets/js/96daec60.955a220e.js create mode 100644 assets/js/aae87ff3.62bbca3a.js delete mode 100644 assets/js/aae87ff3.e4bdb9e2.js create mode 100644 assets/js/ae42d3c5.341e5f02.js delete mode 100644 assets/js/ae42d3c5.49edffb7.js rename assets/js/{af6fbf3d.1aa6f226.js => af6fbf3d.2b5f9048.js} (61%) create mode 100644 assets/js/afc6f80d.06b96232.js delete mode 100644 assets/js/afc6f80d.b9fbe904.js delete mode 100644 assets/js/b0e553de.c4ef4ba8.js create mode 100644 assets/js/b0e553de.ce4bda73.js create mode 100644 assets/js/b564223c.81e18ea4.js delete mode 100644 assets/js/b564223c.99e8aad5.js create mode 100644 assets/js/ba31b44f.9a000ef9.js delete mode 100644 assets/js/ba31b44f.dc992478.js create mode 100644 assets/js/bbd40d9c.075b8ace.js delete mode 100644 assets/js/bbd40d9c.631613cb.js create mode 100644 assets/js/bc47a922.08a112ed.js delete mode 100644 assets/js/bc47a922.b377557f.js delete mode 100644 assets/js/c332032b.96c3e559.js create mode 100644 assets/js/c332032b.9f002d0e.js delete mode 100644 assets/js/c59c9eb2.1a1a153d.js create mode 100644 assets/js/c59c9eb2.d8d79186.js rename assets/js/{cab0926f.a2384583.js => cab0926f.5771f764.js} (55%) rename assets/js/{cc31dfa8.3579740f.js => cc31dfa8.5468af17.js} (67%) rename assets/js/{d9062d8c.9afee93b.js => d9062d8c.298779ed.js} (91%) rename assets/js/{dba7919e.aba4f578.js => dba7919e.629e0f1f.js} (63%) delete mode 100644 assets/js/dbc90ee5.4d6e339b.js create mode 100644 assets/js/dbc90ee5.f96089a3.js delete mode 100644 assets/js/ded851bf.076fe68c.js create mode 100644 assets/js/ded851bf.62b54c52.js create mode 100644 assets/js/e56aa218.4da5957a.js delete mode 100644 assets/js/e56aa218.a946a3e9.js create mode 100644 assets/js/e58c5506.2d3a81c2.js delete mode 100644 assets/js/e58c5506.c79e777d.js delete mode 100644 assets/js/e7d3f44b.17f7c68c.js create mode 100644 assets/js/e7d3f44b.1a9fb41d.js delete mode 100644 assets/js/eae7922f.1de17331.js create mode 100644 assets/js/eae7922f.88adf2af.js delete mode 100644 assets/js/f27bf80f.9866de5c.js create mode 100644 assets/js/f27bf80f.e91497b2.js rename assets/js/{f4993782.9c401e51.js => f4993782.a288acc3.js} (75%) rename assets/js/{f5aa9287.91e92931.js => f5aa9287.a86e16b3.js} (58%) rename assets/js/{fae30412.ece11059.js => fae30412.ab27e23f.js} (74%) create mode 100644 assets/js/fb34ae5b.0dd9a780.js delete mode 100644 assets/js/fb34ae5b.b1a550d1.js rename assets/js/{runtime~main.4a8cfd9a.js => runtime~main.55ca36c1.js} (78%) diff --git a/404.html b/404.html index ffdcdee2b..db746f81f 100644 --- a/404.html +++ b/404.html @@ -10,13 +10,13 @@ - +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- + \ No newline at end of file diff --git a/assets/js/02918e2b.0ca8b141.js b/assets/js/02918e2b.c3242b7d.js similarity index 74% rename from assets/js/02918e2b.0ca8b141.js rename to assets/js/02918e2b.c3242b7d.js index 54cd9993e..cf86bac2b 100644 --- a/assets/js/02918e2b.0ca8b141.js +++ b/assets/js/02918e2b.c3242b7d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[6676],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>f});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function o(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var i=r.createContext({}),c=function(e){var t=r.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},u=function(e){var t=c(e.components);return r.createElement(i.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,l=e.originalType,i=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(a),m=n,f=p["".concat(i,".").concat(m)]||p[m]||d[m]||l;return a?r.createElement(f,o(o({ref:t},u),{},{components:a})):r.createElement(f,o({ref:t},u))}));function f(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var l=a.length,o=new Array(l);o[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[p]="string"==typeof e?e:n,o[1]=s;for(var c=2;c{a.r(t),a.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>l,metadata:()=>s,toc:()=>c});var r=a(7462),n=(a(7294),a(3905));const l={id:"massa-wallet",title:"Massa Wallet"},o="Massa Wallet",s={unversionedId:"build/wallet/massa-wallet",id:"build/wallet/massa-wallet",title:"Massa Wallet",description:"Massa Wallet is a plugin for Massa Station that allows you to",source:"@site/docs/build/wallet/massa-station.mdx",sourceDirName:"build/wallet",slug:"/build/wallet/massa-wallet",permalink:"/docs/build/wallet/massa-wallet",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/wallet/massa-station.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"massa-wallet",title:"Massa Wallet"},sidebar:"buildSidebar",previous:{title:"Introduction",permalink:"/docs/build/wallet/intro"},next:{title:"Wallet Provider",permalink:"/docs/build/wallet/wallet-provider"}},i={},c=[],u={toc:c},p="wrapper";function d(e){let{components:t,...a}=e;return(0,n.kt)(p,(0,r.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"massa-wallet"},"Massa Wallet"),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://github.com/massalabs/station-massa-wallet"},"Massa Wallet")," is a plugin for Massa Station that allows you to\nstore your assets and interact with decentralized applications. It is the recommended way to interact with the Massa blockchain."),(0,n.kt)("p",null,"Follow the link to ",(0,n.kt)("a",{parentName:"p",href:"/docs/massaStation/massa-wallet/getting-started"},"get started with Massa Wallet")," !"))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[6676],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>f});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function o(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var i=r.createContext({}),c=function(e){var t=r.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},u=function(e){var t=c(e.components);return r.createElement(i.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,l=e.originalType,i=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=c(a),m=n,f=p["".concat(i,".").concat(m)]||p[m]||d[m]||l;return a?r.createElement(f,o(o({ref:t},u),{},{components:a})):r.createElement(f,o({ref:t},u))}));function f(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var l=a.length,o=new Array(l);o[0]=m;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[p]="string"==typeof e?e:n,o[1]=s;for(var c=2;c{a.r(t),a.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>l,metadata:()=>s,toc:()=>c});var r=a(7462),n=(a(7294),a(3905));const l={id:"massa-wallet",title:"Massa Wallet"},o="Massa Wallet",s={unversionedId:"build/wallet/massa-wallet",id:"build/wallet/massa-wallet",title:"Massa Wallet",description:"Massa Wallet is a plugin for Massa Station that allows you to",source:"@site/docs/build/wallet/massa-station.mdx",sourceDirName:"build/wallet",slug:"/build/wallet/massa-wallet",permalink:"/docs/build/wallet/massa-wallet",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/wallet/massa-station.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"massa-wallet",title:"Massa Wallet"},sidebar:"buildSidebar",previous:{title:"Introduction",permalink:"/docs/build/wallet/intro"},next:{title:"Wallet Provider",permalink:"/docs/build/wallet/wallet-provider"}},i={},c=[],u={toc:c},p="wrapper";function d(e){let{components:t,...a}=e;return(0,n.kt)(p,(0,r.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"massa-wallet"},"Massa Wallet"),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://github.com/massalabs/station-massa-wallet"},"Massa Wallet")," is a plugin for Massa Station that allows you to\nstore your assets and interact with decentralized applications. It is the recommended way to interact with the Massa blockchain."),(0,n.kt)("p",null,"Follow the link to ",(0,n.kt)("a",{parentName:"p",href:"/docs/massaStation/massa-wallet/getting-started"},"get started with Massa Wallet")," !"))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0303d204.60644a50.js b/assets/js/0303d204.60644a50.js new file mode 100644 index 000000000..d4b71f6fe --- /dev/null +++ b/assets/js/0303d204.60644a50.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[4173],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>m});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function s(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,s=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),p=c(a),h=r,m=p["".concat(l,".").concat(h)]||p[h]||u[h]||s;return a?n.createElement(m,o(o({ref:t},d),{},{components:a})):n.createElement(m,o({ref:t},d))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=a.length,o=new Array(s);o[0]=h;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:r,o[1]=i;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var n=a(7462),r=(a(7294),a(3905));const s={id:"decentralized-web",sidebar_label:"Decentralized Web"},o="Decentralized Web",i={unversionedId:"learn/decentralized-web",id:"learn/decentralized-web",title:"Decentralized Web",description:"The code is law rule is a cornerstone of DeFi. It states among other things that once successfully audited, a",source:"@site/docs/learn/decentralized-web.mdx",sourceDirName:"learn",slug:"/learn/decentralized-web",permalink:"/docs/learn/decentralized-web",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/learn/decentralized-web.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"decentralized-web",sidebar_label:"Decentralized Web"},sidebar:"learnSidebar",previous:{title:"Use-cases",permalink:"/docs/learn/asc/use-cases"}},l={},c=[{value:"Massa Station",id:"massa-station",level:2}],d={toc:c},p="wrapper";function u(e){let{components:t,...a}=e;return(0,r.kt)(p,(0,n.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"decentralized-web"},"Decentralized Web"),(0,r.kt)("p",null,"The ",(0,r.kt)("em",{parentName:"p"},"code is law")," rule is a cornerstone of DeFi. It states among other things that once successfully audited, a\nprogram can remain trusted. This implies that the program of a successfully audited smart contract may never be\nunexpectedly changed by an outsider. Popular ETH smart contracts essentially follow that rule."),(0,r.kt)("p",null,"However, most DeFi web3 apps such as ",(0,r.kt)("a",{parentName:"p",href:"https://app.uniswap.org/"},"app.uniswap.org")," are typically used through an\notherwise normal website that talks to a browser plugin (typically\n",(0,r.kt)("a",{parentName:"p",href:"https://github.com/MetaMask/metamask-extension"},"Metamask"),") allowing the webpage to interact with the user's wallet\nand the blockchain. The website that serves as an entry point to the dApp is neither decentralized nor\nimmutable-once-audited. This breaks the very foundation of blockchain security."),(0,r.kt)("p",null,"This attack vector has been well identified by exploiters and, as smart contracts become more robust, exploiters are\nincreasingly targeting front ends. For instance, in 2022, one of the major DeFi protocols,\n",(0,r.kt)("a",{parentName:"p",href:"https://curve.fi/"},"Curve Finance"),", fell victim to ",(0,r.kt)("a",{parentName:"p",href:"https://rekt.news/curve-finance-rekt/"},"DNS hijacking"),",\nwith hackers managing to steal as much as $575k from users.\nAs long as decentralized applications rely on Web 2.0 infrastructure, these attacks are bound to happen\n",(0,r.kt)("a",{parentName:"p",href:"https://twitter.com/LefterisJP/status/1540306236087877635"},"regularly"),"."),(0,r.kt)("h2",{id:"massa-station"},"Massa Station"),(0,r.kt)("p",null,"The goal of Massa's decentralized web is to allow users to store websites without using any centralized party in between\nyour client and the blockchain. Since the front-end is hosted on the blockchain, anyone can access it using a Massa\nnode."),(0,r.kt)("p",null,"To this end Massa has developed a client that acts as a gateway to the blockchain preventing you from using any\ncentralized servers effectively maximizing your security with immutable and censorship-resistant websites.\nThat way, Massa allows deploying fully decentralized code-is-law apps, as it was meant to be!"),(0,r.kt)("p",null,"Start your decentralized web3 journey now, and install ",(0,r.kt)("a",{parentName:"p",href:"https://station.massa.net"},(0,r.kt)("strong",{parentName:"a"},"Massa Station")),".\nMassa Station allows you to navigate Massa web3 content and to store your own website."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Note that you would typically not host all assets, images and other non-essential data on-chain, but only the\ncritical functioning parts that need auditing and the subsequent security guarantees. The rest can typically be hosted\non IPFS or some other decentralized storage solution.")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0303d204.9ac17590.js b/assets/js/0303d204.9ac17590.js deleted file mode 100644 index 6d949d433..000000000 --- a/assets/js/0303d204.9ac17590.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[4173],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>m});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function s(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,s=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),p=c(a),h=r,m=p["".concat(l,".").concat(h)]||p[h]||u[h]||s;return a?n.createElement(m,o(o({ref:t},d),{},{components:a})):n.createElement(m,o({ref:t},d))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=a.length,o=new Array(s);o[0]=h;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:r,o[1]=i;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var n=a(7462),r=(a(7294),a(3905));const s={id:"decentralized-web",sidebar_label:"Decentralized Web"},o="Decentralized Web",i={unversionedId:"learn/decentralized-web",id:"learn/decentralized-web",title:"Decentralized Web",description:"The code is law rule is a cornerstone of DeFi. It states among other things that once successfully audited, a",source:"@site/docs/learn/decentralized-web.mdx",sourceDirName:"learn",slug:"/learn/decentralized-web",permalink:"/docs/learn/decentralized-web",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/learn/decentralized-web.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"decentralized-web",sidebar_label:"Decentralized Web"},sidebar:"learnSidebar",previous:{title:"Use-cases",permalink:"/docs/learn/asc/use-cases"}},l={},c=[{value:"Massa Station",id:"massa-station",level:2}],d={toc:c},p="wrapper";function u(e){let{components:t,...a}=e;return(0,r.kt)(p,(0,n.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"decentralized-web"},"Decentralized Web"),(0,r.kt)("p",null,"The ",(0,r.kt)("em",{parentName:"p"},"code is law")," rule is a cornerstone of DeFi. It states among other things that once successfully audited, a\nprogram can remain trusted. This implies that the program of a successfully audited smart contract may never be\nunexpectedly changed by an outsider. Popular ETH smart contracts essentially follow that rule."),(0,r.kt)("p",null,"However, most DeFi web3 apps such as ",(0,r.kt)("a",{parentName:"p",href:"https://app.uniswap.org/"},"app.uniswap.org")," are typically used through an\notherwise normal website that talks to a browser plugin (typically\n",(0,r.kt)("a",{parentName:"p",href:"https://github.com/MetaMask/metamask-extension"},"Metamask"),") allowing the webpage to interact with the user's wallet\nand the blockchain. The website that serves as an entry point to the dApp is neither decentralized nor\nimmutable-once-audited. This breaks the very foundation of blockchain security."),(0,r.kt)("p",null,"This attack vector has been well identified by exploiters and, as smart contracts become more robust, exploiters are\nincreasingly targeting front ends. For instance, in 2022, one of the major DeFi protocols,\n",(0,r.kt)("a",{parentName:"p",href:"https://curve.fi/"},"Curve Finance"),", fell victim to ",(0,r.kt)("a",{parentName:"p",href:"https://rekt.news/curve-finance-rekt/"},"DNS hijacking"),",\nwith hackers managing to steal as much as $575k from users.\nAs long as decentralized applications rely on Web 2.0 infrastructure, these attacks are bound to happen\n",(0,r.kt)("a",{parentName:"p",href:"https://twitter.com/LefterisJP/status/1540306236087877635"},"regularly"),"."),(0,r.kt)("h2",{id:"massa-station"},"Massa Station"),(0,r.kt)("p",null,"The goal of Massa's decentralized web is to allow users to store websites without using any centralized party in between\nyour client and the blockchain. Since the front-end is hosted on the blockchain, anyone can access it using a Massa\nnode."),(0,r.kt)("p",null,"To this end Massa has developed a client that acts as a gateway to the blockchain preventing you from using any\ncentralized servers effectively maximizing your security with immutable and censorship-resistant websites.\nThat way, Massa allows deploying fully decentralized code-is-law apps, as it was meant to be!"),(0,r.kt)("p",null,"Start your decentralized web3 journey now, and install ",(0,r.kt)("a",{parentName:"p",href:"https://station.massa.net"},(0,r.kt)("strong",{parentName:"a"},"Massa Station")),".\nMassa Station allows you to navigate Massa web3 content and to store your own website."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Note that you would typically not host all assets, images and other non-essential data on-chain, but only the\ncritical functioning parts that need auditing and the subsequent security guarantees. The rest can typically be hosted\non IPFS or some other decentralized storage solution.")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0512b022.3aaf600e.js b/assets/js/0512b022.3aaf600e.js deleted file mode 100644 index 4d0b7f688..000000000 --- a/assets/js/0512b022.3aaf600e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[1290],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>h});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),i=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},d=function(e){var t=i(e.components);return n.createElement(u.Provider,{value:t},e.children)},l="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,u=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),l=i(r),y=o,h=l["".concat(u,".").concat(y)]||l[y]||p[y]||a;return r?n.createElement(h,c(c({ref:t},d),{},{components:r})):n.createElement(h,c({ref:t},d))}));function h(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,c=new Array(a);c[0]=y;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[l]="string"==typeof e?e:o,c[1]=s;for(var i=2;i{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>c,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>i});var n=r(7462),o=(r(7294),r(3905));const a={id:"check_status",sidebar_label:"Check your node's status"},c="Check your node's status",s={unversionedId:"node/check_status",id:"node/check_status",title:"Check your node's status",description:"Check your routability status",source:"@site/docs/node/check_status.mdx",sourceDirName:"node",slug:"/node/check_status",permalink:"/docs/node/check_status",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/node/check_status.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"check_status",sidebar_label:"Check your node's status"},sidebar:"nodeSidebar",previous:{title:"Staking",permalink:"/docs/node/stake"},next:{title:"Node and client configuration",permalink:"/docs/node/all-configs"}},u={},i=[{value:"Check your routability status",id:"check-your-routability-status",level:2},{value:"Make sure you are connected to peers",id:"make-sure-you-are-connected-to-peers",level:2}],d={toc:i},l="wrapper";function p(e){let{components:t,...r}=e;return(0,o.kt)(l,(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"check-your-nodes-status"},"Check your node's status"),(0,o.kt)("h2",{id:"check-your-routability-status"},"Check your routability status"),(0,o.kt)("p",null,"You can use a service such as ",(0,o.kt)("a",{parentName:"p",href:"https://portchecker.co"},"https://portchecker.co")," to check that the ports 31244 and 31245 are both opened for your public IP address."),(0,o.kt)("p",null,"Additionally, in your massa-client, you can check that the ",(0,o.kt)("inlineCode",{parentName:"p"},"get_status")," command shows your ",(0,o.kt)("inlineCode",{parentName:"p"},"Node's IP: "),".\nIf it shows ",(0,o.kt)("inlineCode",{parentName:"p"},"No routable IP set")," instead, please check again your configuration."),(0,o.kt)("h2",{id:"make-sure-you-are-connected-to-peers"},"Make sure you are connected to peers"),(0,o.kt)("p",null,"In order for your node to be running properly, you have to make sure you are connected to other peers on the network."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"get_status")," command will show you which nodes you are connected too.\nYou need to have both IN and OUT connections."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0512b022.7edea0d5.js b/assets/js/0512b022.7edea0d5.js new file mode 100644 index 000000000..2a8aa23fd --- /dev/null +++ b/assets/js/0512b022.7edea0d5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[1290],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>h});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var u=n.createContext({}),i=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},l=function(e){var t=i(e.components);return n.createElement(u.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},y=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,u=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),d=i(r),y=o,h=d["".concat(u,".").concat(y)]||d[y]||p[y]||a;return r?n.createElement(h,c(c({ref:t},l),{},{components:r})):n.createElement(h,c({ref:t},l))}));function h(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,c=new Array(a);c[0]=y;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[d]="string"==typeof e?e:o,c[1]=s;for(var i=2;i{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>c,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>i});var n=r(7462),o=(r(7294),r(3905));const a={id:"check_status",sidebar_label:"Check your node's status"},c="Check your node's status",s={unversionedId:"node/check_status",id:"node/check_status",title:"Check your node's status",description:"Check your routability status",source:"@site/docs/node/check_status.mdx",sourceDirName:"node",slug:"/node/check_status",permalink:"/docs/node/check_status",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/node/check_status.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"check_status",sidebar_label:"Check your node's status"},sidebar:"nodeSidebar",previous:{title:"Staking",permalink:"/docs/node/stake"},next:{title:"Node and client configuration",permalink:"/docs/node/all-configs"}},u={},i=[{value:"Check your routability status",id:"check-your-routability-status",level:2},{value:"Make sure you are connected to peers",id:"make-sure-you-are-connected-to-peers",level:2}],l={toc:i},d="wrapper";function p(e){let{components:t,...r}=e;return(0,o.kt)(d,(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"check-your-nodes-status"},"Check your node's status"),(0,o.kt)("h2",{id:"check-your-routability-status"},"Check your routability status"),(0,o.kt)("p",null,"You can use a service such as ",(0,o.kt)("a",{parentName:"p",href:"https://portchecker.co"},"https://portchecker.co")," to check that the ports 31244 and 31245 are both opened for your public IP address."),(0,o.kt)("p",null,"Additionally, in your massa-client, you can check that the ",(0,o.kt)("inlineCode",{parentName:"p"},"get_status")," command shows your ",(0,o.kt)("inlineCode",{parentName:"p"},"Node's IP: "),".\nIf it shows ",(0,o.kt)("inlineCode",{parentName:"p"},"No routable IP set")," instead, please check again your configuration."),(0,o.kt)("h2",{id:"make-sure-you-are-connected-to-peers"},"Make sure you are connected to peers"),(0,o.kt)("p",null,"In order for your node to be running properly, you have to make sure you are connected to other peers on the network."),(0,o.kt)("p",null,"The ",(0,o.kt)("inlineCode",{parentName:"p"},"get_status")," command will show you which nodes you are connected too.\nYou need to have both IN and OUT connections."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0734719f.e3287971.js b/assets/js/0734719f.becb4c98.js similarity index 75% rename from assets/js/0734719f.e3287971.js rename to assets/js/0734719f.becb4c98.js index b4d7237a4..58f6d9433 100644 --- a/assets/js/0734719f.e3287971.js +++ b/assets/js/0734719f.becb4c98.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[3594],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),i=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},c=function(e){var t=i(e.components);return n.createElement(s.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},b=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,s=e.parentName,c=u(e,["components","mdxType","originalType","parentName"]),d=i(r),b=a,f=d["".concat(s,".").concat(b)]||d[b]||p[b]||l;return r?n.createElement(f,o(o({ref:t},c),{},{components:r})):n.createElement(f,o({ref:t},c))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=b;var u={};for(var s in t)hasOwnProperty.call(t,s)&&(u[s]=t[s]);u.originalType=e,u[d]="string"==typeof e?e:a,o[1]=u;for(var i=2;i{r.d(t,{Z:()=>o});var n=r(7294),a=r(6010);const l={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:r,className:o}=e;return n.createElement("div",{role:"tabpanel",className:(0,a.Z)(l.tabItem,o),hidden:r},t)}},4866:(e,t,r)=>{r.d(t,{Z:()=>w});var n=r(7462),a=r(7294),l=r(6010),o=r(2466),u=r(6550),s=r(1980),i=r(7392),c=r(12);function d(e){return function(e){return a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:t,label:r,attributes:n,default:a}}=e;return{value:t,label:r,attributes:n,default:a}}))}function p(e){const{values:t,children:r}=e;return(0,a.useMemo)((()=>{const e=t??d(r);return function(e){const t=(0,i.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,r])}function b(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:r}=e;const n=(0,u.k6)(),l=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:t,groupId:r});return[(0,s._X)(l),(0,a.useCallback)((e=>{if(!l)return;const t=new URLSearchParams(n.location.search);t.set(l,e),n.replace({...n.location,search:t.toString()})}),[l,n])]}function m(e){const{defaultValue:t,queryString:r=!1,groupId:n}=e,l=p(e),[o,u]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!b({value:t,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=r.find((e=>e.default))??r[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:l}))),[s,i]=f({queryString:r,groupId:n}),[d,m]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,l]=(0,c.Nk)(r);return[n,(0,a.useCallback)((e=>{r&&l.set(e)}),[r,l])]}({groupId:n}),v=(()=>{const e=s??d;return b({value:e,tabValues:l})?e:null})();(0,a.useLayoutEffect)((()=>{v&&u(v)}),[v]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!b({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);u(e),i(e),m(e)}),[i,m,l]),tabValues:l}}var v=r(2389);const h={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:r,selectedValue:u,selectValue:s,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,o.o5)(),p=e=>{const t=e.currentTarget,r=c.indexOf(t),n=i[r].value;n!==u&&(d(t),s(n))},b=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const r=c.indexOf(e.currentTarget)+1;t=c[r]??c[0];break}case"ArrowLeft":{const r=c.indexOf(e.currentTarget)-1;t=c[r]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":r},t)},i.map((e=>{let{value:t,label:r,attributes:o}=e;return a.createElement("li",(0,n.Z)({role:"tab",tabIndex:u===t?0:-1,"aria-selected":u===t,key:t,ref:e=>c.push(e),onKeyDown:b,onClick:p},o,{className:(0,l.Z)("tabs__item",h.tabItem,o?.className,{"tabs__item--active":u===t})}),r??t)})))}function y(e){let{lazy:t,children:r,selectedValue:n}=e;const l=(Array.isArray(r)?r:[r]).filter(Boolean);if(t){const e=l.find((e=>e.props.value===n));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},l.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function g(e){const t=m(e);return a.createElement("div",{className:(0,l.Z)("tabs-container",h.tabList)},a.createElement(k,(0,n.Z)({},e,t)),a.createElement(y,(0,n.Z)({},e,t)))}function w(e){const t=(0,v.Z)();return a.createElement(g,(0,n.Z)({key:String(t)},e))}},3827:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>f,frontMatter:()=>u,metadata:()=>i,toc:()=>d});var n=r(7462),a=(r(7294),r(3905)),l=r(4866),o=r(5162);const u={id:"providers",sidebar_label:"Providers"},s="RPC Providers",i={unversionedId:"build/api/providers",id:"build/api/providers",title:"RPC Providers",description:"To interact with the different networks of the Massa blockchain, you can select from any of the listed providers.",source:"@site/docs/build/api/providers.mdx",sourceDirName:"build/api",slug:"/build/api/providers",permalink:"/docs/build/api/providers",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/api/providers.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"providers",sidebar_label:"Providers"},sidebar:"buildSidebar",previous:{title:"Tooling Versions",permalink:"/docs/build/tooling-versions"},next:{title:"JsonRPC",permalink:"/docs/build/api/jsonrpc"}},c={},d=[],p={toc:d},b="wrapper";function f(e){let{components:t,...r}=e;return(0,a.kt)(b,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"rpc-providers"},"RPC Providers"),(0,a.kt)("p",null,"To interact with the different networks of the Massa blockchain, you can select from any of the listed providers.\nBe aware that the latency you encounter may vary depending on the provider's geographical location.\nTo enhance redundancy and facilitate load balancing, consider using multiple providers."),(0,a.kt)(l.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{value:"mainnet",label:"\ud83d\udda5 MainNet",default:!0,mdxType:"TabItem"},(0,a.kt)("table",null,(0,a.kt)("thead",null,(0,a.kt)("tr",null,(0,a.kt)("th",null,"Provider"),(0,a.kt)("th",null,"Protocol"),(0,a.kt)("th",null,"Endpoint URL"))),(0,a.kt)("tbody",null,(0,a.kt)("tr",null,(0,a.kt)("td",null,(0,a.kt)("a",{href:"/docs/build/networks-faucets/public-networks"},"Massa Labs")),(0,a.kt)("td",null,(0,a.kt)("code",null,"JsonRPC")),(0,a.kt)("td",null,(0,a.kt)("code",null,"https://mainnet.massa.net/api/v2"))),(0,a.kt)("tr",null,(0,a.kt)("td",null,(0,a.kt)("a",{href:"/docs/build/networks-faucets/public-networks"},"Massa Labs")),(0,a.kt)("td",null,(0,a.kt)("code",null,"gRPC")),(0,a.kt)("td",null,(0,a.kt)("code",null,"grpc://mainnet.massa.net:33037")))))),(0,a.kt)(o.Z,{value:"buildnet",label:"\ud83d\udc77 BuildNet",default:!0,mdxType:"TabItem"},(0,a.kt)("table",null,(0,a.kt)("thead",null,(0,a.kt)("tr",null,(0,a.kt)("th",null,"Provider"),(0,a.kt)("th",null,"Protocol"),(0,a.kt)("th",null,"Endpoint URL"))),(0,a.kt)("tbody",null,(0,a.kt)("tr",null,(0,a.kt)("td",null,(0,a.kt)("a",{href:"/docs/build/networks-faucets/public-networks"},"Massa Labs")),(0,a.kt)("td",null,(0,a.kt)("code",null,"JsonRPC")),(0,a.kt)("td",null,(0,a.kt)("code",null,"https://buildnet.massa.net/api/v2"))),(0,a.kt)("tr",null,(0,a.kt)("td",null,(0,a.kt)("a",{href:"/docs/build/networks-faucets/public-networks"},"Massa Labs")),(0,a.kt)("td",null,(0,a.kt)("code",null,"gRPC")),(0,a.kt)("td",null,(0,a.kt)("code",null,"grpc://buildnet.massa.net:33037"))))))))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[3594],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),i=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},c=function(e){var t=i(e.components);return n.createElement(s.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},b=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,s=e.parentName,c=u(e,["components","mdxType","originalType","parentName"]),d=i(r),b=a,f=d["".concat(s,".").concat(b)]||d[b]||p[b]||l;return r?n.createElement(f,o(o({ref:t},c),{},{components:r})):n.createElement(f,o({ref:t},c))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=b;var u={};for(var s in t)hasOwnProperty.call(t,s)&&(u[s]=t[s]);u.originalType=e,u[d]="string"==typeof e?e:a,o[1]=u;for(var i=2;i{r.d(t,{Z:()=>o});var n=r(7294),a=r(6010);const l={tabItem:"tabItem_Ymn6"};function o(e){let{children:t,hidden:r,className:o}=e;return n.createElement("div",{role:"tabpanel",className:(0,a.Z)(l.tabItem,o),hidden:r},t)}},4866:(e,t,r)=>{r.d(t,{Z:()=>w});var n=r(7462),a=r(7294),l=r(6010),o=r(2466),u=r(6550),s=r(1980),i=r(7392),c=r(12);function d(e){return function(e){return a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:t,label:r,attributes:n,default:a}}=e;return{value:t,label:r,attributes:n,default:a}}))}function p(e){const{values:t,children:r}=e;return(0,a.useMemo)((()=>{const e=t??d(r);return function(e){const t=(0,i.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,r])}function b(e){let{value:t,tabValues:r}=e;return r.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:r}=e;const n=(0,u.k6)(),l=function(e){let{queryString:t=!1,groupId:r}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!r)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:t,groupId:r});return[(0,s._X)(l),(0,a.useCallback)((e=>{if(!l)return;const t=new URLSearchParams(n.location.search);t.set(l,e),n.replace({...n.location,search:t.toString()})}),[l,n])]}function m(e){const{defaultValue:t,queryString:r=!1,groupId:n}=e,l=p(e),[o,u]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!b({value:t,tabValues:r}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=r.find((e=>e.default))??r[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:l}))),[s,i]=f({queryString:r,groupId:n}),[d,m]=function(e){let{groupId:t}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,l]=(0,c.Nk)(r);return[n,(0,a.useCallback)((e=>{r&&l.set(e)}),[r,l])]}({groupId:n}),v=(()=>{const e=s??d;return b({value:e,tabValues:l})?e:null})();(0,a.useLayoutEffect)((()=>{v&&u(v)}),[v]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!b({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);u(e),i(e),m(e)}),[i,m,l]),tabValues:l}}var v=r(2389);const h={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function k(e){let{className:t,block:r,selectedValue:u,selectValue:s,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:d}=(0,o.o5)(),p=e=>{const t=e.currentTarget,r=c.indexOf(t),n=i[r].value;n!==u&&(d(t),s(n))},b=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const r=c.indexOf(e.currentTarget)+1;t=c[r]??c[0];break}case"ArrowLeft":{const r=c.indexOf(e.currentTarget)-1;t=c[r]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":r},t)},i.map((e=>{let{value:t,label:r,attributes:o}=e;return a.createElement("li",(0,n.Z)({role:"tab",tabIndex:u===t?0:-1,"aria-selected":u===t,key:t,ref:e=>c.push(e),onKeyDown:b,onClick:p},o,{className:(0,l.Z)("tabs__item",h.tabItem,o?.className,{"tabs__item--active":u===t})}),r??t)})))}function y(e){let{lazy:t,children:r,selectedValue:n}=e;const l=(Array.isArray(r)?r:[r]).filter(Boolean);if(t){const e=l.find((e=>e.props.value===n));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},l.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function g(e){const t=m(e);return a.createElement("div",{className:(0,l.Z)("tabs-container",h.tabList)},a.createElement(k,(0,n.Z)({},e,t)),a.createElement(y,(0,n.Z)({},e,t)))}function w(e){const t=(0,v.Z)();return a.createElement(g,(0,n.Z)({key:String(t)},e))}},3827:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>f,frontMatter:()=>u,metadata:()=>i,toc:()=>d});var n=r(7462),a=(r(7294),r(3905)),l=r(4866),o=r(5162);const u={id:"providers",sidebar_label:"Providers"},s="RPC Providers",i={unversionedId:"build/api/providers",id:"build/api/providers",title:"RPC Providers",description:"To interact with the different networks of the Massa blockchain, you can select from any of the listed providers.",source:"@site/docs/build/api/providers.mdx",sourceDirName:"build/api",slug:"/build/api/providers",permalink:"/docs/build/api/providers",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/api/providers.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"providers",sidebar_label:"Providers"},sidebar:"buildSidebar",previous:{title:"Tooling Versions",permalink:"/docs/build/tooling-versions"},next:{title:"JsonRPC",permalink:"/docs/build/api/jsonrpc"}},c={},d=[],p={toc:d},b="wrapper";function f(e){let{components:t,...r}=e;return(0,a.kt)(b,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"rpc-providers"},"RPC Providers"),(0,a.kt)("p",null,"To interact with the different networks of the Massa blockchain, you can select from any of the listed providers.\nBe aware that the latency you encounter may vary depending on the provider's geographical location.\nTo enhance redundancy and facilitate load balancing, consider using multiple providers."),(0,a.kt)(l.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{value:"mainnet",label:"\ud83d\udda5 MainNet",default:!0,mdxType:"TabItem"},(0,a.kt)("table",null,(0,a.kt)("thead",null,(0,a.kt)("tr",null,(0,a.kt)("th",null,"Provider"),(0,a.kt)("th",null,"Protocol"),(0,a.kt)("th",null,"Endpoint URL"))),(0,a.kt)("tbody",null,(0,a.kt)("tr",null,(0,a.kt)("td",null,(0,a.kt)("a",{href:"/docs/build/networks-faucets/public-networks"},"Massa Labs")),(0,a.kt)("td",null,(0,a.kt)("code",null,"JsonRPC")),(0,a.kt)("td",null,(0,a.kt)("code",null,"https://mainnet.massa.net/api/v2"))),(0,a.kt)("tr",null,(0,a.kt)("td",null,(0,a.kt)("a",{href:"/docs/build/networks-faucets/public-networks"},"Massa Labs")),(0,a.kt)("td",null,(0,a.kt)("code",null,"gRPC")),(0,a.kt)("td",null,(0,a.kt)("code",null,"grpc://mainnet.massa.net:33037")))))),(0,a.kt)(o.Z,{value:"buildnet",label:"\ud83d\udc77 BuildNet",default:!0,mdxType:"TabItem"},(0,a.kt)("table",null,(0,a.kt)("thead",null,(0,a.kt)("tr",null,(0,a.kt)("th",null,"Provider"),(0,a.kt)("th",null,"Protocol"),(0,a.kt)("th",null,"Endpoint URL"))),(0,a.kt)("tbody",null,(0,a.kt)("tr",null,(0,a.kt)("td",null,(0,a.kt)("a",{href:"/docs/build/networks-faucets/public-networks"},"Massa Labs")),(0,a.kt)("td",null,(0,a.kt)("code",null,"JsonRPC")),(0,a.kt)("td",null,(0,a.kt)("code",null,"https://buildnet.massa.net/api/v2"))),(0,a.kt)("tr",null,(0,a.kt)("td",null,(0,a.kt)("a",{href:"/docs/build/networks-faucets/public-networks"},"Massa Labs")),(0,a.kt)("td",null,(0,a.kt)("code",null,"gRPC")),(0,a.kt)("td",null,(0,a.kt)("code",null,"grpc://buildnet.massa.net:33037"))))))))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/082a8033.c9e8936c.js b/assets/js/082a8033.353e47a1.js similarity index 58% rename from assets/js/082a8033.c9e8936c.js rename to assets/js/082a8033.353e47a1.js index 45a5da4a5..d77b0d160 100644 --- a/assets/js/082a8033.c9e8936c.js +++ b/assets/js/082a8033.353e47a1.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[3047],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>f});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var s=r.createContext({}),c=function(e){var t=r.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},d=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,l=e.originalType,s=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),u=c(a),m=n,f=u["".concat(s,".").concat(m)]||u[m]||p[m]||l;return a?r.createElement(f,i(i({ref:t},d),{},{components:a})):r.createElement(f,i({ref:t},d))}));function f(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var l=a.length,i=new Array(l);i[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[u]="string"==typeof e?e:n,i[1]=o;for(var c=2;c{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>l,metadata:()=>o,toc:()=>c});var r=a(7462),n=(a(7294),a(3905));const l={sidebar_position:1},i="Introduction",o={unversionedId:"build/wallet/intro",id:"build/wallet/intro",title:"Introduction",description:"A wallet is a fundamental tool for interacting with the blockchain.",source:"@site/docs/build/wallet/intro.mdx",sourceDirName:"build/wallet",slug:"/build/wallet/intro",permalink:"/docs/build/wallet/intro",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/wallet/intro.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"buildSidebar",previous:{title:"AS SDK",permalink:"/docs/build/smart-contract/sdk"},next:{title:"Massa Wallet",permalink:"/docs/build/wallet/massa-wallet"}},s={},c=[{value:"Wallet Providers",id:"wallet-providers",level:2}],d={toc:c},u="wrapper";function p(e){let{components:t,...a}=e;return(0,n.kt)(u,(0,r.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"introduction"},"Introduction"),(0,n.kt)("p",null,"A wallet is a fundamental tool for interacting with the blockchain.\nConsider it your digital identity, enabling you to send, receive, and manage assets on a blockchain."),(0,n.kt)("p",null,"There are several wallets available that are compatible with the Massa blockchain.\nThese wallets allow you to securely interact with the blockchain, including sending, receiving, and managing assets"),(0,n.kt)("h2",{id:"wallet-providers"},"Wallet Providers"),(0,n.kt)("p",null,"Here is a list of available wallet providers for the Massa blockchain:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("p",{parentName:"li"},(0,n.kt)("a",{parentName:"p",href:"/docs/build/wallet/massa-wallet"},"Massa Wallet"),": Massa Station is an official wallet developed by the Massa team. It provides a user-friendly interface and robust security features.")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("p",{parentName:"li"},(0,n.kt)("a",{parentName:"p",href:"/docs/build/wallet/community-wallets"},"Community Wallets"),": Community wallets are developed and maintained by the Massa community. These wallets can vary in features and interfaces.")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("p",{parentName:"li"},(0,n.kt)("a",{parentName:"p",href:"/docs/build/wallet/wallet-provider"},"Wallet Provider"),": Wallet Provider offers a secure, reliable, and versatile wallet that supports the Massa blockchain."))))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[3047],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>f});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var s=r.createContext({}),c=function(e){var t=r.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},d=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,l=e.originalType,s=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),u=c(a),m=n,f=u["".concat(s,".").concat(m)]||u[m]||p[m]||l;return a?r.createElement(f,i(i({ref:t},d),{},{components:a})):r.createElement(f,i({ref:t},d))}));function f(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var l=a.length,i=new Array(l);i[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[u]="string"==typeof e?e:n,i[1]=o;for(var c=2;c{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>l,metadata:()=>o,toc:()=>c});var r=a(7462),n=(a(7294),a(3905));const l={sidebar_position:1},i="Introduction",o={unversionedId:"build/wallet/intro",id:"build/wallet/intro",title:"Introduction",description:"A wallet is a fundamental tool for interacting with the blockchain.",source:"@site/docs/build/wallet/intro.mdx",sourceDirName:"build/wallet",slug:"/build/wallet/intro",permalink:"/docs/build/wallet/intro",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/wallet/intro.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"buildSidebar",previous:{title:"AS SDK",permalink:"/docs/build/smart-contract/sdk"},next:{title:"Massa Wallet",permalink:"/docs/build/wallet/massa-wallet"}},s={},c=[{value:"Wallet Providers",id:"wallet-providers",level:2}],d={toc:c},u="wrapper";function p(e){let{components:t,...a}=e;return(0,n.kt)(u,(0,r.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"introduction"},"Introduction"),(0,n.kt)("p",null,"A wallet is a fundamental tool for interacting with the blockchain.\nConsider it your digital identity, enabling you to send, receive, and manage assets on a blockchain."),(0,n.kt)("p",null,"There are several wallets available that are compatible with the Massa blockchain.\nThese wallets allow you to securely interact with the blockchain, including sending, receiving, and managing assets"),(0,n.kt)("h2",{id:"wallet-providers"},"Wallet Providers"),(0,n.kt)("p",null,"Here is a list of available wallet providers for the Massa blockchain:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("p",{parentName:"li"},(0,n.kt)("a",{parentName:"p",href:"/docs/build/wallet/massa-wallet"},"Massa Wallet"),": Massa Station is an official wallet developed by the Massa team. It provides a user-friendly interface and robust security features.")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("p",{parentName:"li"},(0,n.kt)("a",{parentName:"p",href:"/docs/build/wallet/community-wallets"},"Community Wallets"),": Community wallets are developed and maintained by the Massa community. These wallets can vary in features and interfaces.")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("p",{parentName:"li"},(0,n.kt)("a",{parentName:"p",href:"/docs/build/wallet/wallet-provider"},"Wallet Provider"),": Wallet Provider offers a secure, reliable, and versatile wallet that supports the Massa blockchain."))))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/10d3671b.1dd2d8a5.js b/assets/js/10d3671b.1dd2d8a5.js deleted file mode 100644 index 787296a6c..000000000 --- a/assets/js/10d3671b.1dd2d8a5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[1913],{3905:(e,t,a)=>{a.d(t,{Zo:()=>m,kt:()=>u});var n=a(7294);function s(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(s[a]=e[a]);return s}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(s[a]=e[a])}return s}var l=n.createContext({}),p=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},m=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,s=e.mdxType,o=e.originalType,l=e.parentName,m=r(e,["components","mdxType","originalType","parentName"]),c=p(a),d=s,u=c["".concat(l,".").concat(d)]||c[d]||h[d]||o;return a?n.createElement(u,i(i({ref:t},m),{},{components:a})):n.createElement(u,i({ref:t},m))}));function u(e,t){var a=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var o=a.length,i=new Array(o);i[0]=d;var r={};for(var l in t)hasOwnProperty.call(t,l)&&(r[l]=t[l]);r.originalType=e,r[c]="string"==typeof e?e:s,i[1]=r;for(var p=2;p{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>p});var n=a(7462),s=(a(7294),a(3905));const o={id:"node-architecture",sidebar_label:"Node architecture"},i="Architecture of Massa node",r={unversionedId:"learn/architecture/node-architecture",id:"learn/architecture/node-architecture",title:"Architecture of Massa node",description:"This section assumes some basic knowledge of the Massa protocol. If you are not familiar with the basic concepts of Massa,",source:"@site/docs/learn/architecture/node-architecture.mdx",sourceDirName:"learn/architecture",slug:"/learn/architecture/node-architecture",permalink:"/docs/learn/architecture/node-architecture",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/learn/architecture/node-architecture.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"node-architecture",sidebar_label:"Node architecture"},sidebar:"learnSidebar",previous:{title:"Basic concepts",permalink:"/docs/learn/architecture/basic-concepts"},next:{title:"Operation lifecycle",permalink:"/docs/learn/architecture/operation-lifecycle"}},l={},p=[{value:"Bootstrap Module",id:"bootstrap-module",level:2},{value:"API Module",id:"api-module",level:2},{value:"Protocol/Network Module",id:"protocolnetwork-module",level:2},{value:"Selector Module, Proof of Stake sybil resistance",id:"selector-module-proof-of-stake-sybil-resistance",level:2},{value:"Graph/Consensus Module",id:"graphconsensus-module",level:2},{value:"Block cliques",id:"block-cliques",level:3},{value:"Finalized blocks, stale blocks",id:"finalized-blocks-stale-blocks",level:3},{value:"Graph/Consensus Module Function",id:"graphconsensus-module-function",level:3},{value:"Execution Module",id:"execution-module",level:2},{value:"Pool Module",id:"pool-module",level:2},{value:"Block/Endorsement Factory Module",id:"blockendorsement-factory-module",level:2}],m={toc:p},c="wrapper";function h(e){let{components:t,...o}=e;return(0,s.kt)(c,(0,n.Z)({},m,o,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"architecture-of-massa-node"},"Architecture of Massa node"),(0,s.kt)("admonition",{type:"note"},(0,s.kt)("p",{parentName:"admonition"},"This section assumes some basic knowledge of the Massa protocol. If you are not familiar with the basic concepts of Massa,\nread the ",(0,s.kt)("a",{parentName:"p",href:"/docs/learn/architecture/basic-concepts"},"Basic Concepts")," section first.")),(0,s.kt)("p",null,"The section describes the global architecture of a Massa node, from the ground up."),(0,s.kt)("p",null,"This is the diagram of the architecture of the software modules involved in building, endorsing and propagating blocks.\nThe bottom part corresponds to a single process running in a node and is in charge of the execution and consensus building.\nThe pool and factories, referred to as \u201cfactory\u201d, can be potentially running in a different process or be part of the node.\nOverall, each of the modules described here runs inside one or more threads attached to their respective executable process\n(NB: the factory/node separation is not yet implemented, but will be soon)."),(0,s.kt)("p",null,(0,s.kt)("img",{src:a(9270).Z,width:"962",height:"980"})),(0,s.kt)("p",null,"We will explain below the different modules present in this diagram, and simulate the production of an operation to show\nhow it navigates through the different modules to better understand how blocks are produced and propagated."),(0,s.kt)("h2",{id:"bootstrap-module"},"Bootstrap Module"),(0,s.kt)("p",null,"The bootstrap module is responsible for the initial synchronization of the node with the rest of the network. It is responsible\nfor downloading the list of peers, the current graph of blocks, the ledger, the asynchronous pool, state of the Proof-of-Stake\nand latests executed operations."),(0,s.kt)("p",null,"The bootstrap will be done from a server that is listed on the configuration of the node. Bootstrap is the entry point of the\nnetwork so you have to be careful on which node you connect to avoid downloading malicious data."),(0,s.kt)("h2",{id:"api-module"},"API Module"),(0,s.kt)("p",null,"The API Module is the public window of the node to the rest of the world. It allows for interactions with external clients or\nfactories via a ",(0,s.kt)("a",{parentName:"p",href:"/docs/build/api/jsonrpc"},"JSON RPC")," and ",(0,s.kt)("a",{parentName:"p",href:"/docs/build/api/grpc"},"gRPC")," protocols."),(0,s.kt)("p",null,"The API includes interfaces to do the following:"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"publish a new operation from a client"),(0,s.kt)("li",{parentName:"ul"},"query the network about balances or ledger status"),(0,s.kt)("li",{parentName:"ul"},"allow for synchronization between remote pool/factory nodes and the consensus nodes, by sending/asking for blocks, best\nparents, draws, etc.")),(0,s.kt)("h2",{id:"protocolnetwork-module"},"Protocol/Network Module"),(0,s.kt)("p",null,"The Protocol/Network Module implements the protocol connecting consensus nodes. This protocol is supported by a binary and optimized transport layer."),(0,s.kt)("p",null,"The Protocol/Network Module will relay all operations/blocks creation and propagation, so that all other nodes in the\nnetwork can synchronize their internal state, following a type of gossip synchronization protocol."),(0,s.kt)("p",null,"The type of messages that can be relayed via the Protocol/Network Module include:"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"blocks/operations/endorsements propagation (either getting in or out of the node)"),(0,s.kt)("li",{parentName:"ul"},"nodes ban requests"),(0,s.kt)("li",{parentName:"ul"},"connectivity infos/stats.")),(0,s.kt)("h2",{id:"selector-module-proof-of-stake-sybil-resistance"},"Selector Module, Proof of Stake sybil resistance"),(0,s.kt)("p",null,"Every 0.5s, a new slot becomes active to receive a new block. A determinist selection mechanism ensures that one of\nthe nodes in the network is elected to have the responsibility to build the block for that slot. This mechanism must have several key properties:"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("p",{parentName:"li"},"it should be sybil resistant, so that it is not possible to increase one\u2019s odds of being elected by creating multiple\nclones of oneself (sybil) without a cost that is equal or greater than the cost of increasing one\u2019s odds for oneself only;")),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("p",{parentName:"li"},"it should be deterministic, so that all nodes in the network will agree on the result of the selection at any given time;")),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("p",{parentName:"li"},"it should be fair, so that each participant has a well-defined probability of being selected somehow proportional to\nthe cost of participating, and draws converge towards this probability distribution over time."))),(0,s.kt)("p",null,"The way sybil resistance is achieved here is via the proof of stake mechanism. Nodes who want to participate in the block\ncreation lottery will have to stake \u201crolls\u201d that they buy with Massa coins. If they try to cheat by creating fake blocks\nor multiple blocks on the same slot, their stake will be taken away from them (slashing) and they would suffer the loss.\nThe probabilistic \u201csurface\u201d of a participant is equal to its total stake, which makes the creation of sybil accounts useless\nbecause the stake would have to be split between them anyway."),(0,s.kt)("admonition",{type:"note"},(0,s.kt)("p",{parentName:"admonition"},"More about slashing mechanism ",(0,s.kt)("a",{parentName:"p",href:"/docs/learn/architecture/consensus-quality#slashing"},"here"))),(0,s.kt)("p",null,"The method used to draw an elected node for a given slot is simply a random draw from a distribution where addresses are\nweighted by the amount of stake (=rolls) they hold. The schema below illustrates how the seed and probability distribution\nare built, based on past cycles (two cycles are needed for the distribution update to ensure that the balance finalization\nhas occurred and the amount of rolls is accurate):"),(0,s.kt)("p",null,(0,s.kt)("img",{src:a(4246).Z,width:"321",height:"261"})),(0,s.kt)("p",null,"The Selector Module is in charge of computing the formula and replying to requests regarding what node is elected for any\ngiven slot in the present or the past. The Execution Module (see below) is in charge of feeding the Selector Module with\nupdates regarding balances, needed to compute the draws."),(0,s.kt)("h2",{id:"graphconsensus-module"},"Graph/Consensus Module"),(0,s.kt)("p",null,"The Consensus Module is the heart of the machinery of the Massa Network. It is in charge of integrating proposed blocks\ninto their respective slots and verifying the integrity of the result. We have not yet talked about the various constraints\nregarding block creation, and in particular how parents are to be selected. In traditional blockchains, the parent of a\nblock is simply the previous valid block in the chain. In the context of the Massa network and the parallel chains in the\n32 threads, identifying the proper parent in a given thread requires a more sophisticated strategy involving the notion of block cliques."),(0,s.kt)("h3",{id:"block-cliques"},"Block cliques"),(0,s.kt)("p",null,"At any given time, the set of all the blocks that have been produced and propagated in the network constitutes a graph (more precisely\na Directed Acyclic Graph or \u201cDAG\u201d), where each block, except the genesis blocks, has 32 parents. All the reasoning below can be in\nprinciple done on this increasingly vast set, but in practice, we will introduce a notion of \u201cfinalized\u201d or \u201cstaled\u201d blocks, that\ncan be removed from the set and that will allow us to work on a smaller subset of recent blocks that are neither finalized nor\nstaled, so \u201cpending\u201d blocks. This set of pending blocks is all the network needs to know in order to incrementally build up a\nconsensus, therefore non-pending blocks will simply be forgotten (this is a striking difference with most other blockchains\nthat store in each node the history of all past transactions). The main benefit of this block pruning is to allow for some of\nthe algorithms below, which are in general NP-complete, to run fast enough on a smaller subgraph, and to allow for a practical implementation."),(0,s.kt)("p",null,"Here is a simplified example of a graph of pending blocks over two threads, with blocks 3 and 4 competing for slot C1 (for example\nas a result of a multistaking attack where the block producer decided to create competing blocks for the same slot). Here the\nletter of a slot identifies it, while the number refers to its thread number:"),(0,s.kt)("p",null,(0,s.kt)("img",{src:a(1440).Z,width:"518",height:"181"})),(0,s.kt)("p",null,"In this illustration we have shown only relevant parent links in blue, to make the whole diagram more readable, but in reality,\neach block has 32 parents, one in each of the 32 threads."),(0,s.kt)("p",null,"An important notion we will use in the following is that of incompatibility between blocks. Excluding some edge cases with genesis\nblocks, there are two sources of incompatibilities defined for blocks:"),(0,s.kt)("ol",null,(0,s.kt)("li",{parentName:"ol"},(0,s.kt)("strong",{parentName:"li"},"thread incompatibility"),": this occurs when two blocks in a given thread have the same parent in that thread."),(0,s.kt)("li",{parentName:"ol"},(0,s.kt)("strong",{parentName:"li"},"grandpa incompatibility"),": this corresponds to a case with two blocks B1 and B2 in threads t1 and t2, and where the block\nB1 in t1 has a parent in t2 who is an ancestor of B2\u2019s parent in t2, and symmetrically B2\u2019s parent in t1 is an ancestor of\nB1\u2019s parent in t1.")),(0,s.kt)("admonition",{type:"tip"},(0,s.kt)("p",{parentName:"admonition"},"You will find a more formal mathematical definition of these incompatibility notions in the ",(0,s.kt)("a",{parentName:"p",href:"https://arxiv.org/pdf/1803.09029.pdf"},"whitepaper"))),(0,s.kt)("p",null,"From these definitions, you can build another graph, called the incompatibility graph, which connects any two blocks that\nhave any form of incompatibility together:"),(0,s.kt)("p",null,(0,s.kt)("img",{src:a(3509).Z,width:"268",height:"228"})),(0,s.kt)("p",null,"As you can see, some blocks are isolated and therefore compatible with any other, while some are linked, because they have\na form of incompatibility."),(0,s.kt)("p",null,"This brings us to the notion of a maximal clique which is a subset of the incompatibility graph such as none of the block\nmembers are incompatible with each other (so, no internal link within the clique), and it is impossible to add an extra block\nto the set without introducing incompatibilities. In the above example, there are three maximal cliques that can be built,\nas illustrated below:"),(0,s.kt)("p",null,(0,s.kt)("img",{src:a(9645).Z,width:"320",height:"312"})),(0,s.kt)("p",null,"They represent candidates to extend the set of already finalized blocks into a coherent set of new blocks. All we need to\nadd to be able to build a consensus rule now is to introduce a deterministic metric to rank those candidates so that nodes\ncan independently and consistently decide on which clique is the best candidate and keep building on top of it. In particular,\nonce the best maximal clique is identified, it becomes trivial to define the list of the parents for a new block simply by\npicking the oldest block from that clique in each thread."),(0,s.kt)("p",null,"The metric used in a traditional blockchain to rank competing chain candidates is habitually the length of the chain, or more\nprecisely the total amount of work invested in the chain (also known as \u201cNakamoto consensus\u201d). In the case of block cliques,\nwe will introduce a notion of fitness for each block, and the fitness of the clique will simply be the sum of all its block\u2019s\nfitness. The block fitness ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"f"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mi",{parentName:"mrow"},"b"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"f(b)")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.10764em"}},"f"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"b"),(0,s.kt)("span",{parentName:"span",className:"mclose"},")")))))," is simply defined as ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mn",{parentName:"mrow"},"1"),(0,s.kt)("mo",{parentName:"mrow"},"+"),(0,s.kt)("mi",{parentName:"mrow"},"e"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("mi",{parentName:"mrow"},"e")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"1+e, e")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.7278em",verticalAlign:"-0.0833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},"1"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,s.kt)("span",{parentName:"span",className:"mbin"},"+"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.625em",verticalAlign:"-0.1944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"e"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"e")))))," being the number of endorsements registered in the block."),(0,s.kt)("p",null,"Taking the maximal clique with the highest fitness (or some hash-based deterministic selection in case of equality), the\nGraph/Consensus module can define what is called the blockclique at the current time."),(0,s.kt)("h3",{id:"finalized-blocks-stale-blocks"},"Finalized blocks, stale blocks"),(0,s.kt)("p",null,"The set of pending blocks is growing each time a new block is produced and added to the current set. As we mentioned previously,\nthere is also a pruning mechanism in charge of reducing the size of the graph by removing blocks that are considered final, and\nalso blocks that can be considered stale and will never finalize."),(0,s.kt)("p",null,"If a block is only contained inside cliques that have a fitness lower than the fitness of the blockclique (the clique with the maximal fitness), minus a constant ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("msubsup",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msubsup",mathvariant:"normal"},"\u0394"),(0,s.kt)("mi",{parentName:"msubsup"},"f"),(0,s.kt)("mn",{parentName:"msubsup"},"0"))),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"\\Delta_{f}^{0}")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.2333em",verticalAlign:"-0.4192em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},"\u0394"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8141em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.4169em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight",style:{marginRight:"0.10764em"}},"f")))),(0,s.kt)("span",{parentName:"span",style:{top:"-3.063em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},"0"))))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.4192em"}},(0,s.kt)("span",{parentName:"span"})))))))))),", then this block is considered stale. Also, any new block that includes in its parents a stale block is stale."),(0,s.kt)("p",null,"A block is considered final if it is part of all maximal cliques, and included in at least one clique where the total sum of the fitness of all its descendants is greater than ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("msubsup",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msubsup",mathvariant:"normal"},"\u0394"),(0,s.kt)("mi",{parentName:"msubsup"},"f"),(0,s.kt)("mn",{parentName:"msubsup"},"0"))),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"\\Delta_{f}^{0}")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.2333em",verticalAlign:"-0.4192em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},"\u0394"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8141em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.4169em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight",style:{marginRight:"0.10764em"}},"f")))),(0,s.kt)("span",{parentName:"span",style:{top:"-3.063em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},"0"))))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.4192em"}},(0,s.kt)("span",{parentName:"span"})))))))))),"."),(0,s.kt)("p",null,(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("msubsup",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msubsup",mathvariant:"normal"},"\u0394"),(0,s.kt)("mi",{parentName:"msubsup"},"f"),(0,s.kt)("mn",{parentName:"msubsup"},"0"))),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"\\Delta_{f}^{0}")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.2333em",verticalAlign:"-0.4192em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},"\u0394"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8141em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.4169em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight",style:{marginRight:"0.10764em"}},"f")))),(0,s.kt)("span",{parentName:"span",style:{top:"-3.063em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},"0"))))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.4192em"}},(0,s.kt)("span",{parentName:"span"}))))))))))," is defined as a constant ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"F")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"F")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"F")))))," multiplied by ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mn",{parentName:"mrow"},"1"),(0,s.kt)("mo",{parentName:"mrow"},"+"),(0,s.kt)("mi",{parentName:"mrow"},"E")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"1+E")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.7278em",verticalAlign:"-0.0833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},"1"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,s.kt)("span",{parentName:"span",className:"mbin"},"+"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.05764em"}},"E"))))),"\n(",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"E")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"E")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.05764em"}},"E")))))," being the total max number of endorsements in a block, currently 16), and ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"F")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"F")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"F")))))," effectively measuring the maximum span in fully endorsed blocks of a successful blockclique, or the number of fully endorsed blocks by which an alternative clique can be shorter than the blockclique before its blocks may be discarded as stale."),(0,s.kt)("h3",{id:"graphconsensus-module-function"},"Graph/Consensus Module Function"),(0,s.kt)("p",null,"The Consensus Module (formerly known as the Graph) receives new block proposals, integrates them into the set of pending blocks,\nupdating the blockclique with the method explained above, and verifying the legitimacy of the parenting of new blocks. It also\ninforms other modules, like the Execution module, when blocks are finalized and the corresponding ledger modifications implied\nby their operations list should be made permanent."),(0,s.kt)("p",null,"It is also able to answer queries about the current best parents for a new block (based on the current blockclique) or the list\nof current maximal cliques."),(0,s.kt)("h2",{id:"execution-module"},"Execution Module"),(0,s.kt)("p",null,"The Execution Module is in charge of effectively executing the operations contained in blocks within the current blockclique,\nwhich is provided by the Graph/Consensus Module. Operations will typically modify the ledger, either by changing the balances\nof accounts or by modifying the datastore of smart contracts after the execution of some code. From an implementation point\nof view, ledger modifications are however stored as diff vs the current finalized ledger, until the corresponding blocks are\nmarked as finalized by the Graph/Consensus Module."),(0,s.kt)("p",null,"Block creators will typically need to query the Execution Module to check current balances at a given slot and verify if some\noperations can be run with sufficient funds or not, before being integrated into a new block."),(0,s.kt)("p",null,"As a side note, it is also possible that blocks might include invalid operations, in which case the Execution Module will\nsimply ignore them."),(0,s.kt)("p",null,"Being the maintainer of the ledger, the Execution Module is also queried about address information in general, via the API,\nfor any Module that needs it."),(0,s.kt)("p",null,"Finally, the Execution Module will inform the Selector Module when new cycles are initiated as the finalization of blocks\nprogresses."),(0,s.kt)("h2",{id:"pool-module"},"Pool Module"),(0,s.kt)("p",null,"When new pending operations reach a node, they are not immediately processed but instead are stored in a pool of pending operations,\nto be used by the Factory Module. Similarly, proposed endorsements coming from the Endorsement Factory are buffered inside the pool,\nto be integrated into new blocks by the Block Factory Module."),(0,s.kt)("p",null,"The origin of pending operations or endorsements inside the pool can be internal to the factory process or could come from remote\nnodes via the API Module. Similarly, locally produced pending endorsements are broadcasted via a gossip protocol to other pools\nvia the API Module."),(0,s.kt)("p",null,"Note that operations stored in the Pool are naturally discarded after a certain time, since operations come with an expiration\ndate in the ",(0,s.kt)("em",{parentName:"p"},"expiration_period")," field. Still, some potential attacks can occur by trying to flood the pool with high fees\noperations that have no chance of being executed because the corresponding account does not have the required funds.\nDiscussing about countermeasure for this is beyond the scope of this introduction."),(0,s.kt)("h2",{id:"blockendorsement-factory-module"},"Block/Endorsement Factory Module"),(0,s.kt)("p",null,"The Block Factory Module is in charge of creating new blocks when the corresponding node address has been designated to\nbe the block creator for a given slot. This information is provided to the Factory Module from the Selector Module via\nthe API Module."),(0,s.kt)("p",null,"The Block Factory Module also needs information about the best parents (made of the latest blocks in each thread in\nthe blockclique) from the Graph/Consensus Module. These parents will be included in the newly created block. Balance\ninformation, in order to assess the validity of pending operations, is obtained from the Execution Module, which\nmaintains the ledger state from the point of view of the slot where the new block is supposed to be created."),(0,s.kt)("p",null,"The Block Factory Module picks pending operations from the Pool Module. Note that the Block Factory will regularly\nquery the Execution Module about finalized and executed operations, and internally cleanup operations that have been handled."),(0,s.kt)("p",null,"Finally, the Block Factory will query the Pool Module and pick pending endorsements corresponding to the best parents\nthat are selected for the block."),(0,s.kt)("p",null,"With this information, it is able to forge a new block that will then be propagated to the Graph/Consensus Module\nvia the API Module, as well as to other nodes via gossip, to maintain a global synchronized state."),(0,s.kt)("p",null,"The Endorsement Factory Module works in a similar manner, requesting the Selector Module to find out when it has been\ndesignated to be an endorsement producer, then feeding new endorsements to the Pool Module and the API Module for global synchronization."))}h.isMDXComponent=!0},9270:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/architecture-4a1209c66babdf0750ff11fb839724b3.svg"},9645:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/cliques-1ea940b8535eb8b547c71482653edeee.svg"},3509:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/incompatibility_graph-3d0cbae75657b115b202ef3d216b2f86.svg"},4246:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/selector-e621b755dcea738530297fb7760b5f31.svg"},1440:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/unfinalized_blocks_set-dfbeffb53e6ae2f5096aac0c02c8c7b6.svg"}}]); \ No newline at end of file diff --git a/assets/js/10d3671b.aac0aec8.js b/assets/js/10d3671b.aac0aec8.js new file mode 100644 index 000000000..13d200459 --- /dev/null +++ b/assets/js/10d3671b.aac0aec8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[1913],{3905:(e,t,a)=>{a.d(t,{Zo:()=>m,kt:()=>u});var n=a(7294);function s(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(s[a]=e[a]);return s}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(s[a]=e[a])}return s}var l=n.createContext({}),p=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},m=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,s=e.mdxType,o=e.originalType,l=e.parentName,m=r(e,["components","mdxType","originalType","parentName"]),c=p(a),d=s,u=c["".concat(l,".").concat(d)]||c[d]||h[d]||o;return a?n.createElement(u,i(i({ref:t},m),{},{components:a})):n.createElement(u,i({ref:t},m))}));function u(e,t){var a=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var o=a.length,i=new Array(o);i[0]=d;var r={};for(var l in t)hasOwnProperty.call(t,l)&&(r[l]=t[l]);r.originalType=e,r[c]="string"==typeof e?e:s,i[1]=r;for(var p=2;p{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>p});var n=a(7462),s=(a(7294),a(3905));const o={id:"node-architecture",sidebar_label:"Node architecture"},i="Architecture of Massa node",r={unversionedId:"learn/architecture/node-architecture",id:"learn/architecture/node-architecture",title:"Architecture of Massa node",description:"This section assumes some basic knowledge of the Massa protocol. If you are not familiar with the basic concepts of Massa,",source:"@site/docs/learn/architecture/node-architecture.mdx",sourceDirName:"learn/architecture",slug:"/learn/architecture/node-architecture",permalink:"/docs/learn/architecture/node-architecture",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/learn/architecture/node-architecture.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"node-architecture",sidebar_label:"Node architecture"},sidebar:"learnSidebar",previous:{title:"Basic concepts",permalink:"/docs/learn/architecture/basic-concepts"},next:{title:"Operation lifecycle",permalink:"/docs/learn/architecture/operation-lifecycle"}},l={},p=[{value:"Bootstrap Module",id:"bootstrap-module",level:2},{value:"API Module",id:"api-module",level:2},{value:"Protocol/Network Module",id:"protocolnetwork-module",level:2},{value:"Selector Module, Proof of Stake sybil resistance",id:"selector-module-proof-of-stake-sybil-resistance",level:2},{value:"Graph/Consensus Module",id:"graphconsensus-module",level:2},{value:"Block cliques",id:"block-cliques",level:3},{value:"Finalized blocks, stale blocks",id:"finalized-blocks-stale-blocks",level:3},{value:"Graph/Consensus Module Function",id:"graphconsensus-module-function",level:3},{value:"Execution Module",id:"execution-module",level:2},{value:"Pool Module",id:"pool-module",level:2},{value:"Block/Endorsement Factory Module",id:"blockendorsement-factory-module",level:2}],m={toc:p},c="wrapper";function h(e){let{components:t,...o}=e;return(0,s.kt)(c,(0,n.Z)({},m,o,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"architecture-of-massa-node"},"Architecture of Massa node"),(0,s.kt)("admonition",{type:"note"},(0,s.kt)("p",{parentName:"admonition"},"This section assumes some basic knowledge of the Massa protocol. If you are not familiar with the basic concepts of Massa,\nread the ",(0,s.kt)("a",{parentName:"p",href:"/docs/learn/architecture/basic-concepts"},"Basic Concepts")," section first.")),(0,s.kt)("p",null,"The section describes the global architecture of a Massa node, from the ground up."),(0,s.kt)("p",null,"This is the diagram of the architecture of the software modules involved in building, endorsing and propagating blocks.\nThe bottom part corresponds to a single process running in a node and is in charge of the execution and consensus building.\nThe pool and factories, referred to as \u201cfactory\u201d, can be potentially running in a different process or be part of the node.\nOverall, each of the modules described here runs inside one or more threads attached to their respective executable process\n(NB: the factory/node separation is not yet implemented, but will be soon)."),(0,s.kt)("p",null,(0,s.kt)("img",{src:a(9270).Z,width:"962",height:"980"})),(0,s.kt)("p",null,"We will explain below the different modules present in this diagram, and simulate the production of an operation to show\nhow it navigates through the different modules to better understand how blocks are produced and propagated."),(0,s.kt)("h2",{id:"bootstrap-module"},"Bootstrap Module"),(0,s.kt)("p",null,"The bootstrap module is responsible for the initial synchronization of the node with the rest of the network. It is responsible\nfor downloading the list of peers, the current graph of blocks, the ledger, the asynchronous pool, state of the Proof-of-Stake\nand latests executed operations."),(0,s.kt)("p",null,"The bootstrap will be done from a server that is listed on the configuration of the node. Bootstrap is the entry point of the\nnetwork so you have to be careful on which node you connect to avoid downloading malicious data."),(0,s.kt)("h2",{id:"api-module"},"API Module"),(0,s.kt)("p",null,"The API Module is the public window of the node to the rest of the world. It allows for interactions with external clients or\nfactories via a ",(0,s.kt)("a",{parentName:"p",href:"/docs/build/api/jsonrpc"},"JSON RPC")," and ",(0,s.kt)("a",{parentName:"p",href:"/docs/build/api/grpc"},"gRPC")," protocols."),(0,s.kt)("p",null,"The API includes interfaces to do the following:"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"publish a new operation from a client"),(0,s.kt)("li",{parentName:"ul"},"query the network about balances or ledger status"),(0,s.kt)("li",{parentName:"ul"},"allow for synchronization between remote pool/factory nodes and the consensus nodes, by sending/asking for blocks, best\nparents, draws, etc.")),(0,s.kt)("h2",{id:"protocolnetwork-module"},"Protocol/Network Module"),(0,s.kt)("p",null,"The Protocol/Network Module implements the protocol connecting consensus nodes. This protocol is supported by a binary and optimized transport layer."),(0,s.kt)("p",null,"The Protocol/Network Module will relay all operations/blocks creation and propagation, so that all other nodes in the\nnetwork can synchronize their internal state, following a type of gossip synchronization protocol."),(0,s.kt)("p",null,"The type of messages that can be relayed via the Protocol/Network Module include:"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"blocks/operations/endorsements propagation (either getting in or out of the node)"),(0,s.kt)("li",{parentName:"ul"},"nodes ban requests"),(0,s.kt)("li",{parentName:"ul"},"connectivity infos/stats.")),(0,s.kt)("h2",{id:"selector-module-proof-of-stake-sybil-resistance"},"Selector Module, Proof of Stake sybil resistance"),(0,s.kt)("p",null,"Every 0.5s, a new slot becomes active to receive a new block. A determinist selection mechanism ensures that one of\nthe nodes in the network is elected to have the responsibility to build the block for that slot. This mechanism must have several key properties:"),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("p",{parentName:"li"},"it should be sybil resistant, so that it is not possible to increase one\u2019s odds of being elected by creating multiple\nclones of oneself (sybil) without a cost that is equal or greater than the cost of increasing one\u2019s odds for oneself only;")),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("p",{parentName:"li"},"it should be deterministic, so that all nodes in the network will agree on the result of the selection at any given time;")),(0,s.kt)("li",{parentName:"ul"},(0,s.kt)("p",{parentName:"li"},"it should be fair, so that each participant has a well-defined probability of being selected somehow proportional to\nthe cost of participating, and draws converge towards this probability distribution over time."))),(0,s.kt)("p",null,"The way sybil resistance is achieved here is via the proof of stake mechanism. Nodes who want to participate in the block\ncreation lottery will have to stake \u201crolls\u201d that they buy with Massa coins. If they try to cheat by creating fake blocks\nor multiple blocks on the same slot, their stake will be taken away from them (slashing) and they would suffer the loss.\nThe probabilistic \u201csurface\u201d of a participant is equal to its total stake, which makes the creation of sybil accounts useless\nbecause the stake would have to be split between them anyway."),(0,s.kt)("admonition",{type:"note"},(0,s.kt)("p",{parentName:"admonition"},"More about slashing mechanism ",(0,s.kt)("a",{parentName:"p",href:"/docs/learn/architecture/consensus-quality#slashing"},"here"))),(0,s.kt)("p",null,"The method used to draw an elected node for a given slot is simply a random draw from a distribution where addresses are\nweighted by the amount of stake (=rolls) they hold. The schema below illustrates how the seed and probability distribution\nare built, based on past cycles (two cycles are needed for the distribution update to ensure that the balance finalization\nhas occurred and the amount of rolls is accurate):"),(0,s.kt)("p",null,(0,s.kt)("img",{src:a(4246).Z,width:"321",height:"261"})),(0,s.kt)("p",null,"The Selector Module is in charge of computing the formula and replying to requests regarding what node is elected for any\ngiven slot in the present or the past. The Execution Module (see below) is in charge of feeding the Selector Module with\nupdates regarding balances, needed to compute the draws."),(0,s.kt)("h2",{id:"graphconsensus-module"},"Graph/Consensus Module"),(0,s.kt)("p",null,"The Consensus Module is the heart of the machinery of the Massa Network. It is in charge of integrating proposed blocks\ninto their respective slots and verifying the integrity of the result. We have not yet talked about the various constraints\nregarding block creation, and in particular how parents are to be selected. In traditional blockchains, the parent of a\nblock is simply the previous valid block in the chain. In the context of the Massa network and the parallel chains in the\n32 threads, identifying the proper parent in a given thread requires a more sophisticated strategy involving the notion of block cliques."),(0,s.kt)("h3",{id:"block-cliques"},"Block cliques"),(0,s.kt)("p",null,"At any given time, the set of all the blocks that have been produced and propagated in the network constitutes a graph (more precisely\na Directed Acyclic Graph or \u201cDAG\u201d), where each block, except the genesis blocks, has 32 parents. All the reasoning below can be in\nprinciple done on this increasingly vast set, but in practice, we will introduce a notion of \u201cfinalized\u201d or \u201cstaled\u201d blocks, that\ncan be removed from the set and that will allow us to work on a smaller subset of recent blocks that are neither finalized nor\nstaled, so \u201cpending\u201d blocks. This set of pending blocks is all the network needs to know in order to incrementally build up a\nconsensus, therefore non-pending blocks will simply be forgotten (this is a striking difference with most other blockchains\nthat store in each node the history of all past transactions). The main benefit of this block pruning is to allow for some of\nthe algorithms below, which are in general NP-complete, to run fast enough on a smaller subgraph, and to allow for a practical implementation."),(0,s.kt)("p",null,"Here is a simplified example of a graph of pending blocks over two threads, with blocks 3 and 4 competing for slot C1 (for example\nas a result of a multistaking attack where the block producer decided to create competing blocks for the same slot). Here the\nletter of a slot identifies it, while the number refers to its thread number:"),(0,s.kt)("p",null,(0,s.kt)("img",{src:a(1440).Z,width:"518",height:"181"})),(0,s.kt)("p",null,"In this illustration we have shown only relevant parent links in blue, to make the whole diagram more readable, but in reality,\neach block has 32 parents, one in each of the 32 threads."),(0,s.kt)("p",null,"An important notion we will use in the following is that of incompatibility between blocks. Excluding some edge cases with genesis\nblocks, there are two sources of incompatibilities defined for blocks:"),(0,s.kt)("ol",null,(0,s.kt)("li",{parentName:"ol"},(0,s.kt)("strong",{parentName:"li"},"thread incompatibility"),": this occurs when two blocks in a given thread have the same parent in that thread."),(0,s.kt)("li",{parentName:"ol"},(0,s.kt)("strong",{parentName:"li"},"grandpa incompatibility"),": this corresponds to a case with two blocks B1 and B2 in threads t1 and t2, and where the block\nB1 in t1 has a parent in t2 who is an ancestor of B2\u2019s parent in t2, and symmetrically B2\u2019s parent in t1 is an ancestor of\nB1\u2019s parent in t1.")),(0,s.kt)("admonition",{type:"tip"},(0,s.kt)("p",{parentName:"admonition"},"You will find a more formal mathematical definition of these incompatibility notions in the ",(0,s.kt)("a",{parentName:"p",href:"https://arxiv.org/pdf/1803.09029.pdf"},"whitepaper"))),(0,s.kt)("p",null,"From these definitions, you can build another graph, called the incompatibility graph, which connects any two blocks that\nhave any form of incompatibility together:"),(0,s.kt)("p",null,(0,s.kt)("img",{src:a(3509).Z,width:"268",height:"228"})),(0,s.kt)("p",null,"As you can see, some blocks are isolated and therefore compatible with any other, while some are linked, because they have\na form of incompatibility."),(0,s.kt)("p",null,"This brings us to the notion of a maximal clique which is a subset of the incompatibility graph such as none of the block\nmembers are incompatible with each other (so, no internal link within the clique), and it is impossible to add an extra block\nto the set without introducing incompatibilities. In the above example, there are three maximal cliques that can be built,\nas illustrated below:"),(0,s.kt)("p",null,(0,s.kt)("img",{src:a(9645).Z,width:"320",height:"312"})),(0,s.kt)("p",null,"They represent candidates to extend the set of already finalized blocks into a coherent set of new blocks. All we need to\nadd to be able to build a consensus rule now is to introduce a deterministic metric to rank those candidates so that nodes\ncan independently and consistently decide on which clique is the best candidate and keep building on top of it. In particular,\nonce the best maximal clique is identified, it becomes trivial to define the list of the parents for a new block simply by\npicking the oldest block from that clique in each thread."),(0,s.kt)("p",null,"The metric used in a traditional blockchain to rank competing chain candidates is habitually the length of the chain, or more\nprecisely the total amount of work invested in the chain (also known as \u201cNakamoto consensus\u201d). In the case of block cliques,\nwe will introduce a notion of fitness for each block, and the fitness of the clique will simply be the sum of all its block\u2019s\nfitness. The block fitness ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"f"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},"("),(0,s.kt)("mi",{parentName:"mrow"},"b"),(0,s.kt)("mo",{parentName:"mrow",stretchy:"false"},")")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"f(b)")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.10764em"}},"f"),(0,s.kt)("span",{parentName:"span",className:"mopen"},"("),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"b"),(0,s.kt)("span",{parentName:"span",className:"mclose"},")")))))," is simply defined as ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mn",{parentName:"mrow"},"1"),(0,s.kt)("mo",{parentName:"mrow"},"+"),(0,s.kt)("mi",{parentName:"mrow"},"e"),(0,s.kt)("mo",{parentName:"mrow",separator:"true"},","),(0,s.kt)("mi",{parentName:"mrow"},"e")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"1+e, e")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.7278em",verticalAlign:"-0.0833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},"1"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,s.kt)("span",{parentName:"span",className:"mbin"},"+"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.625em",verticalAlign:"-0.1944em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"e"),(0,s.kt)("span",{parentName:"span",className:"mpunct"},","),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.1667em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal"},"e")))))," being the number of endorsements registered in the block."),(0,s.kt)("p",null,"Taking the maximal clique with the highest fitness (or some hash-based deterministic selection in case of equality), the\nGraph/Consensus module can define what is called the blockclique at the current time."),(0,s.kt)("h3",{id:"finalized-blocks-stale-blocks"},"Finalized blocks, stale blocks"),(0,s.kt)("p",null,"The set of pending blocks is growing each time a new block is produced and added to the current set. As we mentioned previously,\nthere is also a pruning mechanism in charge of reducing the size of the graph by removing blocks that are considered final, and\nalso blocks that can be considered stale and will never finalize."),(0,s.kt)("p",null,"If a block is only contained inside cliques that have a fitness lower than the fitness of the blockclique (the clique with the maximal fitness), minus a constant ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("msubsup",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msubsup",mathvariant:"normal"},"\u0394"),(0,s.kt)("mi",{parentName:"msubsup"},"f"),(0,s.kt)("mn",{parentName:"msubsup"},"0"))),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"\\Delta_{f}^{0}")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.2333em",verticalAlign:"-0.4192em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},"\u0394"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8141em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.4169em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight",style:{marginRight:"0.10764em"}},"f")))),(0,s.kt)("span",{parentName:"span",style:{top:"-3.063em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},"0"))))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.4192em"}},(0,s.kt)("span",{parentName:"span"})))))))))),", then this block is considered stale. Also, any new block that includes in its parents a stale block is stale."),(0,s.kt)("p",null,"A block is considered final if it is part of all maximal cliques, and included in at least one clique where the total sum of the fitness of all its descendants is greater than ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("msubsup",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msubsup",mathvariant:"normal"},"\u0394"),(0,s.kt)("mi",{parentName:"msubsup"},"f"),(0,s.kt)("mn",{parentName:"msubsup"},"0"))),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"\\Delta_{f}^{0}")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.2333em",verticalAlign:"-0.4192em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},"\u0394"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8141em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.4169em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight",style:{marginRight:"0.10764em"}},"f")))),(0,s.kt)("span",{parentName:"span",style:{top:"-3.063em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},"0"))))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.4192em"}},(0,s.kt)("span",{parentName:"span"})))))))))),"."),(0,s.kt)("p",null,(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("msubsup",{parentName:"mrow"},(0,s.kt)("mi",{parentName:"msubsup",mathvariant:"normal"},"\u0394"),(0,s.kt)("mi",{parentName:"msubsup"},"f"),(0,s.kt)("mn",{parentName:"msubsup"},"0"))),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"\\Delta_{f}^{0}")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"1.2333em",verticalAlign:"-0.4192em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},(0,s.kt)("span",{parentName:"span",className:"mord"},"\u0394"),(0,s.kt)("span",{parentName:"span",className:"msupsub"},(0,s.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.8141em"}},(0,s.kt)("span",{parentName:"span",style:{top:"-2.4169em",marginLeft:"0em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mathnormal mtight",style:{marginRight:"0.10764em"}},"f")))),(0,s.kt)("span",{parentName:"span",style:{top:"-3.063em",marginRight:"0.05em"}},(0,s.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,s.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},(0,s.kt)("span",{parentName:"span",className:"mord mtight"},"0"))))),(0,s.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,s.kt)("span",{parentName:"span",className:"vlist-r"},(0,s.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.4192em"}},(0,s.kt)("span",{parentName:"span"}))))))))))," is defined as a constant ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"F")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"F")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"F")))))," multiplied by ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mn",{parentName:"mrow"},"1"),(0,s.kt)("mo",{parentName:"mrow"},"+"),(0,s.kt)("mi",{parentName:"mrow"},"E")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"1+E")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.7278em",verticalAlign:"-0.0833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord"},"1"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}}),(0,s.kt)("span",{parentName:"span",className:"mbin"},"+"),(0,s.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2222em"}})),(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.05764em"}},"E"))))),"\n(",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"E")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"E")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.05764em"}},"E")))))," being the total max number of endorsements in a block, currently 16), and ",(0,s.kt)("span",{parentName:"p",className:"math math-inline"},(0,s.kt)("span",{parentName:"span",className:"katex"},(0,s.kt)("span",{parentName:"span",className:"katex-mathml"},(0,s.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,s.kt)("semantics",{parentName:"math"},(0,s.kt)("mrow",{parentName:"semantics"},(0,s.kt)("mi",{parentName:"mrow"},"F")),(0,s.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"F")))),(0,s.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,s.kt)("span",{parentName:"span",className:"base"},(0,s.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6833em"}}),(0,s.kt)("span",{parentName:"span",className:"mord mathnormal",style:{marginRight:"0.13889em"}},"F")))))," effectively measuring the maximum span in fully endorsed blocks of a successful blockclique, or the number of fully endorsed blocks by which an alternative clique can be shorter than the blockclique before its blocks may be discarded as stale."),(0,s.kt)("h3",{id:"graphconsensus-module-function"},"Graph/Consensus Module Function"),(0,s.kt)("p",null,"The Consensus Module (formerly known as the Graph) receives new block proposals, integrates them into the set of pending blocks,\nupdating the blockclique with the method explained above, and verifying the legitimacy of the parenting of new blocks. It also\ninforms other modules, like the Execution module, when blocks are finalized and the corresponding ledger modifications implied\nby their operations list should be made permanent."),(0,s.kt)("p",null,"It is also able to answer queries about the current best parents for a new block (based on the current blockclique) or the list\nof current maximal cliques."),(0,s.kt)("h2",{id:"execution-module"},"Execution Module"),(0,s.kt)("p",null,"The Execution Module is in charge of effectively executing the operations contained in blocks within the current blockclique,\nwhich is provided by the Graph/Consensus Module. Operations will typically modify the ledger, either by changing the balances\nof accounts or by modifying the datastore of smart contracts after the execution of some code. From an implementation point\nof view, ledger modifications are however stored as diff vs the current finalized ledger, until the corresponding blocks are\nmarked as finalized by the Graph/Consensus Module."),(0,s.kt)("p",null,"Block creators will typically need to query the Execution Module to check current balances at a given slot and verify if some\noperations can be run with sufficient funds or not, before being integrated into a new block."),(0,s.kt)("p",null,"As a side note, it is also possible that blocks might include invalid operations, in which case the Execution Module will\nsimply ignore them."),(0,s.kt)("p",null,"Being the maintainer of the ledger, the Execution Module is also queried about address information in general, via the API,\nfor any Module that needs it."),(0,s.kt)("p",null,"Finally, the Execution Module will inform the Selector Module when new cycles are initiated as the finalization of blocks\nprogresses."),(0,s.kt)("h2",{id:"pool-module"},"Pool Module"),(0,s.kt)("p",null,"When new pending operations reach a node, they are not immediately processed but instead are stored in a pool of pending operations,\nto be used by the Factory Module. Similarly, proposed endorsements coming from the Endorsement Factory are buffered inside the pool,\nto be integrated into new blocks by the Block Factory Module."),(0,s.kt)("p",null,"The origin of pending operations or endorsements inside the pool can be internal to the factory process or could come from remote\nnodes via the API Module. Similarly, locally produced pending endorsements are broadcasted via a gossip protocol to other pools\nvia the API Module."),(0,s.kt)("p",null,"Note that operations stored in the Pool are naturally discarded after a certain time, since operations come with an expiration\ndate in the ",(0,s.kt)("em",{parentName:"p"},"expiration_period")," field. Still, some potential attacks can occur by trying to flood the pool with high fees\noperations that have no chance of being executed because the corresponding account does not have the required funds.\nDiscussing about countermeasure for this is beyond the scope of this introduction."),(0,s.kt)("h2",{id:"blockendorsement-factory-module"},"Block/Endorsement Factory Module"),(0,s.kt)("p",null,"The Block Factory Module is in charge of creating new blocks when the corresponding node address has been designated to\nbe the block creator for a given slot. This information is provided to the Factory Module from the Selector Module via\nthe API Module."),(0,s.kt)("p",null,"The Block Factory Module also needs information about the best parents (made of the latest blocks in each thread in\nthe blockclique) from the Graph/Consensus Module. These parents will be included in the newly created block. Balance\ninformation, in order to assess the validity of pending operations, is obtained from the Execution Module, which\nmaintains the ledger state from the point of view of the slot where the new block is supposed to be created."),(0,s.kt)("p",null,"The Block Factory Module picks pending operations from the Pool Module. Note that the Block Factory will regularly\nquery the Execution Module about finalized and executed operations, and internally cleanup operations that have been handled."),(0,s.kt)("p",null,"Finally, the Block Factory will query the Pool Module and pick pending endorsements corresponding to the best parents\nthat are selected for the block."),(0,s.kt)("p",null,"With this information, it is able to forge a new block that will then be propagated to the Graph/Consensus Module\nvia the API Module, as well as to other nodes via gossip, to maintain a global synchronized state."),(0,s.kt)("p",null,"The Endorsement Factory Module works in a similar manner, requesting the Selector Module to find out when it has been\ndesignated to be an endorsement producer, then feeding new endorsements to the Pool Module and the API Module for global synchronization."))}h.isMDXComponent=!0},9270:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/architecture-4a1209c66babdf0750ff11fb839724b3.svg"},9645:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/cliques-1ea940b8535eb8b547c71482653edeee.svg"},3509:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/incompatibility_graph-3d0cbae75657b115b202ef3d216b2f86.svg"},4246:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/selector-e621b755dcea738530297fb7760b5f31.svg"},1440:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/unfinalized_blocks_set-dfbeffb53e6ae2f5096aac0c02c8c7b6.svg"}}]); \ No newline at end of file diff --git a/assets/js/13601854.fac1bb19.js b/assets/js/13601854.8b81edd3.js similarity index 57% rename from assets/js/13601854.fac1bb19.js rename to assets/js/13601854.8b81edd3.js index 22039aefa..7f0e94ac0 100644 --- a/assets/js/13601854.fac1bb19.js +++ b/assets/js/13601854.8b81edd3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[7570],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),m=a,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var r=n(7462),a=(n(7294),n(3905));const o={id:"prerequisites",sidebar_label:"Prerequisites"},i="Prerequisites",s={unversionedId:"build/smart-contract/prerequisites",id:"build/smart-contract/prerequisites",title:"Prerequisites",description:"Before you can begin developing smart contracts on the Massa blockchain, you'll need to ensure that your development environment meets the following requirements:",source:"@site/docs/build/smart-contract/prerequisites.md",sourceDirName:"build/smart-contract",slug:"/build/smart-contract/prerequisites",permalink:"/docs/build/smart-contract/prerequisites",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/smart-contract/prerequisites.md",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"prerequisites",sidebar_label:"Prerequisites"},sidebar:"buildSidebar",previous:{title:"Introduction",permalink:"/docs/build/smart-contract/intro"},next:{title:"WebAssembly Module",permalink:"/docs/build/smart-contract/webassembly-module"}},l={},c=[],p={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"Before you can begin developing smart contracts on the Massa blockchain, you'll need to ensure that your development environment meets the following requirements:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://nodejs.org/en/"},"Node.js")," installed on your system.")),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"We recommend updating Node.js and npm to the latest version for best performance and security."),(0,a.kt)("p",{parentName:"admonition"},"To update npm, run the following commands:"),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre",className:"language-shell"},"npm install -g npm\n")),(0,a.kt)("p",{parentName:"admonition"},"To update Node.js, the recommended way is to use ",(0,a.kt)("inlineCode",{parentName:"p"},"n"),", the Node.js version manager.\nIf you do not already have ",(0,a.kt)("inlineCode",{parentName:"p"},"n")," installed, you can install it with the following command:"),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre",className:"language-shell"},"npm install -g n\n")),(0,a.kt)("p",{parentName:"admonition"},"Once ",(0,a.kt)("inlineCode",{parentName:"p"},"n")," is installed, you can update to the latest version of Node.js with the following command:"),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre",className:"language-shell"},"n latest\n"))),(0,a.kt)("p",null,"Once you have an up-to-date Node.js, you're ready to start developing smart contracts on the Massa blockchain."))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[7570],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>f});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(n),m=a,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(f,i(i({ref:t},p),{},{components:n})):r.createElement(f,i({ref:t},p))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var r=n(7462),a=(n(7294),n(3905));const o={id:"prerequisites",sidebar_label:"Prerequisites"},i="Prerequisites",s={unversionedId:"build/smart-contract/prerequisites",id:"build/smart-contract/prerequisites",title:"Prerequisites",description:"Before you can begin developing smart contracts on the Massa blockchain, you'll need to ensure that your development environment meets the following requirements:",source:"@site/docs/build/smart-contract/prerequisites.md",sourceDirName:"build/smart-contract",slug:"/build/smart-contract/prerequisites",permalink:"/docs/build/smart-contract/prerequisites",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/smart-contract/prerequisites.md",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"prerequisites",sidebar_label:"Prerequisites"},sidebar:"buildSidebar",previous:{title:"Introduction",permalink:"/docs/build/smart-contract/intro"},next:{title:"WebAssembly Module",permalink:"/docs/build/smart-contract/webassembly-module"}},l={},c=[],p={toc:c},u="wrapper";function d(e){let{components:t,...n}=e;return(0,a.kt)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"prerequisites"},"Prerequisites"),(0,a.kt)("p",null,"Before you can begin developing smart contracts on the Massa blockchain, you'll need to ensure that your development environment meets the following requirements:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://nodejs.org/en/"},"Node.js")," installed on your system.")),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"We recommend updating Node.js and npm to the latest version for best performance and security."),(0,a.kt)("p",{parentName:"admonition"},"To update npm, run the following commands:"),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre",className:"language-shell"},"npm install -g npm\n")),(0,a.kt)("p",{parentName:"admonition"},"To update Node.js, the recommended way is to use ",(0,a.kt)("inlineCode",{parentName:"p"},"n"),", the Node.js version manager.\nIf you do not already have ",(0,a.kt)("inlineCode",{parentName:"p"},"n")," installed, you can install it with the following command:"),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre",className:"language-shell"},"npm install -g n\n")),(0,a.kt)("p",{parentName:"admonition"},"Once ",(0,a.kt)("inlineCode",{parentName:"p"},"n")," is installed, you can update to the latest version of Node.js with the following command:"),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre",className:"language-shell"},"n latest\n"))),(0,a.kt)("p",null,"Once you have an up-to-date Node.js, you're ready to start developing smart contracts on the Massa blockchain."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/14161a26.690cf56f.js b/assets/js/14161a26.690cf56f.js new file mode 100644 index 000000000..8518265cb --- /dev/null +++ b/assets/js/14161a26.690cf56f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[7046],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>b});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=c(r),u=a,b=m["".concat(l,".").concat(u)]||m[u]||d[u]||o;return r?n.createElement(b,s(s({ref:t},p),{},{components:r})):n.createElement(b,s({ref:t},p))}));function b(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,s=new Array(o);s[0]=u;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[m]="string"==typeof e?e:a,s[1]=i;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>d,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var n=r(7462),a=(r(7294),r(3905));const o={id:"webassembly-module",sidebar_label:"WebAssembly Module"},s="WebAssembly Module",i={unversionedId:"build/smart-contract/webassembly-module",id:"build/smart-contract/webassembly-module",title:"WebAssembly Module",description:"Each smart contract is a WebAssembly module with exported functions, and has access to specific node ABIs. We will see these ABIs in the next chapter.",source:"@site/docs/build/smart-contract/webassembly-module.md",sourceDirName:"build/smart-contract",slug:"/build/smart-contract/webassembly-module",permalink:"/docs/build/smart-contract/webassembly-module",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/smart-contract/webassembly-module.md",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"webassembly-module",sidebar_label:"WebAssembly Module"},sidebar:"buildSidebar",previous:{title:"Prerequisites",permalink:"/docs/build/smart-contract/prerequisites"},next:{title:"AS SDK",permalink:"/docs/build/smart-contract/sdk"}},l={},c=[],p={toc:c},m="wrapper";function d(e){let{components:t,...r}=e;return(0,a.kt)(m,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"webassembly-module"},"WebAssembly Module"),(0,a.kt)("p",null,"Each smart contract is a WebAssembly module with exported functions, and has access to specific node ABIs. We will see these ABIs in the next chapter."),(0,a.kt)("p",null,"WebAssembly code is compiled from AssemblyScript, a language created specifically for WebAssembly."),(0,a.kt)("p",null,"AssemblyScript is very similar to TypeScript, but there are some important differences to keep in mind.\nFor example, the basic types in AssemblyScript directly expose all integer and floating-point types available in WebAssembly.\nUnion types and optional arguments/properties are not supported in AssemblyScript, and all objects are statically typed and do not allow for dynamically changing properties.\nAdditionally, AssemblyScript does not support exceptions catching or closures yet."),(0,a.kt)("p",null,"To learn more about AssemblyScript, WebAssembly modules, and ABIs, we invite you to check out the following resources:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://assemblyscript.org/"},"AssemblyScript home page"),", ",(0,a.kt)("a",{parentName:"li",href:"https://www.assemblyscript.org/introduction.html"},"its book")," and ",(0,a.kt)("a",{parentName:"li",href:"https://www.assemblyscript.org/introduction.html#from-a-javascript-perspective"},"its introduction from a JS perspective"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://webassembly.org/"},"WebAssembly home page")," and ",(0,a.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/WebAssembly"},"MDN version"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://en.wikipedia.org/wiki/Application_binary_interface"},"Wikipedia explaination of the concept of ABI"),".")),(0,a.kt)("admonition",{type:"caution"},(0,a.kt)("p",{parentName:"admonition"},"Do not initialize a smart contract project following AssemblyScript documentation. It will be unnecessarily painful. Go back to the the ",(0,a.kt)("a",{parentName:"p",href:"/docs/build/hello-world-dapp"},'"Hello, World" dApp tutorial')," or use the following command:"),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre",className:"language-shell"},"npx clear-npx-cache && npx @massalabs/sc-project-initializer@buildnet init my-first-sc && cd my-first-sc\n"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/14161a26.6b096048.js b/assets/js/14161a26.6b096048.js deleted file mode 100644 index ddbb4e136..000000000 --- a/assets/js/14161a26.6b096048.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[7046],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>b});var a=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function s(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),c=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=c(r),u=n,b=m["".concat(l,".").concat(u)]||m[u]||d[u]||o;return r?a.createElement(b,s(s({ref:t},p),{},{components:r})):a.createElement(b,s({ref:t},p))}));function b(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,s=new Array(o);s[0]=u;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[m]="string"==typeof e?e:n,s[1]=i;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>d,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var a=r(7462),n=(r(7294),r(3905));const o={id:"webassembly-module",sidebar_label:"WebAssembly Module"},s="WebAssembly Module",i={unversionedId:"build/smart-contract/webassembly-module",id:"build/smart-contract/webassembly-module",title:"WebAssembly Module",description:"Each smart contract is a WebAssembly module with exported functions, and has access to specific node ABIs. We will see these ABIs in the next chapter.",source:"@site/docs/build/smart-contract/webassembly-module.md",sourceDirName:"build/smart-contract",slug:"/build/smart-contract/webassembly-module",permalink:"/docs/build/smart-contract/webassembly-module",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/smart-contract/webassembly-module.md",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"webassembly-module",sidebar_label:"WebAssembly Module"},sidebar:"buildSidebar",previous:{title:"Prerequisites",permalink:"/docs/build/smart-contract/prerequisites"},next:{title:"AS SDK",permalink:"/docs/build/smart-contract/sdk"}},l={},c=[],p={toc:c},m="wrapper";function d(e){let{components:t,...r}=e;return(0,n.kt)(m,(0,a.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h1",{id:"webassembly-module"},"WebAssembly Module"),(0,n.kt)("p",null,"Each smart contract is a WebAssembly module with exported functions, and has access to specific node ABIs. We will see these ABIs in the next chapter."),(0,n.kt)("p",null,"WebAssembly code is compiled from AssemblyScript, a language created specifically for WebAssembly."),(0,n.kt)("p",null,"AssemblyScript is very similar to TypeScript, but there are some important differences to keep in mind.\nFor example, the basic types in AssemblyScript directly expose all integer and floating-point types available in WebAssembly.\nUnion types and optional arguments/properties are not supported in AssemblyScript, and all objects are statically typed and do not allow for dynamically changing properties.\nAdditionally, AssemblyScript does not support exceptions catching or closures yet."),(0,n.kt)("p",null,"To learn more about AssemblyScript, WebAssembly modules, and ABIs, we invite you to check out the following resources:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://assemblyscript.org/"},"AssemblyScript home page"),", ",(0,n.kt)("a",{parentName:"li",href:"https://www.assemblyscript.org/introduction.html"},"its book")," and ",(0,n.kt)("a",{parentName:"li",href:"https://www.assemblyscript.org/introduction.html#from-a-javascript-perspective"},"its introduction from a JS perspective"),"."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://webassembly.org/"},"WebAssembly home page")," and ",(0,n.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/en-US/docs/WebAssembly"},"MDN version"),"."),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://en.wikipedia.org/wiki/Application_binary_interface"},"Wikipedia explaination of the concept of ABI"),".")),(0,n.kt)("admonition",{type:"caution"},(0,n.kt)("p",{parentName:"admonition"},"Do not initialize a smart contract project following AssemblyScript documentation. It will be unnecessarily painful. Go back to the the ",(0,n.kt)("a",{parentName:"p",href:"/docs/build/hello-world-dapp"},'"Hello, World" dApp tutorial')," or use the following command:"),(0,n.kt)("pre",{parentName:"admonition"},(0,n.kt)("code",{parentName:"pre",className:"language-shell"},"npx clear-npx-cache && npx @massalabs/sc-project-initializer@buildnet init my-first-sc && cd my-first-sc\n"))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1d3e2afe.4d0ca5b8.js b/assets/js/1d3e2afe.4d0ca5b8.js new file mode 100644 index 000000000..add8abeb2 --- /dev/null +++ b/assets/js/1d3e2afe.4d0ca5b8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[2552],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>f});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function s(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,s=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=c(a),p=r,f=u["".concat(l,".").concat(p)]||u[p]||m[p]||s;return a?n.createElement(f,o(o({ref:t},d),{},{components:a})):n.createElement(f,o({ref:t},d))}));function f(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=a.length,o=new Array(s);o[0]=p;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:r,o[1]=i;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>m,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var n=a(7462),r=(a(7294),a(3905));const s={id:"standards",sidebar_label:"Standards"},o="Massa Standard",i={unversionedId:"build/standards",id:"build/standards",title:"Massa Standard",description:"The Massa Standard is your comprehensive starting point for blockchain projects on the Massa network. Offering reference implementations of the most common smart contracts, it's the toolkit you need for tokens, NFTs, or wallet creation.",source:"@site/docs/build/standards.md",sourceDirName:"build",slug:"/build/standards",permalink:"/docs/build/standards",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/standards.md",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"standards",sidebar_label:"Standards"},sidebar:"buildSidebar",previous:{title:"gRPC",permalink:"/docs/build/api/grpc"}},l={},c=[{value:"Fungible Tokens (FT)",id:"fungible-tokens-ft",level:2},{value:"Non-Fungible Tokens (NFT)",id:"non-fungible-tokens-nft",level:2},{value:"Massa Domain Name Service (DNS)",id:"massa-domain-name-service-dns",level:2},{value:"Massa Units Standard",id:"massa-units-standard",level:2}],d={toc:c},u="wrapper";function m(e){let{components:t,...a}=e;return(0,r.kt)(u,(0,n.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"massa-standard"},"Massa Standard"),(0,r.kt)("p",null,"The Massa Standard is your comprehensive starting point for blockchain projects on the Massa network. Offering reference implementations of the most common smart contracts, it's the toolkit you need for tokens, NFTs, or wallet creation."),(0,r.kt)("p",null,"Adhering to a standard like this in the blockchain world is important. Standards ensure all participants in a blockchain network can interact seamlessly because they follow a unified structure and protocol. This compatibility fosters a more robust and inclusive blockchain ecosystem, encouraging mass adoption and facilitating growth."),(0,r.kt)("h2",{id:"fungible-tokens-ft"},"Fungible Tokens (FT)"),(0,r.kt)("p",null,"FT is a standard for creating fungible, tradable tokens on the Massa blockchain. It includes a set of functions that allow for seamless interaction with tokens within smart contracts and wallets."),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/massalabs/massa-standards/tree/main/smart-contracts/assembly/contracts/FT"},"View on GitHub")),(0,r.kt)("h2",{id:"non-fungible-tokens-nft"},"Non-Fungible Tokens (NFT)"),(0,r.kt)("p",null,"NFT is a standard for creating unique, non-fungible tokens on the Massa blockchain. This allows the creation and management of tokens where each instance has a unique value or properties."),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/massalabs/massa-standards/tree/main/smart-contracts/assembly/contracts/NFT"},"View on GitHub")),(0,r.kt)("h2",{id:"massa-domain-name-service-dns"},"Massa Domain Name Service (DNS)"),(0,r.kt)("p",null,"The DNS standard provides a foundational framework for managing Domain Name System (DNS) records within the Massa blockchain ecosystem. It streamlines the creation of a link between the hostname (website name), resolver address (where the smart contract and chunks of the website are located), and the DNS record owner."),(0,r.kt)("h2",{id:"massa-units-standard"},"Massa Units Standard"),(0,r.kt)("p",null,"The Massa Units standard defines common units of measurement for the Massa blockchain, including:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"Massa coin")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"Gas")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"Rolls"))),(0,r.kt)("p",null,"Learn more about ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/massalabs/massa-standards/blob/main/units.md"},"Massa Units Standard")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1d3e2afe.ae7f2f1d.js b/assets/js/1d3e2afe.ae7f2f1d.js deleted file mode 100644 index ea6b0a3e4..000000000 --- a/assets/js/1d3e2afe.ae7f2f1d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[2552],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>f});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function s(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},d=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,s=e.originalType,l=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=c(a),p=r,f=u["".concat(l,".").concat(p)]||u[p]||m[p]||s;return a?n.createElement(f,o(o({ref:t},d),{},{components:a})):n.createElement(f,o({ref:t},d))}));function f(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=a.length,o=new Array(s);o[0]=p;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:r,o[1]=i;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>m,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var n=a(7462),r=(a(7294),a(3905));const s={id:"standards",sidebar_label:"Standards"},o="Massa Standard",i={unversionedId:"build/standards",id:"build/standards",title:"Massa Standard",description:"The Massa Standard is your comprehensive starting point for blockchain projects on the Massa network. Offering reference implementations of the most common smart contracts, it's the toolkit you need for tokens, NFTs, or wallet creation.",source:"@site/docs/build/standards.md",sourceDirName:"build",slug:"/build/standards",permalink:"/docs/build/standards",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/standards.md",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"standards",sidebar_label:"Standards"},sidebar:"buildSidebar",previous:{title:"gRPC",permalink:"/docs/build/api/grpc"}},l={},c=[{value:"Fungible Tokens (FT)",id:"fungible-tokens-ft",level:2},{value:"Non-Fungible Tokens (NFT)",id:"non-fungible-tokens-nft",level:2},{value:"Massa Domain Name Service (DNS)",id:"massa-domain-name-service-dns",level:2},{value:"Massa Units Standard",id:"massa-units-standard",level:2}],d={toc:c},u="wrapper";function m(e){let{components:t,...a}=e;return(0,r.kt)(u,(0,n.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"massa-standard"},"Massa Standard"),(0,r.kt)("p",null,"The Massa Standard is your comprehensive starting point for blockchain projects on the Massa network. Offering reference implementations of the most common smart contracts, it's the toolkit you need for tokens, NFTs, or wallet creation."),(0,r.kt)("p",null,"Adhering to a standard like this in the blockchain world is important. Standards ensure all participants in a blockchain network can interact seamlessly because they follow a unified structure and protocol. This compatibility fosters a more robust and inclusive blockchain ecosystem, encouraging mass adoption and facilitating growth."),(0,r.kt)("h2",{id:"fungible-tokens-ft"},"Fungible Tokens (FT)"),(0,r.kt)("p",null,"FT is a standard for creating fungible, tradable tokens on the Massa blockchain. It includes a set of functions that allow for seamless interaction with tokens within smart contracts and wallets."),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/massalabs/massa-standards/tree/main/smart-contracts/assembly/contracts/FT"},"View on GitHub")),(0,r.kt)("h2",{id:"non-fungible-tokens-nft"},"Non-Fungible Tokens (NFT)"),(0,r.kt)("p",null,"NFT is a standard for creating unique, non-fungible tokens on the Massa blockchain. This allows the creation and management of tokens where each instance has a unique value or properties."),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://github.com/massalabs/massa-standards/tree/main/smart-contracts/assembly/contracts/NFT"},"View on GitHub")),(0,r.kt)("h2",{id:"massa-domain-name-service-dns"},"Massa Domain Name Service (DNS)"),(0,r.kt)("p",null,"The DNS standard provides a foundational framework for managing Domain Name System (DNS) records within the Massa blockchain ecosystem. It streamlines the creation of a link between the hostname (website name), resolver address (where the smart contract and chunks of the website are located), and the DNS record owner."),(0,r.kt)("h2",{id:"massa-units-standard"},"Massa Units Standard"),(0,r.kt)("p",null,"The Massa Units standard defines common units of measurement for the Massa blockchain, including:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"Massa coin")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"Gas")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("p",{parentName:"li"},"Rolls"))),(0,r.kt)("p",null,"Learn more about ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/massalabs/massa-standards/blob/main/units.md"},"Massa Units Standard")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/21529a4e.3994a2b5.js b/assets/js/21529a4e.3994a2b5.js deleted file mode 100644 index 72cd236fa..000000000 --- a/assets/js/21529a4e.3994a2b5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[2595],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>f});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=o.createContext({}),s=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,c=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=s(n),h=a,f=p["".concat(c,".").concat(h)]||p[h]||u[h]||r;return n?o.createElement(f,i(i({ref:t},d),{},{components:n})):o.createElement(f,i({ref:t},d))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=h;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[p]="string"==typeof e?e:a,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var o=n(7462),a=(n(7294),n(3905));const r={id:"operation-lifecycle",sidebar_label:"Operation lifecycle"},i="Operation lifecycle",l={unversionedId:"learn/architecture/operation-lifecycle",id:"learn/architecture/operation-lifecycle",title:"Operation lifecycle",description:"After learning about the Basic concepts and Massa's node architecture, we have all the elements and vocabulary",source:"@site/docs/learn/architecture/operation-lifecycle.mdx",sourceDirName:"learn/architecture",slug:"/learn/architecture/operation-lifecycle",permalink:"/docs/learn/architecture/operation-lifecycle",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/learn/architecture/operation-lifecycle.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"operation-lifecycle",sidebar_label:"Operation lifecycle"},sidebar:"learnSidebar",previous:{title:"Node architecture",permalink:"/docs/learn/architecture/node-architecture"},next:{title:"Consensus quality initiatives",permalink:"/docs/learn/architecture/consensus-quality"}},c={},s=[],d={toc:s},p="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(p,(0,o.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"operation-lifecycle"},"Operation lifecycle"),(0,a.kt)("p",null,"After learning about the Basic concepts and Massa's node architecture, we have all the elements and vocabulary\nin place to explore the lifecycle of an operation within the network; from creation to permanent execution in\na finalized block."),(0,a.kt)("p",null,"Operations originate externally from a client that is forging the operation, for example: a transaction or a\nsmart contract code execution. The client will have to know the IP address of a Massa Node (this can be either\nbecause it is a node itself and will simply use localhost, or via some maintained list of known nodes and/or\nsome browser plugin), and will then send the operation to the API."),(0,a.kt)("p",null,"When an operation is made available in a given node, it will be broadcasted to all other nodes via the Protocol/Network\nModule and to factories via the API Module, so that it will eventually end up in all the Pool Modules of the network."),(0,a.kt)("p",null,"Let\u2019s assume we just got a code execution operation from an external client. Let\u2019s suppose the client knows a\nparticular node, which is running its block factory on the same machine, and sends the operation to this node.\nThese are the different steps of the operation processing that will occur, as illustrated in the schema below:"),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(9677).Z,width:"1041",height:"1041"})),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The operation enters the node via the API Module (the operation path is marked in blue)")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The API Module forwards the operation to the Pool Module and broadcasts it to other nodes via the Protocol/Network\nModule. Other nodes hearing about it will also broadcast it (gossip protocol), and feed it to their Pool Module.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"At that stage, the operation sits in the Pool Modules of most nodes")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The Selector Module elects a particular node to handle the block production of the next current slot")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The elected node Block Factory finds out about its election by querying a Selector Module")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"It starts building a block by picking up pending operations in the Pool Module. The original operation is\neventually picked and integrated into the block. It's worth to mention that only operations created by an address within the same thread as the block can be included. This is known as a 'transaction sharding' technique and it's used to prevent double spending problem. We will now follow the block around (the block path is marked in green)")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The newly produced block is sent to the Graph/Consensus Module")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The new block is processed by the Graph/Consensus Module to be included into the pending blocks DAG and\npotentially integrated into a new blockclique")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The Graph/Consensus Module sends the new block to other nodes via the Protocol/Network Module, to ensure\nsynchronization of the information in the network. The new block reaching other nodes is similarly going to be integrated into their Graph/Consensus Module")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"In general, the blockclique will be extended with the new block and so will reach the Execution Module\nfrom the Graph/Consensus Module via the notification of a new blockclique. Eventually, it will also be notified\nas a final block if it gets finalized.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The Execution Module will run the blocks that are part of the updated blockclique, so the original block\nwill eventually be executed. Within the block is the original operation that was originally sent and that will\nthen be applied to the ledger for potential modifications. At this stage, the modifications are not permanent and\nsimply stored in a diff compared to the finalized ledger")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Eventually, the block will be marked as final and the ledger modification, including the operation changes,\nwill become final in the finalized ledger."))))}u.isMDXComponent=!0},9677:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/operation_lifecycle-201746987c637edaf2d8a3cf760c993a.svg"}}]); \ No newline at end of file diff --git a/assets/js/21529a4e.dccd2915.js b/assets/js/21529a4e.dccd2915.js new file mode 100644 index 000000000..73e1cd24c --- /dev/null +++ b/assets/js/21529a4e.dccd2915.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[2595],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>f});var o=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=o.createContext({}),s=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,c=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=s(n),h=a,f=p["".concat(c,".").concat(h)]||p[h]||u[h]||r;return n?o.createElement(f,i(i({ref:t},d),{},{components:n})):o.createElement(f,i({ref:t},d))}));function f(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=h;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[p]="string"==typeof e?e:a,i[1]=l;for(var s=2;s{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var o=n(7462),a=(n(7294),n(3905));const r={id:"operation-lifecycle",sidebar_label:"Operation lifecycle"},i="Operation lifecycle",l={unversionedId:"learn/architecture/operation-lifecycle",id:"learn/architecture/operation-lifecycle",title:"Operation lifecycle",description:"After learning about the Basic concepts and Massa's node architecture, we have all the elements and vocabulary",source:"@site/docs/learn/architecture/operation-lifecycle.mdx",sourceDirName:"learn/architecture",slug:"/learn/architecture/operation-lifecycle",permalink:"/docs/learn/architecture/operation-lifecycle",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/learn/architecture/operation-lifecycle.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"operation-lifecycle",sidebar_label:"Operation lifecycle"},sidebar:"learnSidebar",previous:{title:"Node architecture",permalink:"/docs/learn/architecture/node-architecture"},next:{title:"Consensus quality initiatives",permalink:"/docs/learn/architecture/consensus-quality"}},c={},s=[],d={toc:s},p="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(p,(0,o.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"operation-lifecycle"},"Operation lifecycle"),(0,a.kt)("p",null,"After learning about the Basic concepts and Massa's node architecture, we have all the elements and vocabulary\nin place to explore the lifecycle of an operation within the network; from creation to permanent execution in\na finalized block."),(0,a.kt)("p",null,"Operations originate externally from a client that is forging the operation, for example: a transaction or a\nsmart contract code execution. The client will have to know the IP address of a Massa Node (this can be either\nbecause it is a node itself and will simply use localhost, or via some maintained list of known nodes and/or\nsome browser plugin), and will then send the operation to the API."),(0,a.kt)("p",null,"When an operation is made available in a given node, it will be broadcasted to all other nodes via the Protocol/Network\nModule and to factories via the API Module, so that it will eventually end up in all the Pool Modules of the network."),(0,a.kt)("p",null,"Let\u2019s assume we just got a code execution operation from an external client. Let\u2019s suppose the client knows a\nparticular node, which is running its block factory on the same machine, and sends the operation to this node.\nThese are the different steps of the operation processing that will occur, as illustrated in the schema below:"),(0,a.kt)("p",null,(0,a.kt)("img",{src:n(9677).Z,width:"1041",height:"1041"})),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The operation enters the node via the API Module (the operation path is marked in blue)")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The API Module forwards the operation to the Pool Module and broadcasts it to other nodes via the Protocol/Network\nModule. Other nodes hearing about it will also broadcast it (gossip protocol), and feed it to their Pool Module.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"At that stage, the operation sits in the Pool Modules of most nodes")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The Selector Module elects a particular node to handle the block production of the next current slot")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The elected node Block Factory finds out about its election by querying a Selector Module")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"It starts building a block by picking up pending operations in the Pool Module. The original operation is\neventually picked and integrated into the block. It's worth to mention that only operations created by an address within the same thread as the block can be included. This is known as a 'transaction sharding' technique and it's used to prevent double spending problem. We will now follow the block around (the block path is marked in green)")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The newly produced block is sent to the Graph/Consensus Module")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The new block is processed by the Graph/Consensus Module to be included into the pending blocks DAG and\npotentially integrated into a new blockclique")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The Graph/Consensus Module sends the new block to other nodes via the Protocol/Network Module, to ensure\nsynchronization of the information in the network. The new block reaching other nodes is similarly going to be integrated into their Graph/Consensus Module")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"In general, the blockclique will be extended with the new block and so will reach the Execution Module\nfrom the Graph/Consensus Module via the notification of a new blockclique. Eventually, it will also be notified\nas a final block if it gets finalized.")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"The Execution Module will run the blocks that are part of the updated blockclique, so the original block\nwill eventually be executed. Within the block is the original operation that was originally sent and that will\nthen be applied to the ledger for potential modifications. At this stage, the modifications are not permanent and\nsimply stored in a diff compared to the finalized ledger")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("p",{parentName:"li"},"Eventually, the block will be marked as final and the ledger modification, including the operation changes,\nwill become final in the finalized ledger."))))}u.isMDXComponent=!0},9677:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/operation_lifecycle-201746987c637edaf2d8a3cf760c993a.svg"}}]); \ No newline at end of file diff --git a/assets/js/233a18d6.6631165d.js b/assets/js/233a18d6.6631165d.js new file mode 100644 index 000000000..d60108167 --- /dev/null +++ b/assets/js/233a18d6.6631165d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[2626],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>f});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),l=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},u=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},m="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),m=l(a),d=r,f=m["".concat(c,".").concat(d)]||m[d]||p[d]||o;return a?n.createElement(f,s(s({ref:t},u),{},{components:a})):n.createElement(f,s({ref:t},u))}));function f(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,s=new Array(o);s[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[m]="string"==typeof e?e:r,s[1]=i;for(var l=2;l{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>p,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var n=a(7462),r=(a(7294),a(3905));const o={id:"use-cases",sidebar_label:"Use-cases"},s="Use-cases & Applications",i={unversionedId:"learn/asc/use-cases",id:"learn/asc/use-cases",title:"Use-cases & Applications",description:"Autonomous smart contracts offers a wide range of compelling use-cases that were either impossible, too costly, or risky to do with benchmark are met.",source:"@site/docs/learn/asc/use-cases.mdx",sourceDirName:"learn/asc",slug:"/learn/asc/use-cases",permalink:"/docs/learn/asc/use-cases",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/learn/asc/use-cases.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"use-cases",sidebar_label:"Use-cases"},sidebar:"learnSidebar",previous:{title:"Autonomous Smart Contracts",permalink:"/docs/learn/asc/massa-asc"},next:{title:"Decentralized Web",permalink:"/docs/learn/decentralized-web"}},c={},l=[{value:"Going further",id:"going-further",level:2}],u={toc:l},m="wrapper";function p(e){let{components:t,...a}=e;return(0,r.kt)(m,(0,n.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"use-cases--applications"},"Use-cases & Applications"),(0,r.kt)("p",null,"Autonomous smart contracts offers a wide range of compelling use-cases that were either impossible, too costly, or risky to do with benchmark are met."),(0,r.kt)("p",null,"Here are some of the best use cases for autonomous smart contracts:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},"Decentralized Finance (DeFi)"),": Autonomous smart contracts can revolutionize DeFi applications by enabling automated and self-executing actions. Some notable use cases include:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Automated liquidations: Smart contracts can automatically trigger the liquidation of under-collateralized positions in lending protocols when predetermined thresholds are breached."),(0,r.kt)("li",{parentName:"ul"},"Yield farming strategies: Contracts can autonomously perform yield farming strategies, automatically swapping and reinvesting tokens based on predefined conditions."),(0,r.kt)("li",{parentName:"ul"},"Dynamic portfolio rebalancing: Smart contracts can automatically adjust portfolio allocations based on market conditions, ensuring desired asset ratios are maintained."))),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},"Supply Chain Management"),": Autonomous smart contracts have the potential to streamline supply chain processes by automating specific actions triggered by predefined conditions. Key use cases include:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Automatic inventory management: Contracts can initiate purchase orders or trigger production when inventory levels reach predefined thresholds, ensuring optimal stock levels."),(0,r.kt)("li",{parentName:"ul"},"Quality control and compliance: Smart contracts can autonomously perform quality checks and audits based on predefined criteria, ensuring compliance with standards and regulations."))),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},"Insurance Claims"),": Autonomous smart contracts can revolutionize the insurance industry by automating claims processes. Notable use cases include:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Instant claims settlement: Contracts can automatically trigger claim payments when specific conditions, such as verified damage or loss, are met, accelerating the claims settlement process."),(0,r.kt)("li",{parentName:"ul"},"Parametric insurance: Smart contracts can leverage external data feeds, such as weather or seismic information, to autonomously determine and process claims without human intervention."))),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},"Gaming and NFTs"),": Autonomous smart contracts can bring enhanced functionality and interactivity, and cost-reduction in on-chain execution, to gaming and non-fungible token (NFT) platforms. Key use cases include:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Dynamic NFTs: Contracts can imbue NFTs with evolving characteristics or abilities based on predefined conditions, creating captivating and unique gaming experiences."),(0,r.kt)("li",{parentName:"ul"},"Automated auctions: Contracts can autonomously initiate and manage auctions for rare items, with bidding and settlement executed automatically when predetermined criteria are met."))),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},"Decentralized Autonomous Organizations (DAOs)"),": Autonomous smart contracts are instrumental in enabling self-governance and decision-making within DAOs. Notable use cases include:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Voting and governance: Contracts can autonomously trigger voting processes based on predefined conditions, empowering token holders to participate in important decision-making. There are various applications for this: from voting in local communities to democratic processes in corporate governance."),(0,r.kt)("li",{parentName:"ul"},"Automated fund management: Smart contracts can autonomously allocate funds, distribute dividends, or trigger investments based on predefined rules and performance metrics."))),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},"Real Estate Transactions"),": Smart contracts can streamline various aspects of real estate transactions, increasing efficiency and reducing the need for intermediaries. Key use cases include:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Escrow and payment automation: Contracts can securely hold funds in escrow and automatically release them when specific conditions, such as successful property transfer or completion of milestones, are met."),(0,r.kt)("li",{parentName:"ul"},"Streamlined rental agreements: Contracts can automate rental payments, manage security deposits, and enforce the terms and conditions stipulated in the agreement.")))),(0,r.kt)("p",null,"These examples illustrate just a few of the many compelling use cases for autonomous smart contracts.\nThe self wake-up functionality empowers automated processes, reduces reliance on intermediaries, and enhances efficiency and\ntransparency across diverse industries."),(0,r.kt)("h2",{id:"going-further"},"Going further"),(0,r.kt)("p",null,"If you want to go further and start coding your own autonomous smart contract, head to the ",(0,r.kt)("a",{parentName:"p",href:"/docs/build/home"},"Build section"),"."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/233a18d6.b65d48aa.js b/assets/js/233a18d6.b65d48aa.js deleted file mode 100644 index ad9f6db20..000000000 --- a/assets/js/233a18d6.b65d48aa.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[2626],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>f});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=n.createContext({}),l=function(e){var t=n.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},u=function(e){var t=l(e.components);return n.createElement(c.Provider,{value:t},e.children)},m="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,c=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),m=l(a),d=r,f=m["".concat(c,".").concat(d)]||m[d]||p[d]||o;return a?n.createElement(f,s(s({ref:t},u),{},{components:a})):n.createElement(f,s({ref:t},u))}));function f(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,s=new Array(o);s[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[m]="string"==typeof e?e:r,s[1]=i;for(var l=2;l{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>p,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var n=a(7462),r=(a(7294),a(3905));const o={id:"use-cases",sidebar_label:"Use-cases"},s="Use-cases & Applications",i={unversionedId:"learn/asc/use-cases",id:"learn/asc/use-cases",title:"Use-cases & Applications",description:"Autonomous smart contracts offers a wide range of compelling use-cases that were either impossible, too costly, or risky to do with benchmark are met.",source:"@site/docs/learn/asc/use-cases.mdx",sourceDirName:"learn/asc",slug:"/learn/asc/use-cases",permalink:"/docs/learn/asc/use-cases",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/learn/asc/use-cases.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"use-cases",sidebar_label:"Use-cases"},sidebar:"learnSidebar",previous:{title:"Autonomous Smart Contracts",permalink:"/docs/learn/asc/massa-asc"},next:{title:"Decentralized Web",permalink:"/docs/learn/decentralized-web"}},c={},l=[{value:"Going further",id:"going-further",level:2}],u={toc:l},m="wrapper";function p(e){let{components:t,...a}=e;return(0,r.kt)(m,(0,n.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"use-cases--applications"},"Use-cases & Applications"),(0,r.kt)("p",null,"Autonomous smart contracts offers a wide range of compelling use-cases that were either impossible, too costly, or risky to do with benchmark are met."),(0,r.kt)("p",null,"Here are some of the best use cases for autonomous smart contracts:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},"Decentralized Finance (DeFi)"),": Autonomous smart contracts can revolutionize DeFi applications by enabling automated and self-executing actions. Some notable use cases include:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Automated liquidations: Smart contracts can automatically trigger the liquidation of under-collateralized positions in lending protocols when predetermined thresholds are breached."),(0,r.kt)("li",{parentName:"ul"},"Yield farming strategies: Contracts can autonomously perform yield farming strategies, automatically swapping and reinvesting tokens based on predefined conditions."),(0,r.kt)("li",{parentName:"ul"},"Dynamic portfolio rebalancing: Smart contracts can automatically adjust portfolio allocations based on market conditions, ensuring desired asset ratios are maintained."))),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},"Supply Chain Management"),": Autonomous smart contracts have the potential to streamline supply chain processes by automating specific actions triggered by predefined conditions. Key use cases include:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Automatic inventory management: Contracts can initiate purchase orders or trigger production when inventory levels reach predefined thresholds, ensuring optimal stock levels."),(0,r.kt)("li",{parentName:"ul"},"Quality control and compliance: Smart contracts can autonomously perform quality checks and audits based on predefined criteria, ensuring compliance with standards and regulations."))),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},"Insurance Claims"),": Autonomous smart contracts can revolutionize the insurance industry by automating claims processes. Notable use cases include:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Instant claims settlement: Contracts can automatically trigger claim payments when specific conditions, such as verified damage or loss, are met, accelerating the claims settlement process."),(0,r.kt)("li",{parentName:"ul"},"Parametric insurance: Smart contracts can leverage external data feeds, such as weather or seismic information, to autonomously determine and process claims without human intervention."))),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},"Gaming and NFTs"),": Autonomous smart contracts can bring enhanced functionality and interactivity, and cost-reduction in on-chain execution, to gaming and non-fungible token (NFT) platforms. Key use cases include:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Dynamic NFTs: Contracts can imbue NFTs with evolving characteristics or abilities based on predefined conditions, creating captivating and unique gaming experiences."),(0,r.kt)("li",{parentName:"ul"},"Automated auctions: Contracts can autonomously initiate and manage auctions for rare items, with bidding and settlement executed automatically when predetermined criteria are met."))),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},"Decentralized Autonomous Organizations (DAOs)"),": Autonomous smart contracts are instrumental in enabling self-governance and decision-making within DAOs. Notable use cases include:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Voting and governance: Contracts can autonomously trigger voting processes based on predefined conditions, empowering token holders to participate in important decision-making. There are various applications for this: from voting in local communities to democratic processes in corporate governance."),(0,r.kt)("li",{parentName:"ul"},"Automated fund management: Smart contracts can autonomously allocate funds, distribute dividends, or trigger investments based on predefined rules and performance metrics."))),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},(0,r.kt)("strong",{parentName:"p"},"Real Estate Transactions"),": Smart contracts can streamline various aspects of real estate transactions, increasing efficiency and reducing the need for intermediaries. Key use cases include:"),(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Escrow and payment automation: Contracts can securely hold funds in escrow and automatically release them when specific conditions, such as successful property transfer or completion of milestones, are met."),(0,r.kt)("li",{parentName:"ul"},"Streamlined rental agreements: Contracts can automate rental payments, manage security deposits, and enforce the terms and conditions stipulated in the agreement.")))),(0,r.kt)("p",null,"These examples illustrate just a few of the many compelling use cases for autonomous smart contracts.\nThe self wake-up functionality empowers automated processes, reduces reliance on intermediaries, and enhances efficiency and\ntransparency across diverse industries."),(0,r.kt)("h2",{id:"going-further"},"Going further"),(0,r.kt)("p",null,"If you want to go further and start coding your own autonomous smart contract, head to the ",(0,r.kt)("a",{parentName:"p",href:"/docs/build/home"},"Build section"),"."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/239c5dbf.4f55c85b.js b/assets/js/239c5dbf.4f55c85b.js new file mode 100644 index 000000000..fedf6983a --- /dev/null +++ b/assets/js/239c5dbf.4f55c85b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[696],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>h});var n=a(7294);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var l=n.createContext({}),d=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},c=function(e){var t=d(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var a=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=d(a),p=o,h=u["".concat(l,".").concat(p)]||u[p]||m[p]||r;return a?n.createElement(h,i(i({ref:t},c),{},{components:a})):n.createElement(h,i({ref:t},c))}));function h(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=a.length,i=new Array(r);i[0]=p;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var d=2;d{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var n=a(7462),o=(a(7294),a(3905));const r={id:"home",title:"Introduction to Massa Station"},i=void 0,s={unversionedId:"massaStation/home",id:"massaStation/home",title:"Introduction to Massa Station",description:"Introduction to Massa Station",source:"@site/docs/massaStation/home.mdx",sourceDirName:"massaStation",slug:"/massaStation/home",permalink:"/docs/massaStation/home",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/massaStation/home.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"home",title:"Introduction to Massa Station"},sidebar:"massaStationSidebar",next:{title:"Install",permalink:"/docs/massaStation/install"}},l={},d=[{value:"Introduction to Massa Station",id:"introduction-to-massa-station",level:2},{value:"Get Started",id:"get-started",level:2},{value:"Build on Massa Station",id:"build-on-massa-station",level:2},{value:"Other Resources",id:"other-resources",level:2}],c={toc:d},u="wrapper";function m(e){let{components:t,...a}=e;return(0,o.kt)(u,(0,n.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"introduction-to-massa-station"},"Introduction to Massa Station"),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"Massa Station")," is a desktop application that provides an intuitive way to interact with the Massa blockchain through\nyour web browser."),(0,o.kt)("p",null,"If you're not a developer or simply prefer a more visual approach, using ",(0,o.kt)("em",{parentName:"p"},"Massa Station")," is ideal for you."),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"Massa Station")," is the gateway to the Massa Blockchain. You can think of it as an application store for modules that\nleverage the exciting features of the Massa Blockchain. ",(0,o.kt)("em",{parentName:"p"},"Massa Station")," comes in the form of a desktop application with\nsome core modules pre-installed. For example, directly out of the box, ",(0,o.kt)("em",{parentName:"p"},"Massa Station")," allows you to access Massa's\n",(0,o.kt)("a",{parentName:"p",href:"/docs/learn/decentralized-web"},"Decentralized Web"),"."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"Once installed on your machine, ",(0,o.kt)("em",{parentName:"p"},"Massa Station")," will allow your browser to resolve ",(0,o.kt)("inlineCode",{parentName:"p"},".massa")," url domains and interact\nwith decentralized applications hosted on Massa. When using ",(0,o.kt)("em",{parentName:"p"},"Massa Station"),", the ",(0,o.kt)("inlineCode",{parentName:"p"},".massa")," url domain indicates that you\nare visiting a website that is hosted on-chain, and directly served to you. You can learn more about Decentralized Web\n",(0,o.kt)("a",{parentName:"p",href:"/docs/learn/decentralized-web"},"here"),".")),(0,o.kt)("p",null,"Another core module of ",(0,o.kt)("em",{parentName:"p"},"Massa Station")," that is already available is the ",(0,o.kt)("a",{parentName:"p",href:"/docs/build/wallet/massa-wallet"},"Massa Wallet"),".\nIt allows you to manage your Massa accounts, and sign and send transactions with an experience similar to a traditional\nbrowser-plugin wallet, but with enhanced security."),(0,o.kt)("p",null,"Besides the core modules developed by the Massa team, ",(0,o.kt)("em",{parentName:"p"},"Massa Station")," was designed with community and modularity in\nmind; indeed, it allows anyone to develop and install their own modules. The most looked upon modules in terms of\ncommunity adoption, and upon audit, will be made publicly available through the Massa Plugin Store. We greatly encourage\nour community to develop their own modules, as we believe that the ",(0,o.kt)("em",{parentName:"p"},"Massa Station")," ecosystem will be the key to the\nadoption of the Massa Blockchain."),(0,o.kt)("h2",{id:"get-started"},"Get Started"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/install"},"Install Massa Station")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/modules"},"Massa Station Modules")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/browse-decentralized-application"},"Browse Decentralized Apps"))),(0,o.kt)("h2",{id:"build-on-massa-station"},"Build on Massa Station"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/guidelines"},"Plugin Creation Guidelines")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/hello-world-plugin"},"Hello World Plugin"))),(0,o.kt)("h2",{id:"other-resources"},"Other Resources"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/faq"},"Massa Station FAQ")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/manual-install"},"Manual Installation")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/uninstall"},"Uninstall Massa Station"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/239c5dbf.d70b5a3f.js b/assets/js/239c5dbf.d70b5a3f.js deleted file mode 100644 index 85aaf1feb..000000000 --- a/assets/js/239c5dbf.d70b5a3f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[696],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>h});var n=a(7294);function o(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(o[a]=e[a]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var l=n.createContext({}),d=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},c=function(e){var t=d(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var a=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=d(a),p=o,h=u["".concat(l,".").concat(p)]||u[p]||m[p]||r;return a?n.createElement(h,i(i({ref:t},c),{},{components:a})):n.createElement(h,i({ref:t},c))}));function h(e,t){var a=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=a.length,i=new Array(r);i[0]=p;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var d=2;d{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var n=a(7462),o=(a(7294),a(3905));const r={id:"home",title:"Introduction to Massa Station"},i=void 0,s={unversionedId:"massaStation/home",id:"massaStation/home",title:"Introduction to Massa Station",description:"Introduction to Massa Station",source:"@site/docs/massaStation/home.mdx",sourceDirName:"massaStation",slug:"/massaStation/home",permalink:"/docs/massaStation/home",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/massaStation/home.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"home",title:"Introduction to Massa Station"},sidebar:"massaStationSidebar",next:{title:"Install",permalink:"/docs/massaStation/install"}},l={},d=[{value:"Introduction to Massa Station",id:"introduction-to-massa-station",level:2},{value:"Get Started",id:"get-started",level:2},{value:"Build on Massa Station",id:"build-on-massa-station",level:2},{value:"Other Resources",id:"other-resources",level:2}],c={toc:d},u="wrapper";function m(e){let{components:t,...a}=e;return(0,o.kt)(u,(0,n.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"introduction-to-massa-station"},"Introduction to Massa Station"),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"Massa Station")," is a desktop application that provides an intuitive way to interact with the Massa blockchain through\nyour web browser."),(0,o.kt)("p",null,"If you're not a developer or simply prefer a more visual approach, using ",(0,o.kt)("em",{parentName:"p"},"Massa Station")," is ideal for you."),(0,o.kt)("p",null,(0,o.kt)("em",{parentName:"p"},"Massa Station")," is the gateway to the Massa Blockchain. You can think of it as an application store for modules that\nleverage the exciting features of the Massa Blockchain. ",(0,o.kt)("em",{parentName:"p"},"Massa Station")," comes in the form of a desktop application with\nsome core modules pre-installed. For example, directly out of the box, ",(0,o.kt)("em",{parentName:"p"},"Massa Station")," allows you to access Massa's\n",(0,o.kt)("a",{parentName:"p",href:"/docs/learn/decentralized-web"},"Decentralized Web"),"."),(0,o.kt)("admonition",{type:"info"},(0,o.kt)("p",{parentName:"admonition"},"Once installed on your machine, ",(0,o.kt)("em",{parentName:"p"},"Massa Station")," will allow your browser to resolve ",(0,o.kt)("inlineCode",{parentName:"p"},".massa")," url domains and interact\nwith decentralized applications hosted on Massa. When using ",(0,o.kt)("em",{parentName:"p"},"Massa Station"),", the ",(0,o.kt)("inlineCode",{parentName:"p"},".massa")," url domain indicates that you\nare visiting a website that is hosted on-chain, and directly served to you. You can learn more about Decentralized Web\n",(0,o.kt)("a",{parentName:"p",href:"/docs/learn/decentralized-web"},"here"),".")),(0,o.kt)("p",null,"Another core module of ",(0,o.kt)("em",{parentName:"p"},"Massa Station")," that is already available is the ",(0,o.kt)("a",{parentName:"p",href:"/docs/build/wallet/massa-wallet"},"Massa Wallet"),".\nIt allows you to manage your Massa accounts, and sign and send transactions with an experience similar to a traditional\nbrowser-plugin wallet, but with enhanced security."),(0,o.kt)("p",null,"Besides the core modules developed by the Massa team, ",(0,o.kt)("em",{parentName:"p"},"Massa Station")," was designed with community and modularity in\nmind; indeed, it allows anyone to develop and install their own modules. The most looked upon modules in terms of\ncommunity adoption, and upon audit, will be made publicly available through the Massa Plugin Store. We greatly encourage\nour community to develop their own modules, as we believe that the ",(0,o.kt)("em",{parentName:"p"},"Massa Station")," ecosystem will be the key to the\nadoption of the Massa Blockchain."),(0,o.kt)("h2",{id:"get-started"},"Get Started"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/install"},"Install Massa Station")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/modules"},"Massa Station Modules")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/browse-decentralized-application"},"Browse Decentralized Apps"))),(0,o.kt)("h2",{id:"build-on-massa-station"},"Build on Massa Station"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/guidelines"},"Plugin Creation Guidelines")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/hello-world-plugin"},"Hello World Plugin"))),(0,o.kt)("h2",{id:"other-resources"},"Other Resources"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/faq"},"Massa Station FAQ")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/manual-install"},"Manual Installation")),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/massaStation/uninstall"},"Uninstall Massa Station"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/256be1ac.0319165e.js b/assets/js/256be1ac.0319165e.js new file mode 100644 index 000000000..246d7d9f6 --- /dev/null +++ b/assets/js/256be1ac.0319165e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[7503],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>h});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),l=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(i.Provider,{value:t},e.children)},m="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),m=l(r),d=o,h=m["".concat(i,".").concat(d)]||m[d]||p[d]||a;return r?n.createElement(h,c(c({ref:t},u),{},{components:r})):n.createElement(h,c({ref:t},u))}));function h(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,c=new Array(a);c[0]=d;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s[m]="string"==typeof e?e:o,c[1]=s;for(var l=2;l{r.d(t,{L:()=>i,V:()=>c});var n=r(7294),o=r(6010);const a={feature:"feature_yCMF"};function c(e){let{children:t}=e;return n.createElement(n.Fragment,null,n.createElement("div",{className:"container features"},n.createElement("div",{className:"row"},t)))}const s=()=>n.createElement("svg",{width:"0.8rem",height:"0.8rem","aria-hidden":"true",viewBox:"0 0 24 24",className:"iconExternalLink_node_modules-@docusaurus-theme-classic-lib-theme-Icon-ExternalLink-styles-module"},n.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}));function i(e){let{url:t,title:r,content:c,icon:i}=e;const l=t.startsWith("http"),u=l?"_blank":"_self",m=l?"noopener noreferrer":"";return n.createElement(n.Fragment,null,n.createElement("a",{className:(0,o.Z)("col col--4",a.feature),href:t,target:u,rel:m},n.createElement("div",null,n.createElement("div",{className:"avatar__name"},i," ",r," ",l&&n.createElement(s,null)),n.createElement("small",null,c))))}},4442:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>d,frontMatter:()=>c,metadata:()=>i,toc:()=>u});var n=r(7462),o=(r(7294),r(3905)),a=r(5652);const c={id:"home",sidebar_label:"Home"},s="General Documentation",i={unversionedId:"learn/home",id:"learn/home",title:"General Documentation",description:"Welcome! On this page you'll find various resources explaining some concepts introduced by the Massa protocol and how the Massa protocol operates.",source:"@site/docs/learn/home.mdx",sourceDirName:"learn",slug:"/learn/home",permalink:"/docs/learn/home",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/learn/home.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"home",sidebar_label:"Home"},sidebar:"learnSidebar",next:{title:"Welcome to Massa",permalink:"/docs/learn/introduction"}},l={},u=[],m={toc:u},p="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(p,(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"general-documentation"},"General Documentation"),(0,o.kt)("p",null,"Welcome! On this page you'll find various resources explaining some concepts introduced by the Massa protocol and how the Massa protocol operates."),(0,o.kt)(a.V,{mdxType:"FeatureList"},(0,o.kt)(a.L,{url:"./architecture/basic-concepts",title:"Basic Concepts",content:"Learn the basics of Massa, from addresses to smart contracts.",icon:"\ud83d\udcda",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"./architecture/node-architecture",title:"Node Architecture",content:"Learn the inner workings of a Massa node.",icon:"\ud83d\udda5",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"./bootstrap",title:"Bootstrapping in Massa",content:"Learn how bootstrapping works in Massa.",icon:"\ud83c\udf10",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"./storage-costs",title:"Storage Costs",content:"Learn how storage costs work.",icon:"\ud83c\udfe6",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"./gas",title:"Gas",content:"Learn how gas works.",icon:"\u26fd",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"./asc/intro",title:"Autonomous Smart Contracts",content:"Learn how Massa automates smart contract execution.",icon:"\ud83e\udd16",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"./operation-format-execution",title:"Detailed operation format and execution",content:"Documentation about operation serialization and execution sequences.",icon:"\u2699\ufe0f",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"https://arxiv.org/abs/1803.09029",title:"Technical Whitepaper",content:"Read the research paper behind Massa.",icon:"\ud83d\udcc4",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"./tokenomics",title:"Tokenomics",content:"Learn the economics related to the Massa token.",icon:"\ud83e\ude99",mdxType:"Feature"})))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/256be1ac.a97c2cab.js b/assets/js/256be1ac.a97c2cab.js deleted file mode 100644 index d0c33c3b2..000000000 --- a/assets/js/256be1ac.a97c2cab.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[7503],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>h});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},u=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},m="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),m=l(r),d=o,h=m["".concat(s,".").concat(d)]||m[d]||p[d]||a;return r?n.createElement(h,c(c({ref:t},u),{},{components:r})):n.createElement(h,c({ref:t},u))}));function h(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,c=new Array(a);c[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[m]="string"==typeof e?e:o,c[1]=i;for(var l=2;l{r.d(t,{L:()=>s,V:()=>c});var n=r(7294),o=r(6010);const a={feature:"feature_yCMF"};function c(e){let{children:t}=e;return n.createElement(n.Fragment,null,n.createElement("div",{className:"container features"},n.createElement("div",{className:"row"},t)))}const i=()=>n.createElement("svg",{width:"0.8rem",height:"0.8rem","aria-hidden":"true",viewBox:"0 0 24 24",className:"iconExternalLink_node_modules-@docusaurus-theme-classic-lib-theme-Icon-ExternalLink-styles-module"},n.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}));function s(e){let{url:t,title:r,content:c,icon:s}=e;const l=t.startsWith("http"),u=l?"_blank":"_self",m=l?"noopener noreferrer":"";return n.createElement(n.Fragment,null,n.createElement("a",{className:(0,o.Z)("col col--4",a.feature),href:t,target:u,rel:m},n.createElement("div",null,n.createElement("div",{className:"avatar__name"},s," ",r," ",l&&n.createElement(i,null)),n.createElement("small",null,c))))}},4442:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>c,metadata:()=>s,toc:()=>u});var n=r(7462),o=(r(7294),r(3905)),a=r(5652);const c={id:"home",sidebar_label:"Home"},i="General Documentation",s={unversionedId:"learn/home",id:"learn/home",title:"General Documentation",description:"Welcome! On this page you'll find various resources explaining some concepts introduced by the Massa protocol and how the Massa protocol operates.",source:"@site/docs/learn/home.mdx",sourceDirName:"learn",slug:"/learn/home",permalink:"/docs/learn/home",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/learn/home.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"home",sidebar_label:"Home"},sidebar:"learnSidebar",next:{title:"Welcome to Massa",permalink:"/docs/learn/introduction"}},l={},u=[],m={toc:u},p="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(p,(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"general-documentation"},"General Documentation"),(0,o.kt)("p",null,"Welcome! On this page you'll find various resources explaining some concepts introduced by the Massa protocol and how the Massa protocol operates."),(0,o.kt)(a.V,{mdxType:"FeatureList"},(0,o.kt)(a.L,{url:"./architecture/basic-concepts",title:"Basic Concepts",content:"Learn the basics of Massa, from addresses to smart contracts.",icon:"\ud83d\udcda",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"./architecture/node-architecture",title:"Node Architecture",content:"Learn the inner workings of a Massa node.",icon:"\ud83d\udda5",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"./bootstrap",title:"Bootstrapping in Massa",content:"Learn how bootstrapping works in Massa.",icon:"\ud83c\udf10",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"./storage-costs",title:"Storage Costs",content:"Learn how storage costs work.",icon:"\ud83c\udfe6",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"./gas",title:"Gas",content:"Learn how gas works.",icon:"\u26fd",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"./asc/intro",title:"Autonomous Smart Contracts",content:"Learn how Massa automates smart contract execution.",icon:"\ud83e\udd16",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"./operation-format-execution",title:"Detailed operation format and execution",content:"Documentation about operation serialization and execution sequences.",icon:"\u2699\ufe0f",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"https://arxiv.org/abs/1803.09029",title:"Technical Whitepaper",content:"Read the research paper behind Massa.",icon:"\ud83d\udcc4",mdxType:"Feature"}),(0,o.kt)(a.L,{url:"./tokenomics",title:"Tokenomics",content:"Learn the economics related to the Massa token.",icon:"\ud83e\ude99",mdxType:"Feature"})))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2580cc57.5e752695.js b/assets/js/2580cc57.5e752695.js new file mode 100644 index 000000000..6312e9762 --- /dev/null +++ b/assets/js/2580cc57.5e752695.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[6489],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>k});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var p=n.createContext({}),l=function(e){var t=n.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},c=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=l(a),h=r,k=d["".concat(p,".").concat(h)]||d[h]||m[h]||o;return a?n.createElement(k,s(s({ref:t},c),{},{components:a})):n.createElement(k,s({ref:t},c))}));function k(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,s=new Array(o);s[0]=h;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[d]="string"==typeof e?e:r,s[1]=i;for(var l=2;l{a.r(t),a.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var n=a(7462),r=(a(7294),a(3905));const o={id:"basic-concepts",sidebar_label:"Basic concepts"},s="Basic concepts",i={unversionedId:"learn/architecture/basic-concepts",id:"learn/architecture/basic-concepts",title:"Basic concepts",description:"Let's dive into the basic definitions and concepts of Massa blockchain.",source:"@site/docs/learn/architecture/basic-concepts.mdx",sourceDirName:"learn/architecture",slug:"/learn/architecture/basic-concepts",permalink:"/docs/learn/architecture/basic-concepts",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/learn/architecture/basic-concepts.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"basic-concepts",sidebar_label:"Basic concepts"},sidebar:"learnSidebar",previous:{title:"Welcome to Massa",permalink:"/docs/learn/introduction"},next:{title:"Node architecture",permalink:"/docs/learn/architecture/node-architecture"}},p={},l=[{value:"Ledger",id:"ledger",level:2},{value:"Address",id:"address",level:2},{value:"Smart Contract",id:"smart-contract",level:2},{value:"Autonomous Smart Contract Execution",id:"autonomous-smart-contract-execution",level:3},{value:"Storage costs",id:"storage-costs",level:2},{value:"Gas",id:"gas",level:2},{value:"Block",id:"block",level:2},{value:"Operation",id:"operation",level:2},{value:"Operation types",id:"operation-types",level:3},{value:"Transaction operations",id:"transaction-operations",level:4},{value:"Buy/Sell Rolls operations",id:"buysell-rolls-operations",level:4},{value:"Smart Contract operations",id:"smart-contract-operations",level:4},{value:"Endorsements",id:"endorsements",level:3}],c={toc:l},d="wrapper";function m(e){let{components:t,...o}=e;return(0,r.kt)(d,(0,n.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"basic-concepts"},"Basic concepts"),(0,r.kt)("p",null,"Let's dive into the basic definitions and concepts of Massa blockchain."),(0,r.kt)("p",null,"The goal of the Massa network is to build a consensus between ",(0,r.kt)("strong",{parentName:"p"},"nodes")," to gather\nand order ",(0,r.kt)("strong",{parentName:"p"},"blocks")," that contain ordered lists of ",(0,r.kt)("strong",{parentName:"p"},"operations"),".\nAn operation ultimate purpose once executed is to act as transitions for the global network state, called the ",(0,r.kt)("strong",{parentName:"p"},"ledger"),"."),(0,r.kt)("p",null,"Operations are produced by external clients and sent to the Massa network via a node.\nSome operations are containing code to be run as ",(0,r.kt)("strong",{parentName:"p"},"smart contracts"),", enabling complex programmatic\nmodifications of the ledger.\nNodes gather pending operations and group them into blocks. Each block has limited space to store operations.\nTraditional blockchains typically link blocks sequentially, including a hash of the previous block in the block\nheader for temporal ordering. In contrast, Massa blocks are organized into a complex spatio-temporal structure,\nenabling parallelization and improved block-creation performance."),(0,r.kt)("p",null,"Instead of one chain, there are exactly 32 ",(0,r.kt)("strong",{parentName:"p"},"threads")," of chains running in parallel, with blocks equally\nspread on each thread over time, and stored inside ",(0,r.kt)("strong",{parentName:"p"},"slots")," that are spaced at fixed time intervals:"),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(5065).Z,width:"887",height:"387"})),(0,r.kt)("p",null,"The time between two slots located on the same thread is called a ",(0,r.kt)("strong",{parentName:"p"},"period")," and lasts 16s (conventionally called ",(0,r.kt)("span",{parentName:"p",className:"math math-inline"},(0,r.kt)("span",{parentName:"span",className:"katex"},(0,r.kt)("span",{parentName:"span",className:"katex-mathml"},(0,r.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,r.kt)("semantics",{parentName:"math"},(0,r.kt)("mrow",{parentName:"semantics"},(0,r.kt)("msub",{parentName:"mrow"},(0,r.kt)("mi",{parentName:"msub"},"t"),(0,r.kt)("mn",{parentName:"msub"},"0"))),(0,r.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"t_0")))),(0,r.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,r.kt)("span",{parentName:"span",className:"base"},(0,r.kt)("span",{parentName:"span",className:"strut",style:{height:"0.7651em",verticalAlign:"-0.15em"}}),(0,r.kt)("span",{parentName:"span",className:"mord"},(0,r.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,r.kt)("span",{parentName:"span",className:"msupsub"},(0,r.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,r.kt)("span",{parentName:"span",className:"vlist-r"},(0,r.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.3011em"}},(0,r.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"0em",marginRight:"0.05em"}},(0,r.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,r.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,r.kt)("span",{parentName:"span",className:"mord mtight"},"0")))),(0,r.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,r.kt)("span",{parentName:"span",className:"vlist-r"},(0,r.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,r.kt)("span",{parentName:"span"})))))))))),").\nCorresponding slots in threads are slightly shifted in time relative to one another, by one period divided by the number\nof threads, which is ",(0,r.kt)("span",{parentName:"p",className:"math math-inline"},(0,r.kt)("span",{parentName:"span",className:"katex"},(0,r.kt)("span",{parentName:"span",className:"katex-mathml"},(0,r.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,r.kt)("semantics",{parentName:"math"},(0,r.kt)("mrow",{parentName:"semantics"},(0,r.kt)("mn",{parentName:"mrow"},"16"),(0,r.kt)("mi",{parentName:"mrow"},"s"),(0,r.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"/"),(0,r.kt)("mn",{parentName:"mrow"},"32"),(0,r.kt)("mo",{parentName:"mrow"},"="),(0,r.kt)("mn",{parentName:"mrow"},"0.5"),(0,r.kt)("mi",{parentName:"mrow"},"s")),(0,r.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"16s/32 = 0.5s")))),(0,r.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,r.kt)("span",{parentName:"span",className:"base"},(0,r.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,r.kt)("span",{parentName:"span",className:"mord"},"16"),(0,r.kt)("span",{parentName:"span",className:"mord mathnormal"},"s"),(0,r.kt)("span",{parentName:"span",className:"mord"},"/32"),(0,r.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,r.kt)("span",{parentName:"span",className:"mrel"},"="),(0,r.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,r.kt)("span",{parentName:"span",className:"base"},(0,r.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6444em"}}),(0,r.kt)("span",{parentName:"span",className:"mord"},"0.5"),(0,r.kt)("span",{parentName:"span",className:"mord mathnormal"},"s"))))),", so that a period contains exactly 32 slots equally spaced over the 32 threads.\nA ",(0,r.kt)("strong",{parentName:"p"},"cycle")," is defined as the succession of 128 periods and so lasts a bit more than 34min. Periods are numbered by\nincrements of one, so can be used together with a thread number to uniquely identify a block slot. Period 0 is the\ngenesis and contains genesis blocks with no parents."),(0,r.kt)("p",null,"The job of the Massa nodes network is to essentially collectively fill up slots with valid blocks. To do so,\nat each interval of 0.5s, a specific node in the network is elected to be allowed to create a block (more about\nthe selection process and the proof of stake sybil resistance mechanism ",(0,r.kt)("a",{parentName:"p",href:"/docs/learn/architecture/node-architecture#selector-module-proof-of-stake-sybil-resistance"},"here"),"),\nand will be rewarded if it creates a valid block in time. It is also possible that a node misses its opportunity\nto create the block, in which case the slot will remain empty (this is called a ",(0,r.kt)("strong",{parentName:"p"},"block miss"),")."),(0,r.kt)("p",null,"In traditional blockchains, blocks are simply referencing their unique parent, forming a chain. In the case of\nMassa, each block is referencing one parent block in each thread (so, 32 parents). Here is an example\nillustrated with one particular block:"),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(8819).Z,width:"887",height:"328"})),(0,r.kt)("p",null,"Let\u2019s introduce some relevant definitions and concepts generally necessary to understand how the Massa network operates.\nWe will then explain the node architecture and how the whole system works."),(0,r.kt)("h2",{id:"ledger"},"Ledger"),(0,r.kt)("p",null,"The ledger is a map that stores a global mapping between addresses and information related to these addresses.\nIt is replicated in each node. The consensus building mechanism ensures that agreement on what operations have\nbeen finalized (and in what order) will be reached over the whole network. The ledger is the state of the Massa network,\nand operations (see below) are requests to modify the ledger. "),(0,r.kt)("p",null,"The information stored in the ledger with each address is the following:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:2,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Ledger Information Associated with Each Address")))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"balance"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The amount of Massa coins owned by the address."))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"bytecode"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"When the address references a smart contract, this is the compiled code corresponding to the smart contract (typically contains several functions that act as API entry points)."))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"datastore"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"A key/value map that can store any persistent data related to a smart contract, its variables, etc."))))),(0,r.kt)("p",null,"In order to promote widespread adoption and facilitate node running with reduced entry fees, the size of the ledger in Massa\nhas been limited to a maximum of 1 TB.\nThis decision sets Massa apart from other benchmark blockchain ledgers and makes it more accessible to users."),(0,r.kt)("p",null,"To achieve such a small ledger size, several technical decisions were made.\nFirstly, state changes that have been finalized and are found in the final Blocks no longer require record-keeping in the Ledger's memory.\nThis optimization helps minimize the storage requirements for historical data, allowing the ledger to operate efficiently within the specified size limit."),(0,r.kt)("p",null,"In addition to this, Massa has introduced ",(0,r.kt)("a",{parentName:"p",href:"/docs/learn/storage-costs"},"Storage Costs")," as a novel approach to enhance storage efficiency.\nUsers are now required to lock a certain amount of coins when they claim storage space.\nThis innovative correlation between storage and circulating coins ensures a balanced utilization of resources.\nBy implementing this mechanism, Massa optimizes storage utilization while maintaining the integrity and security of the ledger."),(0,r.kt)("p",null,"These technical decisions, including the exclusion of finalized state changes from ledger memory and the introduction of Storage\nCosts, play a crucial role in enabling the compact size of the ledger and ultimately facilitating a more efficient and accessible\nblockchain ecosystem."),(0,r.kt)("h2",{id:"address"},"Address"),(0,r.kt)("p",null,"An address on the Massa blockchain serves as your unique identity, granting you the ability to engage in various operations,\nstore information, and exchange data with other participants. With an address, you gain access to a wide range of functionalities\nwithin the blockchain ecosystem."),(0,r.kt)("p",null,"Using your address, you can initiate operations that interact with the blockchain.\nThis includes executing transactions, submitting smart contract calls, and engaging in other blockchain activities.\nYour address acts as the key to unlock these capabilities, allowing you to participate fully in the decentralized network."),(0,r.kt)("p",null,"Furthermore, your address enables you to store and retrieve information on the blockchain. Whether it's personal data, financial records, or any other form of digital information, you can securely store it using your address as the reference. This provides a reliable and immutable storage solution within the blockchain environment."),(0,r.kt)("p",null,"Importantly, your address also facilitates communication and data exchange with other participants on the blockchain.\nBy sharing your address with others, you can interact, transact, and collaborate with different individuals and entities\nwithin the blockchain network.\nThis seamless exchange of data and value promotes a decentralized and interconnected ecosystem."),(0,r.kt)("p",null,"Each user address on Massa has a public and private key associated with it.\nThis is how messages can be signed and identity enforced.\nThe address of an account is simply the hash of its public key. "),(0,r.kt)("p",null,"Addresses are generated using a specific format that includes a prefix ",(0,r.kt)("inlineCode",{parentName:"p"},"A")," and a base58 encoding. The prefix distinguishes between user addresses, linked to a KeyPair, and smart-contract addresses, denoted by the prefixes ",(0,r.kt)("inlineCode",{parentName:"p"},"U")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"S")," respectively."),(0,r.kt)("p",null,"For user addresses (AU), the hash calculation involves taking the Blake3 hash of the byte representation of\nthe user's public key.\nThis process ensures a unique and secure identification for each user address within the system."),(0,r.kt)("h2",{id:"smart-contract"},"Smart Contract"),(0,r.kt)("p",null,"Smart contracts are a piece of code that can be run inside the Massa virtual machine, which can modify the ledger,\nand accept incoming requests through a public interface (via smart-contract operations). "),(0,r.kt)("p",null,"Smart contracts are currently written in AssemblyScript, a derivation from TypeScript, which is itself a\ntype-safe version of JavaScript. AssemblyScript compiles to WebAssembly bytecode (wasm). Massa nodes Execution Module runs such bytecode.\nSmart contracts have access to their own datastore, so they can modify the ledger."),(0,r.kt)("p",null,"Smart contracts follow a different hash calculation than user addresses. It begins by constructing a byte array comprising various elements.\nThis array consists of the slot represented in 5 bytes, with 4 bytes allocated for the period (encoded as a u64 in big endian\nformat), 1 byte for the thread, and an index that increments for each address created within the same slot.\nThe index value is represented as a u64 in big endian format and is reset at the start of each new slot.\nAdditionally, a single byte is appended to indicate whether the address is for real execution (1) or read-only execution (0)."),(0,r.kt)("p",null,"The resulting byte array is then subject to the Blake3 hash function, generating a unique\nhash value that serves as the SC address."),(0,r.kt)("h3",{id:"autonomous-smart-contract-execution"},"Autonomous Smart Contract Execution"),(0,r.kt)("p",null,"One particularity of Massa smart contracts compared to other blockchain smart contracts is their ability to wake\nup by themselves independently of an exterior request on their interface. We call them Autonomous Smart Contracts (ASCs),\nas they allow more autonomy and less dependency on external centralized services."),(0,r.kt)("p",null,"ASCs offer a plethora of use cases that leverage their self wake-up functionality.\nIn the realm of Decentralized Finance (DeFi), these contracts can automate liquidations,\nyield farming strategies, and portfolio rebalancing.\nSupply chain management benefits from autonomous contracts through automated inventory management and quality control processes.\nIn the insurance industry, claims settlements can be accelerated with instant payments and parametric insurance.\nGaming and NFT platforms can provide dynamic and interactive experiences with evolving NFTs and automated auctions.\nAdditionally, real estate transactions can be streamlined with escrow automation and simplified rental agreements.\nThese use cases exemplify the transformative potential of Autonomous Smart Contracts in enabling automated and efficient\nprocesses across various industries."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"Learn more about Autonomous Smart Contracts ",(0,r.kt)("a",{parentName:"p",href:"/docs/learn/asc/intro"},"here"),".")),(0,r.kt)("h2",{id:"storage-costs"},"Storage costs"),(0,r.kt)("p",null,"In Massa, each network node maintains a full copy of the ledger. Having a massive ledger size (hundreds of terabytes), would pose high entry barriers for potential node runners. To ensure smooth operation and enable node hosting at home, it's essential to establish a reasonable size limit, and remove the need for excessive storage capacity. After careful consideration, we have determined that a storage size limit of 1TB strikes the right balance. This means that each participant can store data on the ledger until it reaches the 1TB threshold. By implementing this limit, we aim to promote widespread adoption and empower individuals to run nodes effortlessly. "),(0,r.kt)("p",null,"In order to enforce this limit, users are required to lock a corresponding amount of coins for each byte of storage they claim. This applies to various data elements such as your address, balance, keys in your datastore, bytecode, and more. By locking coins, you establish a commitment that ensures fair usage of storage resources. Once you release your allocated space in the storage, the locked coins are subsequently released as well. This mechanism guarantees a balanced and accountable approach to managing storage within the network."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Read more about storage costs ",(0,r.kt)("a",{parentName:"p",href:"/docs/learn/storage-costs"},"here"),".")),(0,r.kt)("h2",{id:"gas"},"Gas"),(0,r.kt)("p",null,"In Massa, there is no Gas price.\nEach operation declares a max amount of gas that it can use, and provides a fee that is added to the rewards of the block in which the operation is executed."),(0,r.kt)("p",null,"Block producers then choose which operations to include in their blocks to fit the max block gas and max block size constraints while maximizing the total fee."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Read more about gas ",(0,r.kt)("a",{parentName:"p",href:"/docs/learn/gas"},"here"),".")),(0,r.kt)("h2",{id:"block"},"Block"),(0,r.kt)("p",null,"A block is a data structure built by nodes and its function is to aggregate several operations. As explained above,\nfor each new slot that becomes active, a particular node in the network is elected in a deterministic way with the\ntask of creating the block that will be stored in that slot (more about this in the description of the Selector\nModule below). A block from a given thread can only contain operations originating from a creator_public_key whose\nhash\u2019s five first bits designate the corresponding thread, thus implicitly avoiding collisions in operations integrated into parallel threads. Block size is limited to 1 MB."),(0,r.kt)("p",null,"The content of a block is as follows:"),(0,r.kt)("table",null,(0,r.kt)("tr",null,(0,r.kt)("th",{colspan:"2"},"Block header")),(0,r.kt)("tr",null,(0,r.kt)("td",null,(0,r.kt)("code",null,"slot")),(0,r.kt)("td",null,"A description of the block slot, defined by a couple (period, thread) that uniquely identify it")),(0,r.kt)("tr",null,(0,r.kt)("td",null,(0,r.kt)("code",null,"creator_public_key")),(0,r.kt)("td",null,"The public key of the block creator (32 bytes)")),(0,r.kt)("tr",null,(0,r.kt)("td",null,(0,r.kt)("code",null,"parents")),(0,r.kt)("td",null,"A list of the 32 parents of the block, one parent per thread (parent blocks are identified by the block hash)")),(0,r.kt)("tr",null,(0,r.kt)("td",null,(0,r.kt)("code",null,"endorsements")),(0,r.kt)("td",null,"A list of the 16 endorsements for the block (more about endorsements below)")),(0,r.kt)("tr",null,(0,r.kt)("td",null,(0,r.kt)("code",null,"operations_hash")),(0,r.kt)("td",null,"A hash of all the operations included in the block (=hash of the block body below)")),(0,r.kt)("tr",null,(0,r.kt)("td",null,(0,r.kt)("code",null,"signature")),(0,r.kt)("td",null,"Signature of all the above with the private key of the block creator")),(0,r.kt)("tr",null,(0,r.kt)("th",{colspan:"2"},"Block body")),(0,r.kt)("tr",null,(0,r.kt)("td",null,(0,r.kt)("code",null,"operations")),(0,r.kt)("td",null,"The list of all operations included in the block"))),(0,r.kt)("h2",{id:"operation"},"Operation"),(0,r.kt)("p",null,"At its core, the Massa network revolves around the aggregation, sequencing, and execution of operations. Operations are\nrecorded inside blocks that are located in slots. "),(0,r.kt)("p",null,"Operations are denoted by a string prefixed with 'O' that encapsulate crucial information within a byte array.\nThe byte array encompasses the version in a u64 varint format, the Blake3 hash of the fully serialized content\nof the operation, and the public key of the creator.\nBy meticulously organizing and recording operations within blocks that reside in specific slots,\nthe Massa network ensures the integrity and efficiency of its operations."),(0,r.kt)("h3",{id:"operation-types"},"Operation types"),(0,r.kt)("p",null,"There are three types of operations: transactions, roll operations, and smart contract code execution.\nThe general structure of an operation is the following, and the different types of operations differ by their payload:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:3,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Transaction Binary Representation"))),(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Field")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Description")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Type")))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"creator_public_key"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The public key of the operation creator")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"32 bytes"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"expiration_period"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"Period after which the operation is expired")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"fee"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The amount of fees the creator is willing to pay")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"type"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The type of operation\n(from 0 to 4: transaction, rollbuy, rollsell, executesc,\ncallsc)")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"payload"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The content of the operation")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"see each operation"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"signature"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"Signature of all the above with the private key of the\noperation creator")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"64 bytes"))))),(0,r.kt)("h4",{id:"transaction-operations"},"Transaction operations"),(0,r.kt)("p",null,"Transactions are operations that move native Massa coins between addresses. Here is the corresponding payload:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:3,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Transaction Payload Binary Representation"))),(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Field")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Description")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Type")))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"amount"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The amount of coins to transfer")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"destination_address"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The address of the recipient")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"32 bytes"))))),(0,r.kt)("h4",{id:"buysell-rolls-operations"},"Buy/Sell Rolls operations"),(0,r.kt)("p",null,"Rolls are staking tokens that participants can buy or sell with native Massa coins. By owning rolls,\naddresses can participate in block creation ",(0,r.kt)("a",{parentName:"p",href:"/docs/node/stake"},"more about staking below"),".\nThis is done via special operations, with a simple payload:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:3,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Buy/Sell Rolls Payload Binary Representation"))),(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Field")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Description")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Type")))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"nb_of_rolls"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The number of rolls to buy or sell")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))))),(0,r.kt)("h4",{id:"smart-contract-operations"},"Smart Contract operations"),(0,r.kt)("p",null,"Smart Contracts are pieces of code that can be run inside the Massa virtual machine. There are two ways\nof calling for the execution of code; by direct execution of bytecode, and by a smart-contract function call.\nFormer is done using the Execute SC operation, and latter with Call SC operation."),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},"Execute SC operation"),(0,r.kt)("p",{parentName:"li"},"The ExecuteSC operation provides a powerful functionality within the Massa network by enabling the execution of smart contracts\ndirectly instead of storing them.\nInstead of storing the bytecode, the code itself is placed within the operation as a smart contract.\nWhen the ExecuteSC operation is executed, the blockchain triggers the execution of the main function within\nthe smart contract code. After the code is executed, the blockchain proceeds to other tasks while retaining\nand reflecting the changes made to the ledger and other relevant data.\nThis approach ensures that the executed changes are recorded and maintained on the ledger, rather than\nretaining the bytecode itself.\nBy executing smart contracts in this manner, the Massa network offers flexibility and efficiency\nin managing and executing code within its blockchain ecosystem."))),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:3,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Execute SC Payload Binary Representation"))),(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Field")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Description")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Type")))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"max_gas"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The maximum gas spendable for this operation")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"bytecode_len"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The length of the bytecode field")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"bytecode"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The bytecode to run (in the context of the caller address)")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1})),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"datastore_len"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The number of the datastore keys (u64 varint), each record is then stored one after another")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"list of datastore records")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"Concatenation of ",(0,r.kt)("inlineCode",{parentName:"p"},"key_len")," (u8), ",(0,r.kt)("inlineCode",{parentName:"p"},"key"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"value_len")," (u64 varint), ",(0,r.kt)("inlineCode",{parentName:"p"},"value"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1})))),(0,r.kt)("ol",{start:2},(0,r.kt)("li",{parentName:"ol"},"Call SC operation")),(0,r.kt)("p",null,"Here, the code is indirectly called via the call to an existing smart contract function, together with the required parameters:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:3,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Call SC Payload Binary Representation"))),(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Field")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Description")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Type")))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"max_gas"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The maximum gas spendable for this operation")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"coins"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The coins transferred in the call")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"target_address"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The address of the targeted smart contract")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"32 bytes"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"function_name_length"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The length of the name of the function that is called")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u8"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"function_name"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The name of the function that is called")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"utf8"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"param_len"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The number of parameters of the function call")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"params"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The parameters of the function call")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1})))),(0,r.kt)("h3",{id:"endorsements"},"Endorsements"),(0,r.kt)("p",null,"Endorsements are optionally included in the block, but their inclusion is incentivized for block creators. They are\nvalidations of the fact that the parent block on the thread of the block is the best parent that could have been\nchosen, done by other nodes that have also been deterministically selected via the proof of stake probability\ndistribution. A comprehensive description of endorsements can be found ",(0,r.kt)("a",{parentName:"p",href:"/docs/learn/architecture/consensus-quality#endorsement"},"here"),", so we will\nnot go further into details in the context of this introduction."))}m.isMDXComponent=!0},8819:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/block_parents-38637c12a34e50307bf25a25f082254d.svg"},5065:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/structure-5ccea2d6795f98b55e11a04ae9ce1ae7.svg"}}]); \ No newline at end of file diff --git a/assets/js/2580cc57.7351d524.js b/assets/js/2580cc57.7351d524.js deleted file mode 100644 index 87d0aa681..000000000 --- a/assets/js/2580cc57.7351d524.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[6489],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>k});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var p=n.createContext({}),l=function(e){var t=n.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},c=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,o=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=l(a),h=r,k=d["".concat(p,".").concat(h)]||d[h]||m[h]||o;return a?n.createElement(k,s(s({ref:t},c),{},{components:a})):n.createElement(k,s({ref:t},c))}));function k(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=a.length,s=new Array(o);s[0]=h;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i[d]="string"==typeof e?e:r,s[1]=i;for(var l=2;l{a.r(t),a.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>m,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var n=a(7462),r=(a(7294),a(3905));const o={id:"basic-concepts",sidebar_label:"Basic concepts"},s="Basic concepts",i={unversionedId:"learn/architecture/basic-concepts",id:"learn/architecture/basic-concepts",title:"Basic concepts",description:"Let's dive into the basic definitions and concepts of Massa blockchain.",source:"@site/docs/learn/architecture/basic-concepts.mdx",sourceDirName:"learn/architecture",slug:"/learn/architecture/basic-concepts",permalink:"/docs/learn/architecture/basic-concepts",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/learn/architecture/basic-concepts.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"basic-concepts",sidebar_label:"Basic concepts"},sidebar:"learnSidebar",previous:{title:"Welcome to Massa",permalink:"/docs/learn/introduction"},next:{title:"Node architecture",permalink:"/docs/learn/architecture/node-architecture"}},p={},l=[{value:"Ledger",id:"ledger",level:2},{value:"Address",id:"address",level:2},{value:"Smart Contract",id:"smart-contract",level:2},{value:"Autonomous Smart Contract Execution",id:"autonomous-smart-contract-execution",level:3},{value:"Storage costs",id:"storage-costs",level:2},{value:"Gas",id:"gas",level:2},{value:"Block",id:"block",level:2},{value:"Operation",id:"operation",level:2},{value:"Operation types",id:"operation-types",level:3},{value:"Transaction operations",id:"transaction-operations",level:4},{value:"Buy/Sell Rolls operations",id:"buysell-rolls-operations",level:4},{value:"Smart Contract operations",id:"smart-contract-operations",level:4},{value:"Endorsements",id:"endorsements",level:3}],c={toc:l},d="wrapper";function m(e){let{components:t,...o}=e;return(0,r.kt)(d,(0,n.Z)({},c,o,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"basic-concepts"},"Basic concepts"),(0,r.kt)("p",null,"Let's dive into the basic definitions and concepts of Massa blockchain."),(0,r.kt)("p",null,"The goal of the Massa network is to build a consensus between ",(0,r.kt)("strong",{parentName:"p"},"nodes")," to gather\nand order ",(0,r.kt)("strong",{parentName:"p"},"blocks")," that contain ordered lists of ",(0,r.kt)("strong",{parentName:"p"},"operations"),".\nAn operation ultimate purpose once executed is to act as transitions for the global network state, called the ",(0,r.kt)("strong",{parentName:"p"},"ledger"),"."),(0,r.kt)("p",null,"Operations are produced by external clients and sent to the Massa network via a node.\nSome operations are containing code to be run as ",(0,r.kt)("strong",{parentName:"p"},"smart contracts"),", enabling complex programmatic\nmodifications of the ledger.\nNodes gather pending operations and group them into blocks. Each block has limited space to store operations.\nTraditional blockchains typically link blocks sequentially, including a hash of the previous block in the block\nheader for temporal ordering. In contrast, Massa blocks are organized into a complex spatio-temporal structure,\nenabling parallelization and improved block-creation performance."),(0,r.kt)("p",null,"Instead of one chain, there are exactly 32 ",(0,r.kt)("strong",{parentName:"p"},"threads")," of chains running in parallel, with blocks equally\nspread on each thread over time, and stored inside ",(0,r.kt)("strong",{parentName:"p"},"slots")," that are spaced at fixed time intervals:"),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(5065).Z,width:"887",height:"387"})),(0,r.kt)("p",null,"The time between two slots located on the same thread is called a ",(0,r.kt)("strong",{parentName:"p"},"period")," and lasts 16s (conventionally called ",(0,r.kt)("span",{parentName:"p",className:"math math-inline"},(0,r.kt)("span",{parentName:"span",className:"katex"},(0,r.kt)("span",{parentName:"span",className:"katex-mathml"},(0,r.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,r.kt)("semantics",{parentName:"math"},(0,r.kt)("mrow",{parentName:"semantics"},(0,r.kt)("msub",{parentName:"mrow"},(0,r.kt)("mi",{parentName:"msub"},"t"),(0,r.kt)("mn",{parentName:"msub"},"0"))),(0,r.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"t_0")))),(0,r.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,r.kt)("span",{parentName:"span",className:"base"},(0,r.kt)("span",{parentName:"span",className:"strut",style:{height:"0.7651em",verticalAlign:"-0.15em"}}),(0,r.kt)("span",{parentName:"span",className:"mord"},(0,r.kt)("span",{parentName:"span",className:"mord mathnormal"},"t"),(0,r.kt)("span",{parentName:"span",className:"msupsub"},(0,r.kt)("span",{parentName:"span",className:"vlist-t vlist-t2"},(0,r.kt)("span",{parentName:"span",className:"vlist-r"},(0,r.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.3011em"}},(0,r.kt)("span",{parentName:"span",style:{top:"-2.55em",marginLeft:"0em",marginRight:"0.05em"}},(0,r.kt)("span",{parentName:"span",className:"pstrut",style:{height:"2.7em"}}),(0,r.kt)("span",{parentName:"span",className:"sizing reset-size6 size3 mtight"},(0,r.kt)("span",{parentName:"span",className:"mord mtight"},"0")))),(0,r.kt)("span",{parentName:"span",className:"vlist-s"},"\u200b")),(0,r.kt)("span",{parentName:"span",className:"vlist-r"},(0,r.kt)("span",{parentName:"span",className:"vlist",style:{height:"0.15em"}},(0,r.kt)("span",{parentName:"span"})))))))))),").\nCorresponding slots in threads are slightly shifted in time relative to one another, by one period divided by the number\nof threads, which is ",(0,r.kt)("span",{parentName:"p",className:"math math-inline"},(0,r.kt)("span",{parentName:"span",className:"katex"},(0,r.kt)("span",{parentName:"span",className:"katex-mathml"},(0,r.kt)("math",{parentName:"span",xmlns:"http://www.w3.org/1998/Math/MathML"},(0,r.kt)("semantics",{parentName:"math"},(0,r.kt)("mrow",{parentName:"semantics"},(0,r.kt)("mn",{parentName:"mrow"},"16"),(0,r.kt)("mi",{parentName:"mrow"},"s"),(0,r.kt)("mi",{parentName:"mrow",mathvariant:"normal"},"/"),(0,r.kt)("mn",{parentName:"mrow"},"32"),(0,r.kt)("mo",{parentName:"mrow"},"="),(0,r.kt)("mn",{parentName:"mrow"},"0.5"),(0,r.kt)("mi",{parentName:"mrow"},"s")),(0,r.kt)("annotation",{parentName:"semantics",encoding:"application/x-tex"},"16s/32 = 0.5s")))),(0,r.kt)("span",{parentName:"span",className:"katex-html","aria-hidden":"true"},(0,r.kt)("span",{parentName:"span",className:"base"},(0,r.kt)("span",{parentName:"span",className:"strut",style:{height:"1em",verticalAlign:"-0.25em"}}),(0,r.kt)("span",{parentName:"span",className:"mord"},"16"),(0,r.kt)("span",{parentName:"span",className:"mord mathnormal"},"s"),(0,r.kt)("span",{parentName:"span",className:"mord"},"/32"),(0,r.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}}),(0,r.kt)("span",{parentName:"span",className:"mrel"},"="),(0,r.kt)("span",{parentName:"span",className:"mspace",style:{marginRight:"0.2778em"}})),(0,r.kt)("span",{parentName:"span",className:"base"},(0,r.kt)("span",{parentName:"span",className:"strut",style:{height:"0.6444em"}}),(0,r.kt)("span",{parentName:"span",className:"mord"},"0.5"),(0,r.kt)("span",{parentName:"span",className:"mord mathnormal"},"s"))))),", so that a period contains exactly 32 slots equally spaced over the 32 threads.\nA ",(0,r.kt)("strong",{parentName:"p"},"cycle")," is defined as the succession of 128 periods and so lasts a bit more than 34min. Periods are numbered by\nincrements of one, so can be used together with a thread number to uniquely identify a block slot. Period 0 is the\ngenesis and contains genesis blocks with no parents."),(0,r.kt)("p",null,"The job of the Massa nodes network is to essentially collectively fill up slots with valid blocks. To do so,\nat each interval of 0.5s, a specific node in the network is elected to be allowed to create a block (more about\nthe selection process and the proof of stake sybil resistance mechanism ",(0,r.kt)("a",{parentName:"p",href:"/docs/learn/architecture/node-architecture#selector-module-proof-of-stake-sybil-resistance"},"here"),"),\nand will be rewarded if it creates a valid block in time. It is also possible that a node misses its opportunity\nto create the block, in which case the slot will remain empty (this is called a ",(0,r.kt)("strong",{parentName:"p"},"block miss"),")."),(0,r.kt)("p",null,"In traditional blockchains, blocks are simply referencing their unique parent, forming a chain. In the case of\nMassa, each block is referencing one parent block in each thread (so, 32 parents). Here is an example\nillustrated with one particular block:"),(0,r.kt)("p",null,(0,r.kt)("img",{src:a(8819).Z,width:"887",height:"328"})),(0,r.kt)("p",null,"Let\u2019s introduce some relevant definitions and concepts generally necessary to understand how the Massa network operates.\nWe will then explain the node architecture and how the whole system works."),(0,r.kt)("h2",{id:"ledger"},"Ledger"),(0,r.kt)("p",null,"The ledger is a map that stores a global mapping between addresses and information related to these addresses.\nIt is replicated in each node. The consensus building mechanism ensures that agreement on what operations have\nbeen finalized (and in what order) will be reached over the whole network. The ledger is the state of the Massa network,\nand operations (see below) are requests to modify the ledger. "),(0,r.kt)("p",null,"The information stored in the ledger with each address is the following:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:2,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Ledger Information Associated with Each Address")))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"balance"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The amount of Massa coins owned by the address."))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"bytecode"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"When the address references a smart contract, this is the compiled code corresponding to the smart contract (typically contains several functions that act as API entry points)."))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"datastore"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"A key/value map that can store any persistent data related to a smart contract, its variables, etc."))))),(0,r.kt)("p",null,"In order to promote widespread adoption and facilitate node running with reduced entry fees, the size of the ledger in Massa\nhas been limited to a maximum of 1 TB.\nThis decision sets Massa apart from other benchmark blockchain ledgers and makes it more accessible to users."),(0,r.kt)("p",null,"To achieve such a small ledger size, several technical decisions were made.\nFirstly, state changes that have been finalized and are found in the final Blocks no longer require record-keeping in the Ledger's memory.\nThis optimization helps minimize the storage requirements for historical data, allowing the ledger to operate efficiently within the specified size limit."),(0,r.kt)("p",null,"In addition to this, Massa has introduced ",(0,r.kt)("a",{parentName:"p",href:"/docs/learn/storage-costs"},"Storage Costs")," as a novel approach to enhance storage efficiency.\nUsers are now required to lock a certain amount of coins when they claim storage space.\nThis innovative correlation between storage and circulating coins ensures a balanced utilization of resources.\nBy implementing this mechanism, Massa optimizes storage utilization while maintaining the integrity and security of the ledger."),(0,r.kt)("p",null,"These technical decisions, including the exclusion of finalized state changes from ledger memory and the introduction of Storage\nCosts, play a crucial role in enabling the compact size of the ledger and ultimately facilitating a more efficient and accessible\nblockchain ecosystem."),(0,r.kt)("h2",{id:"address"},"Address"),(0,r.kt)("p",null,"An address on the Massa blockchain serves as your unique identity, granting you the ability to engage in various operations,\nstore information, and exchange data with other participants. With an address, you gain access to a wide range of functionalities\nwithin the blockchain ecosystem."),(0,r.kt)("p",null,"Using your address, you can initiate operations that interact with the blockchain.\nThis includes executing transactions, submitting smart contract calls, and engaging in other blockchain activities.\nYour address acts as the key to unlock these capabilities, allowing you to participate fully in the decentralized network."),(0,r.kt)("p",null,"Furthermore, your address enables you to store and retrieve information on the blockchain. Whether it's personal data, financial records, or any other form of digital information, you can securely store it using your address as the reference. This provides a reliable and immutable storage solution within the blockchain environment."),(0,r.kt)("p",null,"Importantly, your address also facilitates communication and data exchange with other participants on the blockchain.\nBy sharing your address with others, you can interact, transact, and collaborate with different individuals and entities\nwithin the blockchain network.\nThis seamless exchange of data and value promotes a decentralized and interconnected ecosystem."),(0,r.kt)("p",null,"Each user address on Massa has a public and private key associated with it.\nThis is how messages can be signed and identity enforced.\nThe address of an account is simply the hash of its public key. "),(0,r.kt)("p",null,"Addresses are generated using a specific format that includes a prefix ",(0,r.kt)("inlineCode",{parentName:"p"},"A")," and a base58 encoding. The prefix distinguishes between user addresses, linked to a KeyPair, and smart-contract addresses, denoted by the prefixes ",(0,r.kt)("inlineCode",{parentName:"p"},"U")," or ",(0,r.kt)("inlineCode",{parentName:"p"},"S")," respectively."),(0,r.kt)("p",null,"For user addresses (AU), the hash calculation involves taking the Blake3 hash of the byte representation of\nthe user's public key.\nThis process ensures a unique and secure identification for each user address within the system."),(0,r.kt)("h2",{id:"smart-contract"},"Smart Contract"),(0,r.kt)("p",null,"Smart contracts are a piece of code that can be run inside the Massa virtual machine, which can modify the ledger,\nand accept incoming requests through a public interface (via smart-contract operations). "),(0,r.kt)("p",null,"Smart contracts are currently written in AssemblyScript, a derivation from TypeScript, which is itself a\ntype-safe version of JavaScript. AssemblyScript compiles to WebAssembly bytecode (wasm). Massa nodes Execution Module runs such bytecode.\nSmart contracts have access to their own datastore, so they can modify the ledger."),(0,r.kt)("p",null,"Smart contracts follow a different hash calculation than user addresses. It begins by constructing a byte array comprising various elements.\nThis array consists of the slot represented in 5 bytes, with 4 bytes allocated for the period (encoded as a u64 in big endian\nformat), 1 byte for the thread, and an index that increments for each address created within the same slot.\nThe index value is represented as a u64 in big endian format and is reset at the start of each new slot.\nAdditionally, a single byte is appended to indicate whether the address is for real execution (1) or read-only execution (0)."),(0,r.kt)("p",null,"The resulting byte array is then subject to the Blake3 hash function, generating a unique\nhash value that serves as the SC address."),(0,r.kt)("h3",{id:"autonomous-smart-contract-execution"},"Autonomous Smart Contract Execution"),(0,r.kt)("p",null,"One particularity of Massa smart contracts compared to other blockchain smart contracts is their ability to wake\nup by themselves independently of an exterior request on their interface. We call them Autonomous Smart Contracts (ASCs),\nas they allow more autonomy and less dependency on external centralized services."),(0,r.kt)("p",null,"ASCs offer a plethora of use cases that leverage their self wake-up functionality.\nIn the realm of Decentralized Finance (DeFi), these contracts can automate liquidations,\nyield farming strategies, and portfolio rebalancing.\nSupply chain management benefits from autonomous contracts through automated inventory management and quality control processes.\nIn the insurance industry, claims settlements can be accelerated with instant payments and parametric insurance.\nGaming and NFT platforms can provide dynamic and interactive experiences with evolving NFTs and automated auctions.\nAdditionally, real estate transactions can be streamlined with escrow automation and simplified rental agreements.\nThese use cases exemplify the transformative potential of Autonomous Smart Contracts in enabling automated and efficient\nprocesses across various industries."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"Learn more about Autonomous Smart Contracts ",(0,r.kt)("a",{parentName:"p",href:"/docs/learn/asc/intro"},"here"),".")),(0,r.kt)("h2",{id:"storage-costs"},"Storage costs"),(0,r.kt)("p",null,"In Massa, each network node maintains a full copy of the ledger. Having a massive ledger size (hundreds of terabytes), would pose high entry barriers for potential node runners. To ensure smooth operation and enable node hosting at home, it's essential to establish a reasonable size limit, and remove the need for excessive storage capacity. After careful consideration, we have determined that a storage size limit of 1TB strikes the right balance. This means that each participant can store data on the ledger until it reaches the 1TB threshold. By implementing this limit, we aim to promote widespread adoption and empower individuals to run nodes effortlessly. "),(0,r.kt)("p",null,"In order to enforce this limit, users are required to lock a corresponding amount of coins for each byte of storage they claim. This applies to various data elements such as your address, balance, keys in your datastore, bytecode, and more. By locking coins, you establish a commitment that ensures fair usage of storage resources. Once you release your allocated space in the storage, the locked coins are subsequently released as well. This mechanism guarantees a balanced and accountable approach to managing storage within the network."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Read more about storage costs ",(0,r.kt)("a",{parentName:"p",href:"/docs/learn/storage-costs"},"here"),".")),(0,r.kt)("h2",{id:"gas"},"Gas"),(0,r.kt)("p",null,"In Massa, there is no Gas price.\nEach operation declares a max amount of gas that it can use, and provides a fee that is added to the rewards of the block in which the operation is executed."),(0,r.kt)("p",null,"Block producers then choose which operations to include in their blocks to fit the max block gas and max block size constraints while maximizing the total fee."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Read more about gas ",(0,r.kt)("a",{parentName:"p",href:"/docs/learn/gas"},"here"),".")),(0,r.kt)("h2",{id:"block"},"Block"),(0,r.kt)("p",null,"A block is a data structure built by nodes and its function is to aggregate several operations. As explained above,\nfor each new slot that becomes active, a particular node in the network is elected in a deterministic way with the\ntask of creating the block that will be stored in that slot (more about this in the description of the Selector\nModule below). A block from a given thread can only contain operations originating from a creator_public_key whose\nhash\u2019s five first bits designate the corresponding thread, thus implicitly avoiding collisions in operations integrated into parallel threads. Block size is limited to 1 MB."),(0,r.kt)("p",null,"The content of a block is as follows:"),(0,r.kt)("table",null,(0,r.kt)("tr",null,(0,r.kt)("th",{colspan:"2"},"Block header")),(0,r.kt)("tr",null,(0,r.kt)("td",null,(0,r.kt)("code",null,"slot")),(0,r.kt)("td",null,"A description of the block slot, defined by a couple (period, thread) that uniquely identify it")),(0,r.kt)("tr",null,(0,r.kt)("td",null,(0,r.kt)("code",null,"creator_public_key")),(0,r.kt)("td",null,"The public key of the block creator (32 bytes)")),(0,r.kt)("tr",null,(0,r.kt)("td",null,(0,r.kt)("code",null,"parents")),(0,r.kt)("td",null,"A list of the 32 parents of the block, one parent per thread (parent blocks are identified by the block hash)")),(0,r.kt)("tr",null,(0,r.kt)("td",null,(0,r.kt)("code",null,"endorsements")),(0,r.kt)("td",null,"A list of the 16 endorsements for the block (more about endorsements below)")),(0,r.kt)("tr",null,(0,r.kt)("td",null,(0,r.kt)("code",null,"operations_hash")),(0,r.kt)("td",null,"A hash of all the operations included in the block (=hash of the block body below)")),(0,r.kt)("tr",null,(0,r.kt)("td",null,(0,r.kt)("code",null,"signature")),(0,r.kt)("td",null,"Signature of all the above with the private key of the block creator")),(0,r.kt)("tr",null,(0,r.kt)("th",{colspan:"2"},"Block body")),(0,r.kt)("tr",null,(0,r.kt)("td",null,(0,r.kt)("code",null,"operations")),(0,r.kt)("td",null,"The list of all operations included in the block"))),(0,r.kt)("h2",{id:"operation"},"Operation"),(0,r.kt)("p",null,"At its core, the Massa network revolves around the aggregation, sequencing, and execution of operations. Operations are\nrecorded inside blocks that are located in slots. "),(0,r.kt)("p",null,"Operations are denoted by a string prefixed with 'O' that encapsulate crucial information within a byte array.\nThe byte array encompasses the version in a u64 varint format, the Blake3 hash of the fully serialized content\nof the operation, and the public key of the creator.\nBy meticulously organizing and recording operations within blocks that reside in specific slots,\nthe Massa network ensures the integrity and efficiency of its operations."),(0,r.kt)("h3",{id:"operation-types"},"Operation types"),(0,r.kt)("p",null,"There are three types of operations: transactions, roll operations, and smart contract code execution.\nThe general structure of an operation is the following, and the different types of operations differ by their payload:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:3,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Transaction Binary Representation"))),(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Field")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Description")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Type")))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"creator_public_key"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The public key of the operation creator")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"32 bytes"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"expiration_period"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"Period after which the operation is expired")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"fee"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The amount of fees the creator is willing to pay")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"type"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The type of operation\n(from 0 to 4: transaction, rollbuy, rollsell, executesc,\ncallsc)")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"payload"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The content of the operation")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"see each operation"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"signature"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"Signature of all the above with the private key of the\noperation creator")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"64 bytes"))))),(0,r.kt)("h4",{id:"transaction-operations"},"Transaction operations"),(0,r.kt)("p",null,"Transactions are operations that move native Massa coins between addresses. Here is the corresponding payload:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:3,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Transaction Payload Binary Representation"))),(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Field")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Description")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Type")))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"amount"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The amount of coins to transfer")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"destination_address"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The address of the recipient")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"32 bytes"))))),(0,r.kt)("h4",{id:"buysell-rolls-operations"},"Buy/Sell Rolls operations"),(0,r.kt)("p",null,"Rolls are staking tokens that participants can buy or sell with native Massa coins. By owning rolls,\naddresses can participate in block creation ",(0,r.kt)("a",{parentName:"p",href:"/docs/node/stake"},"more about staking below"),".\nThis is done via special operations, with a simple payload:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:3,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Buy/Sell Rolls Payload Binary Representation"))),(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Field")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Description")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Type")))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"nb_of_rolls"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The number of rolls to buy or sell")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))))),(0,r.kt)("h4",{id:"smart-contract-operations"},"Smart Contract operations"),(0,r.kt)("p",null,"Smart Contracts are pieces of code that can be run inside the Massa virtual machine. There are two ways\nof calling for the execution of code; by direct execution of bytecode, and by a smart-contract function call.\nFormer is done using the Execute SC operation, and latter with Call SC operation."),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("p",{parentName:"li"},"Execute SC operation"),(0,r.kt)("p",{parentName:"li"},"The ExecuteSC operation provides a powerful functionality within the Massa network by enabling the execution of smart contracts\ndirectly instead of storing them.\nInstead of storing the bytecode, the code itself is placed within the operation as a smart contract.\nWhen the ExecuteSC operation is executed, the blockchain triggers the execution of the main function within\nthe smart contract code. After the code is executed, the blockchain proceeds to other tasks while retaining\nand reflecting the changes made to the ledger and other relevant data.\nThis approach ensures that the executed changes are recorded and maintained on the ledger, rather than\nretaining the bytecode itself.\nBy executing smart contracts in this manner, the Massa network offers flexibility and efficiency\nin managing and executing code within its blockchain ecosystem."))),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:3,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Execute SC Payload Binary Representation"))),(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Field")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Description")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Type")))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"max_gas"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The maximum gas spendable for this operation")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"bytecode_len"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The length of the bytecode field")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"bytecode"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The bytecode to run (in the context of the caller address)")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1})),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"datastore_len"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The number of the datastore keys (u64 varint), each record is then stored one after another")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"list of datastore records")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"Concatenation of ",(0,r.kt)("inlineCode",{parentName:"p"},"key_len")," (u8), ",(0,r.kt)("inlineCode",{parentName:"p"},"key"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"value_len")," (u64 varint), ",(0,r.kt)("inlineCode",{parentName:"p"},"value"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1})))),(0,r.kt)("ol",{start:2},(0,r.kt)("li",{parentName:"ol"},"Call SC operation")),(0,r.kt)("p",null,"Here, the code is indirectly called via the call to an existing smart contract function, together with the required parameters:"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:3,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Call SC Payload Binary Representation"))),(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Field")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Description")),(0,r.kt)("th",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"th"},"Type")))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"max_gas"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The maximum gas spendable for this operation")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"coins"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The coins transferred in the call")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"target_address"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The address of the targeted smart contract")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"32 bytes"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"function_name_length"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The length of the name of the function that is called")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u8"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"function_name"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The name of the function that is called")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"utf8"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"param_len"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The number of parameters of the function call")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"u64 varint"))),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},(0,r.kt)("inlineCode",{parentName:"p"},"params"))),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1},(0,r.kt)("p",{parentName:"td"},"The parameters of the function call")),(0,r.kt)("td",{parentName:"tr",colSpan:1,rowSpan:1})))),(0,r.kt)("h3",{id:"endorsements"},"Endorsements"),(0,r.kt)("p",null,"Endorsements are optionally included in the block, but their inclusion is incentivized for block creators. They are\nvalidations of the fact that the parent block on the thread of the block is the best parent that could have been\nchosen, done by other nodes that have also been deterministically selected via the proof of stake probability\ndistribution. A comprehensive description of endorsements can be found ",(0,r.kt)("a",{parentName:"p",href:"/docs/learn/architecture/consensus-quality#endorsement"},"here"),", so we will\nnot go further into details in the context of this introduction."))}m.isMDXComponent=!0},8819:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/block_parents-38637c12a34e50307bf25a25f082254d.svg"},5065:(e,t,a)=>{a.d(t,{Z:()=>n});const n=a.p+"assets/images/structure-5ccea2d6795f98b55e11a04ae9ce1ae7.svg"}}]); \ No newline at end of file diff --git a/assets/js/28d23288.afed3aba.js b/assets/js/28d23288.afed3aba.js deleted file mode 100644 index 85c608c1c..000000000 --- a/assets/js/28d23288.afed3aba.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[2247],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>k});var a=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function l(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function s(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var i=a.createContext({}),u=function(e){var n=a.useContext(i),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=u(e.components);return a.createElement(i.Provider,{value:n},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},m=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,l=e.originalType,i=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),c=u(t),m=r,k=c["".concat(i,".").concat(m)]||c[m]||d[m]||l;return t?a.createElement(k,s(s({ref:n},p),{},{components:t})):a.createElement(k,s({ref:n},p))}));function k(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var l=t.length,s=new Array(l);s[0]=m;var o={};for(var i in n)hasOwnProperty.call(n,i)&&(o[i]=n[i]);o.originalType=e,o[c]="string"==typeof e?e:r,s[1]=o;for(var u=2;u{t.d(n,{Z:()=>s});var a=t(7294),r=t(6010);const l={tabItem:"tabItem_Ymn6"};function s(e){let{children:n,hidden:t,className:s}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(l.tabItem,s),hidden:t},n)}},4866:(e,n,t)=>{t.d(n,{Z:()=>_});var a=t(7462),r=t(7294),l=t(6010),s=t(2466),o=t(6550),i=t(1980),u=t(7392),p=t(12);function c(e){return function(e){return r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:n,label:t,attributes:a,default:r}}=e;return{value:n,label:t,attributes:a,default:r}}))}function d(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??c(t);return function(e){const n=(0,u.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,t])}function m(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function k(e){let{queryString:n=!1,groupId:t}=e;const a=(0,o.k6)(),l=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,i._X)(l),(0,r.useCallback)((e=>{if(!l)return;const n=new URLSearchParams(a.location.search);n.set(l,e),a.replace({...a.location,search:n.toString()})}),[l,a])]}function b(e){const{defaultValue:n,queryString:t=!1,groupId:a}=e,l=d(e),[s,o]=(0,r.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({value:n,tabValues:t}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const a=t.find((e=>e.default))??t[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:n,tabValues:l}))),[i,u]=k({queryString:t,groupId:a}),[c,b]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[a,l]=(0,p.Nk)(t);return[a,(0,r.useCallback)((e=>{t&&l.set(e)}),[t,l])]}({groupId:a}),h=(()=>{const e=i??c;return m({value:e,tabValues:l})?e:null})();(0,r.useLayoutEffect)((()=>{h&&o(h)}),[h]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);o(e),u(e),b(e)}),[u,b,l]),tabValues:l}}var h=t(2389);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function f(e){let{className:n,block:t,selectedValue:o,selectValue:i,tabValues:u}=e;const p=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.o5)(),d=e=>{const n=e.currentTarget,t=p.indexOf(n),a=u[t].value;a!==o&&(c(n),i(a))},m=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const t=p.indexOf(e.currentTarget)+1;n=p[t]??p[0];break}case"ArrowLeft":{const t=p.indexOf(e.currentTarget)-1;n=p[t]??p[p.length-1];break}}n?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":t},n)},u.map((e=>{let{value:n,label:t,attributes:s}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:o===n?0:-1,"aria-selected":o===n,key:n,ref:e=>p.push(e),onKeyDown:m,onClick:d},s,{className:(0,l.Z)("tabs__item",g.tabItem,s?.className,{"tabs__item--active":o===n})}),t??n)})))}function N(e){let{lazy:n,children:t,selectedValue:a}=e;const l=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=l.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},l.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==a}))))}function v(e){const n=b(e);return r.createElement("div",{className:(0,l.Z)("tabs-container",g.tabList)},r.createElement(f,(0,a.Z)({},e,n)),r.createElement(N,(0,a.Z)({},e,n)))}function _(e){const n=(0,h.Z)();return r.createElement(v,(0,a.Z)({key:String(n)},e))}},7250:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>i,default:()=>k,frontMatter:()=>o,metadata:()=>u,toc:()=>c});var a=t(7462),r=(t(7294),t(3905)),l=t(4866),s=t(5162);const o={id:"jsonrpc",sidebar_label:"JsonRPC"},i="Massa JSON-RPC API",u={unversionedId:"build/api/jsonrpc",id:"build/api/jsonrpc",title:"Massa JSON-RPC API",description:"The JsonRPC API allows you to communicate with the Massa blockchain.",source:"@site/docs/build/api/jsonrpc.mdx",sourceDirName:"build/api",slug:"/build/api/jsonrpc",permalink:"/docs/build/api/jsonrpc",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/api/jsonrpc.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"jsonrpc",sidebar_label:"JsonRPC"},sidebar:"buildSidebar",previous:{title:"Providers",permalink:"/docs/build/api/providers"},next:{title:"gRPC",permalink:"/docs/build/api/grpc"}},p={},c=[{value:"Integrations",id:"integrations",level:2},{value:"Explore the Blockchain",id:"explore-the-blockchain",level:2},{value:"get_status",id:"get_status",level:3},{value:"get_cliques",id:"get_cliques",level:3},{value:"get_stakers",id:"get_stakers",level:3},{value:"get_addresses",id:"get_addresses",level:3},{value:"get_graph_interval",id:"get_graph_interval",level:3},{value:"get_blocks",id:"get_blocks",level:3},{value:"get_operations",id:"get_operations",level:3},{value:"get_endorsements",id:"get_endorsements",level:3},{value:"WebSockets support",id:"websockets-support",level:2},{value:"Error codes",id:"error-codes",level:2}],d={toc:c},m="wrapper";function k(e){let{components:n,...o}=e;return(0,r.kt)(m,(0,a.Z)({},d,o,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"massa-json-rpc-api"},"Massa JSON-RPC API"),(0,r.kt)("p",null,"The JsonRPC API allows you to communicate with the Massa blockchain."),(0,r.kt)("p",null,"The Massa JSON-RPC API is splitted in two parts:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Private API"),": used for node management. Default port: 33034 e.g.\n",(0,r.kt)("a",{parentName:"li",href:"http://localhost:33034"},"http://localhost:33034")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Public API"),": used for blockchain interactions. Default port:\n33035 e.g. ",(0,r.kt)("a",{parentName:"li",href:"http://localhost:33035"},"http://localhost:33035"))),(0,r.kt)("p",null,"The complete Massa ",(0,r.kt)("a",{parentName:"p",href:"https://spec.open-rpc.org/"},"OpenRPC")," specification is available\n",(0,r.kt)("a",{parentName:"p",href:"https://raw.githubusercontent.com/massalabs/massa/main/massa-node/base_config/openrpc.json"},"here"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("a",{parentName:"p",href:"https://playground.open-rpc.org/?schemaUrl=https://test.massa.net/api/v2&uiSchema%5BappBar%5D%5Bui:input%5D=false&uiSchema%5BappBar%5D%5Bui:inputPlaceholder%5D=Enter+Massa+JSON-RPC+server+URL&uiSchema%5BappBar%5D%5Bui:logoUrl%5D=https://massa.net/favicons/favicon.ico&uiSchema%5BappBar%5D%5Bui:splitView%5D=false&uiSchema%5BappBar%5D%5Bui:darkMode%5D=false&uiSchema%5BappBar%5D%5Bui:title%5D=Massa&uiSchema%5BappBar%5D%5Bui:examplesDropdown%5D=false&uiSchema%5Bmethods%5D%5Bui:defaultExpanded%5D=false&uiSchema%5Bmethods%5D%5Bui:methodPlugins%5D=true&uiSchema%5Bparams%5D%5Bui:defaultExpanded%5D=false"},"Interactive API Specification"),"\ndocuments every available method and allows you to play with the API."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"Massa has a new experimental API with both Http and WebSocket support:\nDefault port: 33036"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Http"),": used for node management and blockchain interactions. e.g.\n",(0,r.kt)("a",{parentName:"li",href:"http://localhost:33036"},"http://localhost:33036")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"WebSocket"),": used for streaming blockchain events. e.g.\n",(0,r.kt)("a",{parentName:"li",href:"ws://localhost:33036"},"ws://localhost:33036")))),(0,r.kt)("h2",{id:"integrations"},"Integrations"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"JavaScript"),": The ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/massalabs/massa-web3"},"massa-web3")," TypeScript library\ncan be used to call the JSON-RPC API... and much more."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Postman"),": You can find our Massa Postman collections on our official ",(0,r.kt)("a",{parentName:"li",href:"https://www.postman.com/massalabs"},"workspace"),".")),(0,r.kt)("h2",{id:"explore-the-blockchain"},"Explore the Blockchain"),(0,r.kt)("p",null,"In this section we'll learn how to interact with Massa blockchain using the public API via\ncURL commands which will create JSON-RPC request calls."),(0,r.kt)("h3",{id:"get_status"},"get_status"),(0,r.kt)("p",null,"Summary of the current state: time, last final blocks (hash, thread,\nslot, timestamp), clique count, connected nodes count."),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_status",\n "params": []\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_status",\n "params": []\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "result": {\n "node_id": "N1VRyXjUaHeJd4Rmr3waVmpZDFzzH5ARRi3f5ye5BYgxBmxHC7X",\n "node_ip": "141.94.218.103",\n "version": "SECU.27.0",\n "current_time": 1699881695772,\n "current_cycle": 208,\n "current_cycle_time": 1699879784000,\n "next_cycle_time": 1699881832000,\n "connected_nodes": {\n "N13Ykon8Zo73PTKMruLViMMtE2rEG646JQ4sCcee2DnopmVM3P5": [\n "::ffff:51.75.60.228",\n false\n ],\n "N1XxexKa3XNzvmakNmPawqFrE9Z2NFhfq1AhvV1Qx4zXq5p1Bp9": [\n "::ffff:158.69.23.120",\n false\n ],\n "N1qxuqNnx9kyAMYxUfsYiv2gQd5viiBX126SzzexEdbbWd2vQKu": [\n "::ffff:198.27.74.5",\n false\n ],\n "N12UbyLJDS7zimGWf3LTHe8hYY67RdLke1iDRZqJbQQLHQSKPW8j": [\n "::ffff:149.202.86.103",\n false\n ],\n "N12rPDBmpnpnbECeAKDjbmeR19dYjAUwyLzsa8wmYJnkXLCNF28E": [\n "::ffff:158.69.120.215",\n false\n ],\n "N12vxrYTQzS5TRzxLfFNYxn6PyEsphKWkdqx2mVfEuvJ9sPF43uq": [\n "::ffff:149.202.89.125",\n false\n ]\n },\n "last_slot": {\n "period": 26743,\n "thread": 15\n },\n "next_slot": {\n "period": 26743,\n "thread": 16\n },\n "consensus_stats": {\n "start_timespan": 1699881635772,\n "end_timespan": 1699881695772,\n "final_block_count": 121,\n "stale_block_count": 0,\n "clique_count": 1\n },\n "pool_stats": [\n 0,\n 96\n ],\n "network_stats": {\n "in_connection_count": 6,\n "out_connection_count": 0,\n "known_peer_count": 7,\n "banned_peer_count": 0,\n "active_node_count": 6\n },\n "execution_stats": {\n "time_window_start": 1699881635772,\n "time_window_end": 1699881695772,\n "final_block_count": 121,\n "final_executed_operations_count": 0,\n "active_cursor": {\n "period": 26743,\n "thread": 11\n },\n "final_cursor": {\n "period": 26741,\n "thread": 14\n }\n },\n "config": {\n "genesis_timestamp": 1699453800000,\n "end_timestamp": null,\n "thread_count": 32,\n "t0": 16000,\n "delta_f0": 1088,\n "operation_validity_periods": 10,\n "periods_per_cycle": 128,\n "block_reward": "1.02",\n "roll_price": "100",\n "max_block_size": 300000\n }\n },\n "id": 1\n}\n')))),(0,r.kt)("h3",{id:"get_cliques"},"get_cliques"),(0,r.kt)("p",null,"Get information about the block\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.massa.net/docs/learn/architecture/node-architecture#block-cliques"},"cliques"),"\nof the graph."),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_cliques",\n "params": []\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_cliques",\n "params": []\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n"result": [\n {\n "block_ids": [\n "B12RHJKyPx8DdGHMevdP8Uyxidcg3nThb9XEnHXEJR7cbBi6JrR9",\n ...\n "B12c7xPkmdy3qbAF1rWn7XeTBdum6VHbYJiW5MUuyBGnshrf5NW8"\n ],\n "fitness": 1117,\n "is_blockclique": true\n }\n],\n"id": 1\n}\n')))),(0,r.kt)("h3",{id:"get_stakers"},"get_stakers"),(0,r.kt)("p",null,"Get information about active\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.massa.net/docs/node/stake"},"stakers")," and\ntheir roll counts for the current cycle."),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_stakers",\n "params": [ {"offset": 0, "limit": 2 }]\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_stakers",\n "params": [ {"offset": 0, "limit": 2 }]\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n"jsonrpc": "2.0",\n"result": [\n [\n "AU12gAkmGeozFceJD4tQmbVvihYdX2KyWZcYLL8xdYZeP4EuWYdex",\n 145\n ],\n [\n "AU18A67vpbjHPq7KgFnMbezoJuGcjVLZsF4ybx4rEbnA3wZ1Gy7c",\n 124\n ]\n],\n}\n')))),(0,r.kt)("h3",{id:"get_addresses"},"get_addresses"),(0,r.kt)("p",null,"Get information about\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.massa.net/docs/learn/architecture/basic-concepts#address"},"address"),"\n(es) (balances, block creation, ",".","..)."),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_addresses",\n "params": [["AU12gAkmGeozFceJD4tQmbVvihYdX2KyWZcYLL8xdYZeP4EuWYdex"]]\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_addresses",\n "params": [["AU12gAkmGeozFceJD4tQmbVvihYdX2KyWZcYLL8xdYZeP4EuWYdex"]]\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n"result": [\n {\n "address": "AU12gAkmGeozFceJD4tQmbVvihYdX2KyWZcYLL8xdYZeP4EuWYdex",\n "thread": 27,\n "final_balance": "153.519945908",\n "final_roll_count": 145,\n "final_datastore_keys": [],\n "candidate_balance": "153.755240036",\n "candidate_roll_count": 145,\n "candidate_datastore_keys": [],\n "deferred_credits": [],\n "next_block_draws": [\n {\n "period": 25784,\n "thread": 5\n },\n ...\n {\n "slot": {\n "period": 25791,\n "thread": 29\n },\n "index": 1\n }\n ],\n "created_blocks": [\n "B12Y4eqmeJ5uWakcgZXRqDxRzFstKt8KJd2MgMSysqcMX4eWoaw4",\n "B12CANhVvuBpXtjyVS5kkZBGmw5wanvEuuF34ct3GABHLLAMroxT",\n "B122nYsgcJ72Cor9RcZB6ZGduc4pFm97srfGEPiijeZq9k1VatBS",\n "B12TC646QjDoQWAPuAYhsy9i8f3qdzajFas25eJsRXaj1mbBhGRk",\n "B12aFhukUBCz8TXJK5SakyT6MW18GTFNiRoeUKqzXT6e2ePbutor"\n ],\n "created_operations": [],\n "created_endorsements": [\n "E12uK8JkAkMpC5gDXaa26Vxvu8nRL5ZvD61WFjToeyTDVexnzYcH",\n ...\n "E12XbfbSzPvVRyW1mGhxBpkrDBzVdGdZvRkaYpDbrUP96fCZteSy"\n ],\n "cycle_infos": [\n {\n "cycle": 197,\n "is_final": true,\n "ok_count": 48,\n "nok_count": 0,\n "active_rolls": null\n },\n ...\n {\n "cycle": 201,\n "is_final": false,\n "ok_count": 11,\n "nok_count": 0,\n "active_rolls": 145\n }\n ]\n }\n],\n"id": 1\n}\n')))),(0,r.kt)("h3",{id:"get_graph_interval"},"get_graph_interval"),(0,r.kt)("p",null,"Get information about block graph\nwithin the specified time interval."),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_graph_interval",\n "params": [{"start": 1678095527706, "end": 1678095529706}]\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_graph_interval",\n "params": [{"start": 1678095527706, "end": 1678095529706}]\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n"result": [\n {\n "id": "B1pd4hCpPnHM8QMvKp9uGM5sdUZoq6s9wERwk7z9ANoo8FSTJ7j",\n "is_final": false,\n "is_stale": false,\n "is_in_blockclique": true,\n "slot": {\n "period": 25795,\n "thread": 17\n },\n "creator": "AU12tr8pSnamJRQEdm4K9DaogpdANXF636XNV13iNHAL6bLpKxooR",\n "parents": [\n "B12echxHFVHsCsWaRxL5pxPmYtefjhuJDNtd7TX6iseF6jxdyZnS",\n ...\n "B12WQuyYopKPLkK9HF2eRaJDRbnE2cAhqT19XpGT2gMh9o4E2BrL"\n ]\n },\n {\n "id": "B12G3GVLNct669ZiAQQDsXW9Mbo5PHtmwrEKNAvnBVa11kqqps5n",\n "is_final": false,\n "is_stale": false,\n "is_in_blockclique": true,\n "slot": {\n "period": 25795,\n "thread": 16\n },\n "creator": "AU1LJYrJQiQZYqiktgrbb5MWgSnd1FuUQqhQsw48PPdrAB3uqLCS",\n "parents": [\n "B12echxHFVHsCsWaRxL5pxPmYtefjhuJDNtd7TX6iseF6jxdyZnS",\n ...\n "B12WQuyYopKPLkK9HF2eRaJDRbnE2cAhqT19XpGT2gMh9o4E2BrL"\n ]\n },\n {\n "id": "B12RYZz9S8PuqWvQUFStxmTDb4j3UqfVEkNqeBwYDvwCrnzBMJ8J",\n "is_final": false,\n "is_stale": false,\n "is_in_blockclique": true,\n "slot": {\n "period": 25795,\n "thread": 18\n },\n "creator": "AU1vWZXTD4YdfdbqWS3RRgnH5DBdJSfgwVi9vJztH2V3iNMakzKo",\n "parents": [\n "B12echxHFVHsCsWaRxL5pxPmYtefjhuJDNtd7TX6iseF6jxdyZnS",\n ...\n "B12WQuyYopKPLkK9HF2eRaJDRbnE2cAhqT19XpGT2gMh9o4E2BrL"\n ]\n }\n],\n"id": 1\n}\n')))),(0,r.kt)("h3",{id:"get_blocks"},"get_blocks"),(0,r.kt)("p",null,"Get information about ",(0,r.kt)("a",{parentName:"p",href:"https://docs.massa.net/docs/learn/architecture/basic-concepts#block"},"block(s)"),"\nassociated to a given hash(s)."),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_blocks",\n "params": [["B122ByHzPVJ3QFwmuYcZ4vZYzq6rfkqx7BJSJdFNHWp9j2o5Fpxv"]]\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_blocks",\n "params": [["B122ByHzPVJ3QFwmuYcZ4vZYzq6rfkqx7BJSJdFNHWp9j2o5Fpxv"]]\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n"result": [\n {\n "id": "B122ByHzPVJ3QFwmuYcZ4vZYzq6rfkqx7BJSJdFNHWp9j2o5Fpxv",\n "content": {\n "is_final": true,\n "is_in_blockclique": false,\n "is_candidate": false,\n "is_discarded": false,\n "block": {\n "header": {\n "content": {\n "slot": {\n "period": 25787,\n "thread": 4\n },\n "parents": [\n "B12L3Cvj8EZiX6sCryti4fqZ3nZ4tbDiYjtyAxVoYfJUxfPuN2Lm",\n ...\n "B1xMgVk5hcp8qdFzvCeG3SqS3AA4i52fAXw7kZn4DzJWnXGgZDW"\n ],\n "operation_merkle_root": "8uJok77DvcHgdzqzMQ62yu6nV9tKqTU6JhsCtvWxBK6VsabSZ",\n "endorsements": [\n {\n "content": {\n "slot": {\n "period": 25787,\n "thread": 4\n },\n "index": 0,\n "endorsed_block": "B1PF5E4D3LKa6soJ8BXv6nveHFHRPzBYtqysVWhLZT5fmnedc6T"\n },\n "signature": "V21cLHbr5mUzpRrRHc66EkvsDh5KZHvWKfFhFo2B2ni9qVK9p8nhPuE14btaWXAN7ru4d7q7jm9TcW55McXd2smhd6NbP",\n "content_creator_pub_key": "P1bi78ormwmdSYuvmk77ZbQsyz4VDqEZZGKnXVWyksJYitx6nwJ",\n "content_creator_address": "AU12ta1W4CcLrQmBAYEc7BPCopj8zqyJzBmFncYcXQQw2N2M5SC6U",\n "id": "E1KLYEDm4qBUxi1SDHo3tf3dCGJ5kDYL3w8N766KgnYZV6A7omy"\n },\n ...\n {\n "content": {\n "slot": {\n "period": 25787,\n "thread": 4\n },\n "index": 15,\n "endorsed_block": "B1PF5E4D3LKa6soJ8BXv6nveHFHRPzBYtqysVWhLZT5fmnedc6T"\n },\n "signature": "E3HGbZvJEPVZcRUYDUpnk4R8t9p941MKZTK3awTXTMpG1pufThBu9CpNd7YDW1mkEc4ZJB31Hcvp8cKVPe57MBUJutu1c",\n "content_creator_pub_key": "P123qyM3ZzUw5Mi7uxj8mKYNHo7H7ybTQWZy53cR7BHhXbTxrT8z",\n "content_creator_address": "AU1Xr8m6utu6DBXyRCFGrD2jPCa62tnwNwkkJSCnh4iWQG3M63za",\n "id": "E12rQSKKLw1wXBXajvjGS9PB8NYEhuDf2TxKgQ7PfAccEff51QyM"\n }\n ]\n },\n "signature": "4vKvfytWkgv5YjTQQiVwADpBMpvAF6W79KBHzAs1iybLswUZ2VhWPh6dMTnifVeiBYXVJuvgcMkKkRH8VjL2izkRVTAxs",\n "content_creator_pub_key": "P1snABBASHQQuCDERNdUBzg2kJ37LLFK8L7sgBoBd32mRU38ev9",\n "content_creator_address": "AU1WqP6GTsR8w4eyRPHQkrQhujmRb3hmLaQt3HZfeTVHWVZade48",\n "id": "B122ByHzPVJ3QFwmuYcZ4vZYzq6rfkqx7BJSJdFNHWp9j2o5Fpxv"\n },\n "operations": [\n "O116jye7zBAttWHfCufcMVQEQaa9JMTqv6To5mE2CzmzBs7cZ7W",\n ...\n "O12we35pSQhP8i31B2i9wXRNgfkFMCN7CUGgF2HCoRj1XB3LXUNw"\n ]\n }\n }\n }\n],\n"id": 1\n}\n')))),(0,r.kt)("h3",{id:"get_operations"},"get_operations"),(0,r.kt)("p",null,"Get information about\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.massa.net/docs/learn/architecture/basic-concepts#operation"},"operation"),"\n(s) information associated to a given operation(s) ID(s)."),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_operations",\n "params": [["O1LMr9xyL9fVSbUvZao4jy6t2Pj5UPtLG8x1fxvS6SD7dPb5S52"]]\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_operations",\n "params": [["O1LMr9xyL9fVSbUvZao4jy6t2Pj5UPtLG8x1fxvS6SD7dPb5S52"]]\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n"result": [\n {\n "id": "O1LMr9xyL9fVSbUvZao4jy6t2Pj5UPtLG8x1fxvS6SD7dPb5S52",\n "in_pool": true,\n "in_blocks": [\n "B1CM6E6CcSvFtXD1VHhVezt9CvpUGsB7TcSh3Z9k1HW6J3zLDyP"\n ],\n "is_operation_final": false,\n "thread": 8,\n "operation": {\n "content": {\n "fee": "0",\n "expire_period": 25824,\n "op": {\n "Transaction": {\n "recipient_address": "AU12WQRoxQJKMjNG8hVjkyh4YgBwaYeUH4BsqJEEdTUJda37GhSx9",\n "amount": "0.000600754"\n }\n }\n },\n "signature": "D3JUUhPiQTDvdYKa4Gv38xUNSpfHbYUU9qsw3rLypwZdjbniVdmHn15VnaF1NDrmSqUPf6UFs5xpDmid3xzmMqoXBV83",\n "content_creator_pub_key": "P1YSCrgzD8QXQCmMUEqrGvroBsu9UMCbWJUgCUnW3txDyFajBW5",\n "content_creator_address": "AU1Y6Zhw2GWt2ETWxyym3GnJSv4ZW3rXRQVxcLUDprB3ybr5LKAq",\n "id": "O1LMr9xyL9fVSbUvZao4jy6t2Pj5UPtLG8x1fxvS6SD7dPb5S52"\n },\n "op_exec_status": true\n }\n],\n"id": 1\n}\n')))),(0,r.kt)("h3",{id:"get_endorsements"},"get_endorsements"),(0,r.kt)("p",null,"Get information about\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.massa.net/docs/learn/architecture/consensus-quality#endorsement"},"endorsement"),"\n(s) (content, finality ",".","..)"),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_endorsements",\n "params": [["E12kB72Jz4iMWkVkckS2e6cUBm4e5XEW77biDjSysAWmQkNrvuJr"]]\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_endorsements",\n "params": [["E12kB72Jz4iMWkVkckS2e6cUBm4e5XEW77biDjSysAWmQkNrvuJr"]]\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n"result": [\n {\n "id": "E12kB72Jz4iMWkVkckS2e6cUBm4e5XEW77biDjSysAWmQkNrvuJr",\n "in_pool": false,\n "in_blocks": [\n "B1CM6E6CcSvFtXD1VHhVezt9CvpUGsB7TcSh3Z9k1HW6J3zLDyP"\n ],\n "is_final": true,\n "endorsement": {\n "content": {\n "slot": {\n "period": 25817,\n "thread": 8\n },\n "index": 6,\n "endorsed_block": "B17nShoffS6PVyB1qZQSgLmgWvczzPDinhkcHWUxWP2q9fg646A"\n },\n "signature": "H6bsbwfUwkyMYdKU7vdWdft61bCacYPv77Gsxmp9rng7wTZSRYjuqXi6uy5eFwh8qM9iggRAabumbv4ZT9ChC42ZVYeuK",\n "content_creator_pub_key": "P12KNCqp2tSrQtFBF8wUxDJ1aSdrvyqg6UPShhXUVSWA9udJFcfV",\n "content_creator_address": "AU1AZf2B9Cn3V7zSvoCm7Egdi5ZUx5m35sADYHcPujHsb2fLPQXs",\n "id": "E12kB72Jz4iMWkVkckS2e6cUBm4e5XEW77biDjSysAWmQkNrvuJr"\n }\n }\n],\n"id": 1\n}\n')))),(0,r.kt)("h2",{id:"websockets-support"},"WebSockets support"),(0,r.kt)("p",null,"In this section we'll learn how to enable and subscribe to WebSockets\nvia Postman client."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Experimental support for WebSocket is a feature that is subject to\nchange in a future releases.")),(0,r.kt)("p",null,"Available subscriptions:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"subscribe_new_blocks/unsubscribe_new_blocks"),":\nsubscribe/unsubscribe to/from new produced blocks."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"subscribe_new_blocks_headers/unsubscribe_new_blocks_headers"),":\nsubscribe/unsubscribe to/from new produced blocks headers."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"subscribe_new_filled_blocks/unsubscribe_new_filled_blocks"),":\nsubscribe/unsubscribe to/from new produced filled blocks with\noperations content."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"subscribe_new_operations/unsubscribe_new_operations"),":\nsubscribe/unsubscribe to/from new produced operations.")),(0,r.kt)("p",null,"To enable WebSocket support in Massa node, edit file\n",(0,r.kt)("inlineCode",{parentName:"p"},"massa-node/config/config.toml")," (create it if absent) with the following\ncontents:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-toml"},"[api]\n # whether to broadcast for blocks, endorsement and operations\n enable_broadcast = true\n # whether to enable WS.\n enable_ws = true\n")),(0,r.kt)("p",null,"Postman brings support for WebSocket APIs, more information about it\n",(0,r.kt)("a",{parentName:"p",href:"https://blog.postman.com/postman-supports-websocket-apis/"},"here"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"image",src:t(2970).Z,width:"3012",height:"1652"})),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"run the massa node"),(0,r.kt)("li",{parentName:"ul"},"connect to ",(0,r.kt)("inlineCode",{parentName:"li"},"ws://localhost:33036")),(0,r.kt)("li",{parentName:"ul"},"send the request message:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "subscribe_new_filled_blocks",\n "params": []\n}\n')),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"If the request succeed, the response will contains a subscription id:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "result": 3508678639232691,\n "id": 1\n}\n')),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Result:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "method": "new_filled_blocks",\n "params": {\n "subscription": 3508678639232691,\n "result": "FILLED_BLOCK_CONTENT_0"\n }\n}\n')),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"A message is received everytime a filled block is produced:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "method": "new_filled_blocks",\n "params": {\n "subscription": 3508678639232691,\n "result": "FILLED_BLOCK_CONTENT_N"\n }\n}\n')),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"unsubscribe and stop receiving new filled blocks:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "unsubscribe_new_filled_blocks",\n "params": [\n 3508678639232691\n ]\n}\n')),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Result:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "result": true,\n "id": 1\n}\n')),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Multiple subscriptions are supported")),(0,r.kt)("h2",{id:"error-codes"},"Error codes"),(0,r.kt)("p",null,"When a call to Massa API fails, it ",(0,r.kt)("strong",{parentName:"p"},"MUST")," return a valid JSON-RPC\n",(0,r.kt)("a",{parentName:"p",href:"https://www.jsonrpc.org/specification#error_object"},"error object"),"."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"th"},"Code")),(0,r.kt)("th",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"th"},"Message")),(0,r.kt)("th",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"th"},"Meaning")))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32600"),(0,r.kt)("td",{parentName:"tr",align:null},"Invalid request"),(0,r.kt)("td",{parentName:"tr",align:null},"The JSON sent is not a valid Request object")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32601"),(0,r.kt)("td",{parentName:"tr",align:null},"Method not found"),(0,r.kt)("td",{parentName:"tr",align:null},"The method does not exist / is not available")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32602"),(0,r.kt)("td",{parentName:"tr",align:null},"Invalid params"),(0,r.kt)("td",{parentName:"tr",align:null},"Invalid method parameter(s)")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32603"),(0,r.kt)("td",{parentName:"tr",align:null},"Internal error"),(0,r.kt)("td",{parentName:"tr",align:null},"Internal JSON-RPC error")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32700"),(0,r.kt)("td",{parentName:"tr",align:null},"Parse error"),(0,r.kt)("td",{parentName:"tr",align:null},"Invalid JSON, parsing issue")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32000"),(0,r.kt)("td",{parentName:"tr",align:null},"Bad request"),(0,r.kt)("td",{parentName:"tr",align:null},"Indicates that the server cannot or will not process the request due to something that is perceived to be a client error")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32001"),(0,r.kt)("td",{parentName:"tr",align:null},"Internal server error"),(0,r.kt)("td",{parentName:"tr",align:null},"The server encountered an unexpected issue")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32003"),(0,r.kt)("td",{parentName:"tr",align:null},"Service Unavailable"),(0,r.kt)("td",{parentName:"tr",align:null},"Indicates that the server is not ready to handle the request")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32004"),(0,r.kt)("td",{parentName:"tr",align:null},"Not found"),(0,r.kt)("td",{parentName:"tr",align:null},"Indicates that the server cannot find the requested resource")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32005"),(0,r.kt)("td",{parentName:"tr",align:null},"Method not allowed"),(0,r.kt)("td",{parentName:"tr",align:null},"Indicates that the server knows the request method, but the target resource doesn't support this method")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32006"),(0,r.kt)("td",{parentName:"tr",align:null},"Send channel error"),(0,r.kt)("td",{parentName:"tr",align:null},"Send channel error")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32007"),(0,r.kt)("td",{parentName:"tr",align:null},"Receive channel error"),(0,r.kt)("td",{parentName:"tr",align:null},"Receive channel error")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32008"),(0,r.kt)("td",{parentName:"tr",align:null},"Massa hash error"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"massa_hash")," error")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32009"),(0,r.kt)("td",{parentName:"tr",align:null},"Consensus error"),(0,r.kt)("td",{parentName:"tr",align:null},"Error from Consensus module")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32010"),(0,r.kt)("td",{parentName:"tr",align:null},"Execution error"),(0,r.kt)("td",{parentName:"tr",align:null},"Error from Execution module")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32012"),(0,r.kt)("td",{parentName:"tr",align:null},"Protocol error"),(0,r.kt)("td",{parentName:"tr",align:null},"Error from Protocol module")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32013"),(0,r.kt)("td",{parentName:"tr",align:null},"Models error"),(0,r.kt)("td",{parentName:"tr",align:null},"Error in Models")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32014"),(0,r.kt)("td",{parentName:"tr",align:null},"Time error"),(0,r.kt)("td",{parentName:"tr",align:null},"Error from Time module")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32015"),(0,r.kt)("td",{parentName:"tr",align:null},"Wallet error"),(0,r.kt)("td",{parentName:"tr",align:null},"Error from Wallet module")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32016"),(0,r.kt)("td",{parentName:"tr",align:null},"Inconsistency error"),(0,r.kt)("td",{parentName:"tr",align:null},"Inconsistency in the result of request")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32017"),(0,r.kt)("td",{parentName:"tr",align:null},"Missing command sender"),(0,r.kt)("td",{parentName:"tr",align:null},"Missing command sender")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32018"),(0,r.kt)("td",{parentName:"tr",align:null},"Missing config"),(0,r.kt)("td",{parentName:"tr",align:null},"Missing configuration")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32019"),(0,r.kt)("td",{parentName:"tr",align:null},"Wrong API"),(0,r.kt)("td",{parentName:"tr",align:null},"The wrong API (either Public or Private) was called")))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example error: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n"jsonrpc": "2.0",\n"error": {\n "code": -32400,\n "message": "Bad request: too many arguments, maximum authorized 2 but found 3"\n},\n"id": 1\n}\n')))))}k.isMDXComponent=!0},2970:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/postman_websocket-d590daa827a5e9776c8b59899397a030.png"}}]); \ No newline at end of file diff --git a/assets/js/28d23288.bfb73dae.js b/assets/js/28d23288.bfb73dae.js new file mode 100644 index 000000000..335e8ed54 --- /dev/null +++ b/assets/js/28d23288.bfb73dae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[2247],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>k});var a=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function l(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function s(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var i=a.createContext({}),u=function(e){var n=a.useContext(i),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=u(e.components);return a.createElement(i.Provider,{value:n},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},m=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,l=e.originalType,i=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),c=u(t),m=r,k=c["".concat(i,".").concat(m)]||c[m]||d[m]||l;return t?a.createElement(k,s(s({ref:n},p),{},{components:t})):a.createElement(k,s({ref:n},p))}));function k(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var l=t.length,s=new Array(l);s[0]=m;var o={};for(var i in n)hasOwnProperty.call(n,i)&&(o[i]=n[i]);o.originalType=e,o[c]="string"==typeof e?e:r,s[1]=o;for(var u=2;u{t.d(n,{Z:()=>s});var a=t(7294),r=t(6010);const l={tabItem:"tabItem_Ymn6"};function s(e){let{children:n,hidden:t,className:s}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(l.tabItem,s),hidden:t},n)}},4866:(e,n,t)=>{t.d(n,{Z:()=>_});var a=t(7462),r=t(7294),l=t(6010),s=t(2466),o=t(6550),i=t(1980),u=t(7392),p=t(12);function c(e){return function(e){return r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:n,label:t,attributes:a,default:r}}=e;return{value:n,label:t,attributes:a,default:r}}))}function d(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??c(t);return function(e){const n=(0,u.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,t])}function m(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function k(e){let{queryString:n=!1,groupId:t}=e;const a=(0,o.k6)(),l=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,i._X)(l),(0,r.useCallback)((e=>{if(!l)return;const n=new URLSearchParams(a.location.search);n.set(l,e),a.replace({...a.location,search:n.toString()})}),[l,a])]}function b(e){const{defaultValue:n,queryString:t=!1,groupId:a}=e,l=d(e),[s,o]=(0,r.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({value:n,tabValues:t}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const a=t.find((e=>e.default))??t[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:n,tabValues:l}))),[i,u]=k({queryString:t,groupId:a}),[c,b]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[a,l]=(0,p.Nk)(t);return[a,(0,r.useCallback)((e=>{t&&l.set(e)}),[t,l])]}({groupId:a}),h=(()=>{const e=i??c;return m({value:e,tabValues:l})?e:null})();(0,r.useLayoutEffect)((()=>{h&&o(h)}),[h]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);o(e),u(e),b(e)}),[u,b,l]),tabValues:l}}var h=t(2389);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function f(e){let{className:n,block:t,selectedValue:o,selectValue:i,tabValues:u}=e;const p=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.o5)(),d=e=>{const n=e.currentTarget,t=p.indexOf(n),a=u[t].value;a!==o&&(c(n),i(a))},m=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const t=p.indexOf(e.currentTarget)+1;n=p[t]??p[0];break}case"ArrowLeft":{const t=p.indexOf(e.currentTarget)-1;n=p[t]??p[p.length-1];break}}n?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":t},n)},u.map((e=>{let{value:n,label:t,attributes:s}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:o===n?0:-1,"aria-selected":o===n,key:n,ref:e=>p.push(e),onKeyDown:m,onClick:d},s,{className:(0,l.Z)("tabs__item",g.tabItem,s?.className,{"tabs__item--active":o===n})}),t??n)})))}function N(e){let{lazy:n,children:t,selectedValue:a}=e;const l=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=l.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},l.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==a}))))}function v(e){const n=b(e);return r.createElement("div",{className:(0,l.Z)("tabs-container",g.tabList)},r.createElement(f,(0,a.Z)({},e,n)),r.createElement(N,(0,a.Z)({},e,n)))}function _(e){const n=(0,h.Z)();return r.createElement(v,(0,a.Z)({key:String(n)},e))}},7250:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>i,default:()=>k,frontMatter:()=>o,metadata:()=>u,toc:()=>c});var a=t(7462),r=(t(7294),t(3905)),l=t(4866),s=t(5162);const o={id:"jsonrpc",sidebar_label:"JsonRPC"},i="Massa JSON-RPC API",u={unversionedId:"build/api/jsonrpc",id:"build/api/jsonrpc",title:"Massa JSON-RPC API",description:"The JsonRPC API allows you to communicate with the Massa blockchain.",source:"@site/docs/build/api/jsonrpc.mdx",sourceDirName:"build/api",slug:"/build/api/jsonrpc",permalink:"/docs/build/api/jsonrpc",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/api/jsonrpc.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"jsonrpc",sidebar_label:"JsonRPC"},sidebar:"buildSidebar",previous:{title:"Providers",permalink:"/docs/build/api/providers"},next:{title:"gRPC",permalink:"/docs/build/api/grpc"}},p={},c=[{value:"Integrations",id:"integrations",level:2},{value:"Explore the Blockchain",id:"explore-the-blockchain",level:2},{value:"get_status",id:"get_status",level:3},{value:"get_cliques",id:"get_cliques",level:3},{value:"get_stakers",id:"get_stakers",level:3},{value:"get_addresses",id:"get_addresses",level:3},{value:"get_graph_interval",id:"get_graph_interval",level:3},{value:"get_blocks",id:"get_blocks",level:3},{value:"get_operations",id:"get_operations",level:3},{value:"get_endorsements",id:"get_endorsements",level:3},{value:"WebSockets support",id:"websockets-support",level:2},{value:"Error codes",id:"error-codes",level:2}],d={toc:c},m="wrapper";function k(e){let{components:n,...o}=e;return(0,r.kt)(m,(0,a.Z)({},d,o,{components:n,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"massa-json-rpc-api"},"Massa JSON-RPC API"),(0,r.kt)("p",null,"The JsonRPC API allows you to communicate with the Massa blockchain."),(0,r.kt)("p",null,"The Massa JSON-RPC API is splitted in two parts:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Private API"),": used for node management. Default port: 33034 e.g.\n",(0,r.kt)("a",{parentName:"li",href:"http://localhost:33034"},"http://localhost:33034")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Public API"),": used for blockchain interactions. Default port:\n33035 e.g. ",(0,r.kt)("a",{parentName:"li",href:"http://localhost:33035"},"http://localhost:33035"))),(0,r.kt)("p",null,"The complete Massa ",(0,r.kt)("a",{parentName:"p",href:"https://spec.open-rpc.org/"},"OpenRPC")," specification is available\n",(0,r.kt)("a",{parentName:"p",href:"https://raw.githubusercontent.com/massalabs/massa/main/massa-node/base_config/openrpc.json"},"here"),"."),(0,r.kt)("p",null,"The ",(0,r.kt)("a",{parentName:"p",href:"https://playground.open-rpc.org/?schemaUrl=https://test.massa.net/api/v2&uiSchema%5BappBar%5D%5Bui:input%5D=false&uiSchema%5BappBar%5D%5Bui:inputPlaceholder%5D=Enter+Massa+JSON-RPC+server+URL&uiSchema%5BappBar%5D%5Bui:logoUrl%5D=https://massa.net/favicons/favicon.ico&uiSchema%5BappBar%5D%5Bui:splitView%5D=false&uiSchema%5BappBar%5D%5Bui:darkMode%5D=false&uiSchema%5BappBar%5D%5Bui:title%5D=Massa&uiSchema%5BappBar%5D%5Bui:examplesDropdown%5D=false&uiSchema%5Bmethods%5D%5Bui:defaultExpanded%5D=false&uiSchema%5Bmethods%5D%5Bui:methodPlugins%5D=true&uiSchema%5Bparams%5D%5Bui:defaultExpanded%5D=false"},"Interactive API Specification"),"\ndocuments every available method and allows you to play with the API."),(0,r.kt)("admonition",{type:"info"},(0,r.kt)("p",{parentName:"admonition"},"Massa has a new experimental API with both Http and WebSocket support:\nDefault port: 33036"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Http"),": used for node management and blockchain interactions. e.g.\n",(0,r.kt)("a",{parentName:"li",href:"http://localhost:33036"},"http://localhost:33036")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"WebSocket"),": used for streaming blockchain events. e.g.\n",(0,r.kt)("a",{parentName:"li",href:"ws://localhost:33036"},"ws://localhost:33036")))),(0,r.kt)("h2",{id:"integrations"},"Integrations"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"JavaScript"),": The ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/massalabs/massa-web3"},"massa-web3")," TypeScript library\ncan be used to call the JSON-RPC API... and much more."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Postman"),": You can find our Massa Postman collections on our official ",(0,r.kt)("a",{parentName:"li",href:"https://www.postman.com/massalabs"},"workspace"),".")),(0,r.kt)("h2",{id:"explore-the-blockchain"},"Explore the Blockchain"),(0,r.kt)("p",null,"In this section we'll learn how to interact with Massa blockchain using the public API via\ncURL commands which will create JSON-RPC request calls."),(0,r.kt)("h3",{id:"get_status"},"get_status"),(0,r.kt)("p",null,"Summary of the current state: time, last final blocks (hash, thread,\nslot, timestamp), clique count, connected nodes count."),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_status",\n "params": []\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_status",\n "params": []\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "result": {\n "node_id": "N1VRyXjUaHeJd4Rmr3waVmpZDFzzH5ARRi3f5ye5BYgxBmxHC7X",\n "node_ip": "141.94.218.103",\n "version": "SECU.27.0",\n "current_time": 1699881695772,\n "current_cycle": 208,\n "current_cycle_time": 1699879784000,\n "next_cycle_time": 1699881832000,\n "connected_nodes": {\n "N13Ykon8Zo73PTKMruLViMMtE2rEG646JQ4sCcee2DnopmVM3P5": [\n "::ffff:51.75.60.228",\n false\n ],\n "N1XxexKa3XNzvmakNmPawqFrE9Z2NFhfq1AhvV1Qx4zXq5p1Bp9": [\n "::ffff:158.69.23.120",\n false\n ],\n "N1qxuqNnx9kyAMYxUfsYiv2gQd5viiBX126SzzexEdbbWd2vQKu": [\n "::ffff:198.27.74.5",\n false\n ],\n "N12UbyLJDS7zimGWf3LTHe8hYY67RdLke1iDRZqJbQQLHQSKPW8j": [\n "::ffff:149.202.86.103",\n false\n ],\n "N12rPDBmpnpnbECeAKDjbmeR19dYjAUwyLzsa8wmYJnkXLCNF28E": [\n "::ffff:158.69.120.215",\n false\n ],\n "N12vxrYTQzS5TRzxLfFNYxn6PyEsphKWkdqx2mVfEuvJ9sPF43uq": [\n "::ffff:149.202.89.125",\n false\n ]\n },\n "last_slot": {\n "period": 26743,\n "thread": 15\n },\n "next_slot": {\n "period": 26743,\n "thread": 16\n },\n "consensus_stats": {\n "start_timespan": 1699881635772,\n "end_timespan": 1699881695772,\n "final_block_count": 121,\n "stale_block_count": 0,\n "clique_count": 1\n },\n "pool_stats": [\n 0,\n 96\n ],\n "network_stats": {\n "in_connection_count": 6,\n "out_connection_count": 0,\n "known_peer_count": 7,\n "banned_peer_count": 0,\n "active_node_count": 6\n },\n "execution_stats": {\n "time_window_start": 1699881635772,\n "time_window_end": 1699881695772,\n "final_block_count": 121,\n "final_executed_operations_count": 0,\n "active_cursor": {\n "period": 26743,\n "thread": 11\n },\n "final_cursor": {\n "period": 26741,\n "thread": 14\n }\n },\n "config": {\n "genesis_timestamp": 1699453800000,\n "end_timestamp": null,\n "thread_count": 32,\n "t0": 16000,\n "delta_f0": 1088,\n "operation_validity_periods": 10,\n "periods_per_cycle": 128,\n "block_reward": "1.02",\n "roll_price": "100",\n "max_block_size": 300000\n }\n },\n "id": 1\n}\n')))),(0,r.kt)("h3",{id:"get_cliques"},"get_cliques"),(0,r.kt)("p",null,"Get information about the block\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.massa.net/docs/learn/architecture/node-architecture#block-cliques"},"cliques"),"\nof the graph."),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_cliques",\n "params": []\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_cliques",\n "params": []\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n"result": [\n {\n "block_ids": [\n "B12RHJKyPx8DdGHMevdP8Uyxidcg3nThb9XEnHXEJR7cbBi6JrR9",\n ...\n "B12c7xPkmdy3qbAF1rWn7XeTBdum6VHbYJiW5MUuyBGnshrf5NW8"\n ],\n "fitness": 1117,\n "is_blockclique": true\n }\n],\n"id": 1\n}\n')))),(0,r.kt)("h3",{id:"get_stakers"},"get_stakers"),(0,r.kt)("p",null,"Get information about active\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.massa.net/docs/node/stake"},"stakers")," and\ntheir roll counts for the current cycle."),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_stakers",\n "params": [ {"offset": 0, "limit": 2 }]\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_stakers",\n "params": [ {"offset": 0, "limit": 2 }]\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n"jsonrpc": "2.0",\n"result": [\n [\n "AU12gAkmGeozFceJD4tQmbVvihYdX2KyWZcYLL8xdYZeP4EuWYdex",\n 145\n ],\n [\n "AU18A67vpbjHPq7KgFnMbezoJuGcjVLZsF4ybx4rEbnA3wZ1Gy7c",\n 124\n ]\n],\n}\n')))),(0,r.kt)("h3",{id:"get_addresses"},"get_addresses"),(0,r.kt)("p",null,"Get information about\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.massa.net/docs/learn/architecture/basic-concepts#address"},"address"),"\n(es) (balances, block creation, ",".","..)."),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_addresses",\n "params": [["AU12gAkmGeozFceJD4tQmbVvihYdX2KyWZcYLL8xdYZeP4EuWYdex"]]\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_addresses",\n "params": [["AU12gAkmGeozFceJD4tQmbVvihYdX2KyWZcYLL8xdYZeP4EuWYdex"]]\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n"result": [\n {\n "address": "AU12gAkmGeozFceJD4tQmbVvihYdX2KyWZcYLL8xdYZeP4EuWYdex",\n "thread": 27,\n "final_balance": "153.519945908",\n "final_roll_count": 145,\n "final_datastore_keys": [],\n "candidate_balance": "153.755240036",\n "candidate_roll_count": 145,\n "candidate_datastore_keys": [],\n "deferred_credits": [],\n "next_block_draws": [\n {\n "period": 25784,\n "thread": 5\n },\n ...\n {\n "slot": {\n "period": 25791,\n "thread": 29\n },\n "index": 1\n }\n ],\n "created_blocks": [\n "B12Y4eqmeJ5uWakcgZXRqDxRzFstKt8KJd2MgMSysqcMX4eWoaw4",\n "B12CANhVvuBpXtjyVS5kkZBGmw5wanvEuuF34ct3GABHLLAMroxT",\n "B122nYsgcJ72Cor9RcZB6ZGduc4pFm97srfGEPiijeZq9k1VatBS",\n "B12TC646QjDoQWAPuAYhsy9i8f3qdzajFas25eJsRXaj1mbBhGRk",\n "B12aFhukUBCz8TXJK5SakyT6MW18GTFNiRoeUKqzXT6e2ePbutor"\n ],\n "created_operations": [],\n "created_endorsements": [\n "E12uK8JkAkMpC5gDXaa26Vxvu8nRL5ZvD61WFjToeyTDVexnzYcH",\n ...\n "E12XbfbSzPvVRyW1mGhxBpkrDBzVdGdZvRkaYpDbrUP96fCZteSy"\n ],\n "cycle_infos": [\n {\n "cycle": 197,\n "is_final": true,\n "ok_count": 48,\n "nok_count": 0,\n "active_rolls": null\n },\n ...\n {\n "cycle": 201,\n "is_final": false,\n "ok_count": 11,\n "nok_count": 0,\n "active_rolls": 145\n }\n ]\n }\n],\n"id": 1\n}\n')))),(0,r.kt)("h3",{id:"get_graph_interval"},"get_graph_interval"),(0,r.kt)("p",null,"Get information about block graph\nwithin the specified time interval."),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_graph_interval",\n "params": [{"start": 1678095527706, "end": 1678095529706}]\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_graph_interval",\n "params": [{"start": 1678095527706, "end": 1678095529706}]\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n"result": [\n {\n "id": "B1pd4hCpPnHM8QMvKp9uGM5sdUZoq6s9wERwk7z9ANoo8FSTJ7j",\n "is_final": false,\n "is_stale": false,\n "is_in_blockclique": true,\n "slot": {\n "period": 25795,\n "thread": 17\n },\n "creator": "AU12tr8pSnamJRQEdm4K9DaogpdANXF636XNV13iNHAL6bLpKxooR",\n "parents": [\n "B12echxHFVHsCsWaRxL5pxPmYtefjhuJDNtd7TX6iseF6jxdyZnS",\n ...\n "B12WQuyYopKPLkK9HF2eRaJDRbnE2cAhqT19XpGT2gMh9o4E2BrL"\n ]\n },\n {\n "id": "B12G3GVLNct669ZiAQQDsXW9Mbo5PHtmwrEKNAvnBVa11kqqps5n",\n "is_final": false,\n "is_stale": false,\n "is_in_blockclique": true,\n "slot": {\n "period": 25795,\n "thread": 16\n },\n "creator": "AU1LJYrJQiQZYqiktgrbb5MWgSnd1FuUQqhQsw48PPdrAB3uqLCS",\n "parents": [\n "B12echxHFVHsCsWaRxL5pxPmYtefjhuJDNtd7TX6iseF6jxdyZnS",\n ...\n "B12WQuyYopKPLkK9HF2eRaJDRbnE2cAhqT19XpGT2gMh9o4E2BrL"\n ]\n },\n {\n "id": "B12RYZz9S8PuqWvQUFStxmTDb4j3UqfVEkNqeBwYDvwCrnzBMJ8J",\n "is_final": false,\n "is_stale": false,\n "is_in_blockclique": true,\n "slot": {\n "period": 25795,\n "thread": 18\n },\n "creator": "AU1vWZXTD4YdfdbqWS3RRgnH5DBdJSfgwVi9vJztH2V3iNMakzKo",\n "parents": [\n "B12echxHFVHsCsWaRxL5pxPmYtefjhuJDNtd7TX6iseF6jxdyZnS",\n ...\n "B12WQuyYopKPLkK9HF2eRaJDRbnE2cAhqT19XpGT2gMh9o4E2BrL"\n ]\n }\n],\n"id": 1\n}\n')))),(0,r.kt)("h3",{id:"get_blocks"},"get_blocks"),(0,r.kt)("p",null,"Get information about ",(0,r.kt)("a",{parentName:"p",href:"https://docs.massa.net/docs/learn/architecture/basic-concepts#block"},"block(s)"),"\nassociated to a given hash(s)."),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_blocks",\n "params": [["B122ByHzPVJ3QFwmuYcZ4vZYzq6rfkqx7BJSJdFNHWp9j2o5Fpxv"]]\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_blocks",\n "params": [["B122ByHzPVJ3QFwmuYcZ4vZYzq6rfkqx7BJSJdFNHWp9j2o5Fpxv"]]\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n"result": [\n {\n "id": "B122ByHzPVJ3QFwmuYcZ4vZYzq6rfkqx7BJSJdFNHWp9j2o5Fpxv",\n "content": {\n "is_final": true,\n "is_in_blockclique": false,\n "is_candidate": false,\n "is_discarded": false,\n "block": {\n "header": {\n "content": {\n "slot": {\n "period": 25787,\n "thread": 4\n },\n "parents": [\n "B12L3Cvj8EZiX6sCryti4fqZ3nZ4tbDiYjtyAxVoYfJUxfPuN2Lm",\n ...\n "B1xMgVk5hcp8qdFzvCeG3SqS3AA4i52fAXw7kZn4DzJWnXGgZDW"\n ],\n "operation_merkle_root": "8uJok77DvcHgdzqzMQ62yu6nV9tKqTU6JhsCtvWxBK6VsabSZ",\n "endorsements": [\n {\n "content": {\n "slot": {\n "period": 25787,\n "thread": 4\n },\n "index": 0,\n "endorsed_block": "B1PF5E4D3LKa6soJ8BXv6nveHFHRPzBYtqysVWhLZT5fmnedc6T"\n },\n "signature": "V21cLHbr5mUzpRrRHc66EkvsDh5KZHvWKfFhFo2B2ni9qVK9p8nhPuE14btaWXAN7ru4d7q7jm9TcW55McXd2smhd6NbP",\n "content_creator_pub_key": "P1bi78ormwmdSYuvmk77ZbQsyz4VDqEZZGKnXVWyksJYitx6nwJ",\n "content_creator_address": "AU12ta1W4CcLrQmBAYEc7BPCopj8zqyJzBmFncYcXQQw2N2M5SC6U",\n "id": "E1KLYEDm4qBUxi1SDHo3tf3dCGJ5kDYL3w8N766KgnYZV6A7omy"\n },\n ...\n {\n "content": {\n "slot": {\n "period": 25787,\n "thread": 4\n },\n "index": 15,\n "endorsed_block": "B1PF5E4D3LKa6soJ8BXv6nveHFHRPzBYtqysVWhLZT5fmnedc6T"\n },\n "signature": "E3HGbZvJEPVZcRUYDUpnk4R8t9p941MKZTK3awTXTMpG1pufThBu9CpNd7YDW1mkEc4ZJB31Hcvp8cKVPe57MBUJutu1c",\n "content_creator_pub_key": "P123qyM3ZzUw5Mi7uxj8mKYNHo7H7ybTQWZy53cR7BHhXbTxrT8z",\n "content_creator_address": "AU1Xr8m6utu6DBXyRCFGrD2jPCa62tnwNwkkJSCnh4iWQG3M63za",\n "id": "E12rQSKKLw1wXBXajvjGS9PB8NYEhuDf2TxKgQ7PfAccEff51QyM"\n }\n ]\n },\n "signature": "4vKvfytWkgv5YjTQQiVwADpBMpvAF6W79KBHzAs1iybLswUZ2VhWPh6dMTnifVeiBYXVJuvgcMkKkRH8VjL2izkRVTAxs",\n "content_creator_pub_key": "P1snABBASHQQuCDERNdUBzg2kJ37LLFK8L7sgBoBd32mRU38ev9",\n "content_creator_address": "AU1WqP6GTsR8w4eyRPHQkrQhujmRb3hmLaQt3HZfeTVHWVZade48",\n "id": "B122ByHzPVJ3QFwmuYcZ4vZYzq6rfkqx7BJSJdFNHWp9j2o5Fpxv"\n },\n "operations": [\n "O116jye7zBAttWHfCufcMVQEQaa9JMTqv6To5mE2CzmzBs7cZ7W",\n ...\n "O12we35pSQhP8i31B2i9wXRNgfkFMCN7CUGgF2HCoRj1XB3LXUNw"\n ]\n }\n }\n }\n],\n"id": 1\n}\n')))),(0,r.kt)("h3",{id:"get_operations"},"get_operations"),(0,r.kt)("p",null,"Get information about\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.massa.net/docs/learn/architecture/basic-concepts#operation"},"operation"),"\n(s) information associated to a given operation(s) ID(s)."),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_operations",\n "params": [["O1LMr9xyL9fVSbUvZao4jy6t2Pj5UPtLG8x1fxvS6SD7dPb5S52"]]\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_operations",\n "params": [["O1LMr9xyL9fVSbUvZao4jy6t2Pj5UPtLG8x1fxvS6SD7dPb5S52"]]\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n"result": [\n {\n "id": "O1LMr9xyL9fVSbUvZao4jy6t2Pj5UPtLG8x1fxvS6SD7dPb5S52",\n "in_pool": true,\n "in_blocks": [\n "B1CM6E6CcSvFtXD1VHhVezt9CvpUGsB7TcSh3Z9k1HW6J3zLDyP"\n ],\n "is_operation_final": false,\n "thread": 8,\n "operation": {\n "content": {\n "fee": "0",\n "expire_period": 25824,\n "op": {\n "Transaction": {\n "recipient_address": "AU12WQRoxQJKMjNG8hVjkyh4YgBwaYeUH4BsqJEEdTUJda37GhSx9",\n "amount": "0.000600754"\n }\n }\n },\n "signature": "D3JUUhPiQTDvdYKa4Gv38xUNSpfHbYUU9qsw3rLypwZdjbniVdmHn15VnaF1NDrmSqUPf6UFs5xpDmid3xzmMqoXBV83",\n "content_creator_pub_key": "P1YSCrgzD8QXQCmMUEqrGvroBsu9UMCbWJUgCUnW3txDyFajBW5",\n "content_creator_address": "AU1Y6Zhw2GWt2ETWxyym3GnJSv4ZW3rXRQVxcLUDprB3ybr5LKAq",\n "id": "O1LMr9xyL9fVSbUvZao4jy6t2Pj5UPtLG8x1fxvS6SD7dPb5S52"\n },\n "op_exec_status": true\n }\n],\n"id": 1\n}\n')))),(0,r.kt)("h3",{id:"get_endorsements"},"get_endorsements"),(0,r.kt)("p",null,"Get information about\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.massa.net/docs/learn/architecture/consensus-quality#endorsement"},"endorsement"),"\n(s) (content, finality ",".","..)"),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(s.Z,{value:"json (Mainnet)",label:"cURL (Mainnet)",default:!0,mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://mainnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_endorsements",\n "params": [["E12kB72Jz4iMWkVkckS2e6cUBm4e5XEW77biDjSysAWmQkNrvuJr"]]\n}\'\n'))),(0,r.kt)(s.Z,{value:"json (Buildnet)",label:"cURL (Buildnet)",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},'curl --location --request POST \'https://buildnet.massa.net/api/v2\' \\\n--header \'Content-Type: application/json\' \\\n--data-raw \'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "get_endorsements",\n "params": [["E12kB72Jz4iMWkVkckS2e6cUBm4e5XEW77biDjSysAWmQkNrvuJr"]]\n}\'\n')))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example response: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n"result": [\n {\n "id": "E12kB72Jz4iMWkVkckS2e6cUBm4e5XEW77biDjSysAWmQkNrvuJr",\n "in_pool": false,\n "in_blocks": [\n "B1CM6E6CcSvFtXD1VHhVezt9CvpUGsB7TcSh3Z9k1HW6J3zLDyP"\n ],\n "is_final": true,\n "endorsement": {\n "content": {\n "slot": {\n "period": 25817,\n "thread": 8\n },\n "index": 6,\n "endorsed_block": "B17nShoffS6PVyB1qZQSgLmgWvczzPDinhkcHWUxWP2q9fg646A"\n },\n "signature": "H6bsbwfUwkyMYdKU7vdWdft61bCacYPv77Gsxmp9rng7wTZSRYjuqXi6uy5eFwh8qM9iggRAabumbv4ZT9ChC42ZVYeuK",\n "content_creator_pub_key": "P12KNCqp2tSrQtFBF8wUxDJ1aSdrvyqg6UPShhXUVSWA9udJFcfV",\n "content_creator_address": "AU1AZf2B9Cn3V7zSvoCm7Egdi5ZUx5m35sADYHcPujHsb2fLPQXs",\n "id": "E12kB72Jz4iMWkVkckS2e6cUBm4e5XEW77biDjSysAWmQkNrvuJr"\n }\n }\n],\n"id": 1\n}\n')))),(0,r.kt)("h2",{id:"websockets-support"},"WebSockets support"),(0,r.kt)("p",null,"In this section we'll learn how to enable and subscribe to WebSockets\nvia Postman client."),(0,r.kt)("admonition",{type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Experimental support for WebSocket is a feature that is subject to\nchange in a future releases.")),(0,r.kt)("p",null,"Available subscriptions:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"subscribe_new_blocks/unsubscribe_new_blocks"),":\nsubscribe/unsubscribe to/from new produced blocks."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"subscribe_new_blocks_headers/unsubscribe_new_blocks_headers"),":\nsubscribe/unsubscribe to/from new produced blocks headers."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"subscribe_new_filled_blocks/unsubscribe_new_filled_blocks"),":\nsubscribe/unsubscribe to/from new produced filled blocks with\noperations content."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"subscribe_new_operations/unsubscribe_new_operations"),":\nsubscribe/unsubscribe to/from new produced operations.")),(0,r.kt)("p",null,"To enable WebSocket support in Massa node, edit file\n",(0,r.kt)("inlineCode",{parentName:"p"},"massa-node/config/config.toml")," (create it if absent) with the following\ncontents:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-toml"},"[api]\n # whether to broadcast for blocks, endorsement and operations\n enable_broadcast = true\n # whether to enable WS.\n enable_ws = true\n")),(0,r.kt)("p",null,"Postman brings support for WebSocket APIs, more information about it\n",(0,r.kt)("a",{parentName:"p",href:"https://blog.postman.com/postman-supports-websocket-apis/"},"here"),"."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"image",src:t(2970).Z,width:"3012",height:"1652"})),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"run the massa node"),(0,r.kt)("li",{parentName:"ul"},"connect to ",(0,r.kt)("inlineCode",{parentName:"li"},"ws://localhost:33036")),(0,r.kt)("li",{parentName:"ul"},"send the request message:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "subscribe_new_filled_blocks",\n "params": []\n}\n')),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"If the request succeed, the response will contains a subscription id:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "result": 3508678639232691,\n "id": 1\n}\n')),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Result:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "method": "new_filled_blocks",\n "params": {\n "subscription": 3508678639232691,\n "result": "FILLED_BLOCK_CONTENT_0"\n }\n}\n')),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"A message is received everytime a filled block is produced:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "method": "new_filled_blocks",\n "params": {\n "subscription": 3508678639232691,\n "result": "FILLED_BLOCK_CONTENT_N"\n }\n}\n')),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"unsubscribe and stop receiving new filled blocks:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "id": 1,\n "method": "unsubscribe_new_filled_blocks",\n "params": [\n 3508678639232691\n ]\n}\n')),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Result:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "jsonrpc": "2.0",\n "result": true,\n "id": 1\n}\n')),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Multiple subscriptions are supported")),(0,r.kt)("h2",{id:"error-codes"},"Error codes"),(0,r.kt)("p",null,"When a call to Massa API fails, it ",(0,r.kt)("strong",{parentName:"p"},"MUST")," return a valid JSON-RPC\n",(0,r.kt)("a",{parentName:"p",href:"https://www.jsonrpc.org/specification#error_object"},"error object"),"."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"th"},"Code")),(0,r.kt)("th",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"th"},"Message")),(0,r.kt)("th",{parentName:"tr",align:null},(0,r.kt)("strong",{parentName:"th"},"Meaning")))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32600"),(0,r.kt)("td",{parentName:"tr",align:null},"Invalid request"),(0,r.kt)("td",{parentName:"tr",align:null},"The JSON sent is not a valid Request object")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32601"),(0,r.kt)("td",{parentName:"tr",align:null},"Method not found"),(0,r.kt)("td",{parentName:"tr",align:null},"The method does not exist / is not available")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32602"),(0,r.kt)("td",{parentName:"tr",align:null},"Invalid params"),(0,r.kt)("td",{parentName:"tr",align:null},"Invalid method parameter(s)")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32603"),(0,r.kt)("td",{parentName:"tr",align:null},"Internal error"),(0,r.kt)("td",{parentName:"tr",align:null},"Internal JSON-RPC error")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32700"),(0,r.kt)("td",{parentName:"tr",align:null},"Parse error"),(0,r.kt)("td",{parentName:"tr",align:null},"Invalid JSON, parsing issue")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32000"),(0,r.kt)("td",{parentName:"tr",align:null},"Bad request"),(0,r.kt)("td",{parentName:"tr",align:null},"Indicates that the server cannot or will not process the request due to something that is perceived to be a client error")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32001"),(0,r.kt)("td",{parentName:"tr",align:null},"Internal server error"),(0,r.kt)("td",{parentName:"tr",align:null},"The server encountered an unexpected issue")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32003"),(0,r.kt)("td",{parentName:"tr",align:null},"Service Unavailable"),(0,r.kt)("td",{parentName:"tr",align:null},"Indicates that the server is not ready to handle the request")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32004"),(0,r.kt)("td",{parentName:"tr",align:null},"Not found"),(0,r.kt)("td",{parentName:"tr",align:null},"Indicates that the server cannot find the requested resource")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32005"),(0,r.kt)("td",{parentName:"tr",align:null},"Method not allowed"),(0,r.kt)("td",{parentName:"tr",align:null},"Indicates that the server knows the request method, but the target resource doesn't support this method")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32006"),(0,r.kt)("td",{parentName:"tr",align:null},"Send channel error"),(0,r.kt)("td",{parentName:"tr",align:null},"Send channel error")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32007"),(0,r.kt)("td",{parentName:"tr",align:null},"Receive channel error"),(0,r.kt)("td",{parentName:"tr",align:null},"Receive channel error")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32008"),(0,r.kt)("td",{parentName:"tr",align:null},"Massa hash error"),(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("inlineCode",{parentName:"td"},"massa_hash")," error")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32009"),(0,r.kt)("td",{parentName:"tr",align:null},"Consensus error"),(0,r.kt)("td",{parentName:"tr",align:null},"Error from Consensus module")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32010"),(0,r.kt)("td",{parentName:"tr",align:null},"Execution error"),(0,r.kt)("td",{parentName:"tr",align:null},"Error from Execution module")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32012"),(0,r.kt)("td",{parentName:"tr",align:null},"Protocol error"),(0,r.kt)("td",{parentName:"tr",align:null},"Error from Protocol module")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32013"),(0,r.kt)("td",{parentName:"tr",align:null},"Models error"),(0,r.kt)("td",{parentName:"tr",align:null},"Error in Models")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32014"),(0,r.kt)("td",{parentName:"tr",align:null},"Time error"),(0,r.kt)("td",{parentName:"tr",align:null},"Error from Time module")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32015"),(0,r.kt)("td",{parentName:"tr",align:null},"Wallet error"),(0,r.kt)("td",{parentName:"tr",align:null},"Error from Wallet module")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32016"),(0,r.kt)("td",{parentName:"tr",align:null},"Inconsistency error"),(0,r.kt)("td",{parentName:"tr",align:null},"Inconsistency in the result of request")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32017"),(0,r.kt)("td",{parentName:"tr",align:null},"Missing command sender"),(0,r.kt)("td",{parentName:"tr",align:null},"Missing command sender")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32018"),(0,r.kt)("td",{parentName:"tr",align:null},"Missing config"),(0,r.kt)("td",{parentName:"tr",align:null},"Missing configuration")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"-32019"),(0,r.kt)("td",{parentName:"tr",align:null},"Wrong API"),(0,r.kt)("td",{parentName:"tr",align:null},"The wrong API (either Public or Private) was called")))),(0,r.kt)("details",null,(0,r.kt)("summary",null,"Example error: "),(0,r.kt)("p",null,(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n"jsonrpc": "2.0",\n"error": {\n "code": -32400,\n "message": "Bad request: too many arguments, maximum authorized 2 but found 3"\n},\n"id": 1\n}\n')))))}k.isMDXComponent=!0},2970:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/postman_websocket-d590daa827a5e9776c8b59899397a030.png"}}]); \ No newline at end of file diff --git a/assets/js/28eb6811.45a8763e.js b/assets/js/28eb6811.45a8763e.js deleted file mode 100644 index 9b5be0100..000000000 --- a/assets/js/28eb6811.45a8763e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[6952],{3905:(e,n,t)=>{t.d(n,{Zo:()=>_,kt:()=>d});var a=t(7294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function r(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=a.createContext({}),l=function(e){var n=a.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},_=function(e){var n=l(e.components);return a.createElement(c.Provider,{value:n},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},m=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,_=s(e,["components","mdxType","originalType","parentName"]),u=l(t),m=o,d=u["".concat(c,".").concat(m)]||u[m]||p[m]||i;return t?a.createElement(d,r(r({ref:n},_),{},{components:t})):a.createElement(d,r({ref:n},_))}));function d(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,r=new Array(i);r[0]=m;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s[u]="string"==typeof e?e:o,r[1]=s;for(var l=2;l{t.d(n,{Z:()=>r});var a=t(7294),o=t(6010);const i={tabItem:"tabItem_Ymn6"};function r(e){let{children:n,hidden:t,className:r}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(i.tabItem,r),hidden:t},n)}},4866:(e,n,t)=>{t.d(n,{Z:()=>y});var a=t(7462),o=t(7294),i=t(6010),r=t(2466),s=t(6550),c=t(1980),l=t(7392),_=t(12);function u(e){return function(e){return o.Children.map(e,(e=>{if(!e||(0,o.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:n,label:t,attributes:a,default:o}}=e;return{value:n,label:t,attributes:a,default:o}}))}function p(e){const{values:n,children:t}=e;return(0,o.useMemo)((()=>{const e=n??u(t);return function(e){const n=(0,l.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,t])}function m(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function d(e){let{queryString:n=!1,groupId:t}=e;const a=(0,s.k6)(),i=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,c._X)(i),(0,o.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(a.location.search);n.set(i,e),a.replace({...a.location,search:n.toString()})}),[i,a])]}function h(e){const{defaultValue:n,queryString:t=!1,groupId:a}=e,i=p(e),[r,s]=(0,o.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({value:n,tabValues:t}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const a=t.find((e=>e.default))??t[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:n,tabValues:i}))),[c,l]=d({queryString:t,groupId:a}),[u,h]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[a,i]=(0,_.Nk)(t);return[a,(0,o.useCallback)((e=>{t&&i.set(e)}),[t,i])]}({groupId:a}),f=(()=>{const e=c??u;return m({value:e,tabValues:i})?e:null})();(0,o.useLayoutEffect)((()=>{f&&s(f)}),[f]);return{selectedValue:r,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);s(e),l(e),h(e)}),[l,h,i]),tabValues:i}}var f=t(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function g(e){let{className:n,block:t,selectedValue:s,selectValue:c,tabValues:l}=e;const _=[],{blockElementScrollPositionUntilNextRender:u}=(0,r.o5)(),p=e=>{const n=e.currentTarget,t=_.indexOf(n),a=l[t].value;a!==s&&(u(n),c(a))},m=e=>{let n=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const t=_.indexOf(e.currentTarget)+1;n=_[t]??_[0];break}case"ArrowLeft":{const t=_.indexOf(e.currentTarget)-1;n=_[t]??_[_.length-1];break}}n?.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":t},n)},l.map((e=>{let{value:n,label:t,attributes:r}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===n?0:-1,"aria-selected":s===n,key:n,ref:e=>_.push(e),onKeyDown:m,onClick:p},r,{className:(0,i.Z)("tabs__item",b.tabItem,r?.className,{"tabs__item--active":s===n})}),t??n)})))}function x(e){let{lazy:n,children:t,selectedValue:a}=e;const i=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=i.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},i.map(((e,n)=>(0,o.cloneElement)(e,{key:n,hidden:e.props.value!==a}))))}function k(e){const n=h(e);return o.createElement("div",{className:(0,i.Z)("tabs-container",b.tabList)},o.createElement(g,(0,a.Z)({},e,n)),o.createElement(x,(0,a.Z)({},e,n)))}function y(e){const n=(0,f.Z)();return o.createElement(k,(0,a.Z)({key:String(n)},e))}},3353:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>_,contentTitle:()=>c,default:()=>d,frontMatter:()=>s,metadata:()=>l,toc:()=>u});var a=t(7462),o=(t(7294),t(3905)),i=t(4866),r=t(5162);const s={id:"all-configs",sidebar_label:"Node and client configuration"},c="Node and client configuration",l={unversionedId:"node/all-configs",id:"node/all-configs",title:"Node and client configuration",description:"Use with caution, overriding some configurations could lead to node",source:"@site/docs/node/all-configs.mdx",sourceDirName:"node",slug:"/node/all-configs",permalink:"/docs/node/all-configs",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/node/all-configs.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"all-configs",sidebar_label:"Node and client configuration"},sidebar:"nodeSidebar",previous:{title:"Check your node's status",permalink:"/docs/node/check_status"},next:{title:"Updating a node",permalink:"/docs/node/update"}},_={},u=[{value:"Node configuration",id:"node-configuration",level:2},{value:"Client configuration",id:"client-configuration",level:2}],p={toc:u},m="wrapper";function d(e){let{components:n,...t}=e;return(0,o.kt)(m,(0,a.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"node-and-client-configuration"},"Node and client configuration"),(0,o.kt)("admonition",{type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Use with caution, overriding some configurations could lead to node\ninstability and/or a complete desynchronization from Massa blockchain.")),(0,o.kt)("h2",{id:"node-configuration"},"Node configuration"),(0,o.kt)("p",null,"You can override the default configuration via\nthe ",(0,o.kt)("inlineCode",{parentName:"p"},"massa-node/config/config.toml")," file."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{value:"mainnet",label:"\ud83d\udda5 MainNet",default:!0,mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[logging]\n # Logging level. High log levels might impact performance. 0: ERROR, 1: WARN, 2: INFO, 3: DEBUG, 4: TRACE\n level = 2\n\n[api]\n # max number of future periods considered during requests\n draw_lookahead_period_count = 10\n # port on which the node API listens for admin and node management requests. Dangerous if publicly exposed. Bind to "[::1]:port" for IPv6\n bind_private = "127.0.0.1:33034"\n # port on which the node API listens for public requests. Can be exposed to the Internet. Bind to "[::]:port" for IPv6\n bind_public = "0.0.0.0:33035"\n # port on which the node API(V2) listens for HTTP requests and WebSockets subscriptions. Can be exposed to the Internet. Bind to "[::]:port" for IPv6\n bind_api = "0.0.0.0:33036"\n # max number of arguments per RPC call\n max_arguments = 128\n # path to the openrpc specification file used in `rpc.discover` method\n openrpc_spec_path = "base_config/openrpc.json"\n # maximum size in bytes of a request. Defaults to 50MB\n max_request_body_size = 52428800\n # maximum size in bytes of a response. Defaults to 50MB\n max_response_body_size = 52428800\n # maximum number of incoming connections allowed\n max_connections = 100\n # maximum number of subscriptions per connection\n max_subscriptions_per_connection = 100\n # max length for logging for requests and responses. Logs bigger than this limit will be truncated\n max_log_length = 4096\n # host filtering\n allow_hosts = []\n # batch request limit. 0 means disabled\n batch_request_limit = 16\n # the interval at which `Ping` frames are submitted in milliseconds\n ping_interval = 60000\n # whether to enable HTTP.\n enable_http = true\n # whether to enable WS.\n enable_ws = false\n # whether to broadcast for blocks, endorsements and operations\n enable_broadcast = false\n # deferred credits delta (in milliseconds)\n deferred_credits_delta = 7776000000 # ~ 3 months (90\xd724\xd760\xd760\xd71000) in milliseconds\n\n[grpc]\n [grpc.public]\n # whether to enable gRPC\n enabled = true\n # whether to add HTTP 1 layer\n accept_http1 = false\n # whether to enable CORS. works only if `accept_http1` is true\n enable_cors = false\n # whether to enable gRPC health service\n enable_health = true\n # whether to enable gRPC reflection(introspection)\n enable_reflection = true\n # whether to enable TLS\n enable_tls = false\n # whether to enable mTLS (requires `enable_tls` to be true)\n enable_mtls = false\n # whether to generate a self-signed certificate if none is provided(ignored if `enable_tls` is false)\n generate_self_signed_certificates = true\n # list of subject alternative names for the server certificate(requires `generate_self_signed_certificates` to be true)\n subject_alt_names = []\n # bind for the Massa gRPC API\n bind = "0.0.0.0:33037"\n # which compression encodings does the server accept for requests\n accept_compressed = "Gzip"\n # which compression encodings might the server use for responses\n send_compressed = "Gzip"\n # limits the maximum size of a decoded message. Defaults to 50MB\n max_decoding_message_size = 52428800\n # limits the maximum size of an encoded message. Defaults to 50MB\n max_encoding_message_size = 52428800\n # limits the maximum size of streaming channel\n max_channel_size = 128\n # set a timeout on for all request handlers in seconds. Defaults to 60s\n timeout = 60\n # sets the maximum frame size to use for HTTP2(must be within 16384(16KB) and 16777215(16MB)). Defaults to 16KB\n max_frame_size = 16384\n # set the concurrency limit applied to on requests inbound per connection. Defaults to 32\n concurrency_limit_per_connection = 100\n # sets the SETTINGS_MAX_CONCURRENT_STREAMS spec option for HTTP2 connections\n max_concurrent_streams = 100\n # max number of arguments per gRPC request\n max_arguments = 128\n # set the value of `TCP_NODELAY` option for accepted connections. Enabled by default\n tcp_nodelay = true\n # max number of future periods considered during requests\n draw_lookahead_period_count = 10\n # max number of addresses that can be included in a single request\n max_addresses_per_request = 50\n # max number of slot ranges that can be included in a single request\n max_slot_ranges_per_request = 50\n # max number of block ids that can be included in a single request\n max_block_ids_per_request = 50\n # max number of endorsement ids that can be included in a single request\n max_endorsement_ids_per_request = 100\n # max number of operation ids that can be included in a single request\n max_operation_ids_per_request = 250\n # max op datastore entries per request\n max_datastore_entries_per_request = 128\n # max number of filters that can be included in a single request\n max_filters_per_request = 32\n # max number of query items that can be included in a single request\n max_query_items_per_request = 128\n # certificate authority root path\n certificate_authority_root_path = "config/tls_public_ca.pem"\n # server certificate path\n server_certificate_path = "config/tls_public_server.pem"\n # server private key path\n server_private_key_path = "config/tls_public_server.key"\n # client certificate authority root path\n client_certificate_authority_root_path = "config/tls_public_client_ca.pem"\n # client certificate path\n client_certificate_path = "../massa-client/config/tls_public_client.pem"\n # client private key path\n client_private_key_path = "../massa-client/config/tls_public_client.key"\n [grpc.private]\n # whether to enable gRPC\n enabled = true\n # whether to add HTTP 1 layer\n accept_http1 = false\n # whether to enable CORS. works only if `accept_http1` is true\n enable_cors = false\n # whether to enable gRPC health service\n enable_health = true\n # whether to enable gRPC reflection(introspection)\n enable_reflection = true\n # whether to enable TLS\n enable_tls = false\n # whether to enable mTLS (requires `enable_tls` to be true)\n enable_mtls = true\n # whether to generate a self-signed certificate if none is provided(ignored if `enable_tls` is false)\n generate_self_signed_certificates = true\n # list of subject alternative names for the server certificate(requires `generate_self_signed_certificates` to be true)\n subject_alt_names = []\n # bind for the Massa gRPC API\n bind = "127.0.0.1:33038"\n # which compression encodings does the server accept for requests\n accept_compressed = "Gzip"\n # which compression encodings might the server use for responses\n send_compressed = "Gzip"\n # limits the maximum size of a decoded message. Defaults to 50MB\n max_decoding_message_size = 52428800\n # limits the maximum size of an encoded message. Defaults to 50MB\n max_encoding_message_size = 52428800\n # limits the maximum size of streaming channel\n max_channel_size = 128\n # set a timeout on for all request handlers in seconds. Defaults to 60s\n timeout = 60\n # sets the maximum frame size to use for HTTP2(must be within 16384(16KB) and 16777215(16MB)). Defaults to 16KB\n max_frame_size = 16384\n # set the concurrency limit applied to on requests inbound per connection. Defaults to 32\n concurrency_limit_per_connection = 100\n # sets the SETTINGS_MAX_CONCURRENT_STREAMS spec option for HTTP2 connections\n max_concurrent_streams = 100\n # max number of arguments per gRPC request\n max_arguments = 128\n # set the value of `TCP_NODELAY` option for accepted connections. Enabled by default\n tcp_nodelay = true\n # max number of future periods considered during requests\n draw_lookahead_period_count = 10\n # max number of addresses that can be included in a single request\n max_addresses_per_request = 50\n # max number of slot ranges that can be included in a single request\n max_slot_ranges_per_request = 50\n # max number of block ids that can be included in a single request\n max_block_ids_per_request = 50\n # max number of endorsement ids that can be included in a single request\n max_endorsement_ids_per_request = 100\n # max number of operation ids that can be included in a single request\n max_operation_ids_per_request = 250\n # max op datastore entries per request\n max_datastore_entries_per_request = 128\n # max number of filters that can be included in a single request\n max_filters_per_request = 32\n # max number of query items that can be included in a single request\n max_query_items_per_request = 128\n # certificate authority root path\n certificate_authority_root_path = "config/tls_private_ca.pem"\n # server certificate path\n server_certificate_path = "config/tls_private_server.pem"\n # server private key path\n server_private_key_path = "config/tls_private_server.key"\n # client certificate authority root path\n client_certificate_authority_root_path = "config/tls_private_client_ca.pem"\n # client certificate path\n client_certificate_path = "../massa-client/config/tls_private_client.pem"\n # client private key path\n client_private_key_path = "../massa-client/config/tls_private_client.key"\n[execution]\n # max number of generated events kept in RAM\n max_final_events = 10000\n # maximum length of the read-only execution requests queue\n readonly_queue_length = 10\n # by how many milliseconds should the execution lag behind real time\n # higher values increase speculative execution lag but improve performance\n cursor_delay = 2000\n # duration of the statistics time window in milliseconds\n stats_time_window_duration = 60000\n # maximum allowed gas for read only executions\n max_read_only_gas = 4_294_967_295\n # gas cost for ABIs\n abi_gas_costs_file = "base_config/gas_costs/abi_gas_costs.json"\n # gas cost for wasm operator\n wasm_gas_costs_file = "base_config/gas_costs/wasm_gas_costs.json"\n # path to the hard drive cache storage\n hd_cache_path = "storage/cache/rocks_db"\n # maximum number of entries we want to keep in the LRU cache\n # in the worst case scenario this is equivalent to 2Gb\n lru_cache_size = 200\n # maximum number of entries we want to keep in the HD cache\n # in the worst case scenario this is equivalent to 20Gb\n hd_cache_size = 2000\n # amount of entries removed when `hd_cache_size` is reached\n snip_amount = 10\n # slot execution outputs channel capacity\n broadcast_slot_execution_output_channel_capacity = 5000\n\n[ledger]\n # path to the initial ledger\n initial_ledger_path = "base_config/initial_ledger.json"\n # path to the disk ledger db directory\n disk_ledger_path = "storage/ledger/rocks_db"\n # length of the changes history. Higher values allow bootstrapping nodes with slower connections\n final_history_length = 100\n # path of the initial deferred credits file\n initial_deferred_credits_path = "base_config/deferred_credits.json"\n\n[consensus]\n # max number of previously discarded blocks kept in RAM\n max_discarded_blocks = 100\n # max number of blocks in the future kept in RAM\n max_future_processing_blocks = 400\n # max number of blocks waiting for dependencies\n max_dependency_blocks = 2048\n # number of final periods that must be kept without operations (increase improve bootstrap process, high values will increase RAM usage.)\n force_keep_final_periods_without_ops = 32\n # number of final periods that must be kept with operations (increase to more resilience to short network disconnections, high values will increase RAM usage.)\n force_keep_final_periods = 5\n # useless blocks are pruned every block_db_prune_interval ms\n block_db_prune_interval = 5000\n # considered timespan for stats info\n stats_timespan = 60000\n # blocks headers channel capacity\n broadcast_blocks_headers_channel_capacity = 128\n # blocks channel capacity\n broadcast_blocks_channel_capacity = 128\n # filled blocks channel capacity\n broadcast_filled_blocks_channel_capacity = 128\n\n[protocol]\n # port on which to listen for protocol communication. You may need to change this to "0.0.0.0:port" if IPv6 is disabled system-wide.\n bind = "[::]:31244"\n # timeout for connection establishment\n connect_timeout = 3000\n # path to the node key (not the staking key)\n keypair_file = "config/node_privkey.key"\n # path to the initial peers file\n initial_peers_file = "base_config/initial_peers.json"\n # Limit of read/write number of bytes per second with a peer (Should be a 10 multiple)\n read_write_limit_bytes_per_second = 2_000_000_000\n # timeout after which without answer a handshake is ended\n message_timeout = 5000\n # timeout after which a peer tester will consider the peer unreachable\n tester_timeout = 10000\n # timeout after whick we consider a node does not have the block we asked for\n ask_block_timeout = 10000\n # Max known blocks we keep during their propagation\n max_blocks_kept_for_propagation = 300\n # Time during which a block is expected to propagate (in milliseconds)\n max_block_propagation_time = 40000\n # Block propagation tick interval, useful for propagating blocks quickly to newly connected peers (in milliseconds)\n block_propagation_tick = 1000\n # max cache size for which blocks our node knows about\n max_known_blocks_size = 1024\n # max cache size for which blocks a foreign node knows about\n max_node_known_blocks_size = 1024\n # max cache size for which blocks a foreign node asked for\n max_node_wanted_blocks_size = 1024\n # max number of blocks we can ask simultaneously per node\n max_simultaneous_ask_blocks_per_node = 128\n # max milliseconds to wait while sending an event before dropping it\n max_send_wait = 0\n # max cache size for which operations your node knows about\n max_known_ops_size = 1000000\n # max size of the cache of asked operations\n asked_operations_buffer_capacity = 600000\n # max cache size for which operations a foreign node knows about\n max_node_known_ops_size = 200000\n # max cache size for which endorsements our node knows about\n max_known_endorsements_size = 2048\n # max cache size for which endorsements a foreign node knows about\n max_node_known_endorsements_size = 2048\n # maximum number of batches in the memory buffer.\n # dismiss the new batches if overflow\n operation_batch_buffer_capacity = 10024\n # immediately announce ops if overflow\n operation_announcement_buffer_capacity = 2000\n # start processing batches in the buffer each `operation_batch_proc_period` in millisecond\n operation_batch_proc_period = 500\n # interval at which operations are announced in batches.\n operation_announcement_interval = 300\n # max number of operation per message, same as network param but can be smaller\n max_operations_per_message = 5000\n # Number of millis seconds between each try out connections\n try_connection_timer = 250\n # Number of millis seconds between each try out connections for same peer\n try_connection_timer_same_peer = 10000\n # Number of millis seconds between each unban of every peer\n unban_everyone_timer = 86400000\n # Number of millis seconds that create a timeout for out connections\n timeout_connection = 1000\n # max number of operations kept for propagation\n max_ops_kept_for_propagation = 320000\n # time threshold after which operation are not propagated\n max_operations_propagation_time = 32000\n # time threshold after which endorsement are not propagated\n max_endorsements_propagation_time = 32000\n # number of thread tester\n thread_tester_count = 25\n # Nb max in connections that we accept\n max_in_connections = 250\n # Cooldown before testing again old peer\n test_oldest_peer_cooldown = 720000\n # Rate limitation on the data streams (per second)\n rate_limit = 5_242_880 # 5 MiB / secs\n # Peer default category limits\n default_category_info = { target_out_connections = 10, max_in_connections_per_ip = 2, max_in_connections = 15, allow_local_peers = false }\n # Peer categories limits\n [protocol.peers_categories]\n Bootstrap = { target_out_connections = 1, max_in_connections_per_ip = 1, max_in_connections = 1, allow_local_peers = false }\n\n[network]\n\n[metrics]\n # enable prometheus metrics\n enabled = true\n # port on which to listen for prometheus metrics\n bind = "[::]:31248"\n # interval at which to update metrics\n tick_delay = 5000\n\n[bootstrap]\n # list of bootstrap (ip, node id)\n bootstrap_list = [\n ["149.202.86.103:31245", "N16noomm9akwBSTkvhs4KX6kjbhVhYkLqrzneCwBdo2SUE8axHx"],\n ["149.202.89.125:31245", "N12bYghvuhCuQ38iSAGQvKTb1iXtwzPZhNJLhWQPYcmgz8PDPAGo"],\n ["158.69.120.215:31245", "N1jRVjMZK8ZEmUGxDbLgHv3BTeQy8wHnazKCdcpQy4sFxu9d8GW"],\n ["158.69.23.120:31245", "N12B7LqdyVVBXr8TMygU28R7JYxUR2dsLLp63YXtH9XAR1R2NUrY"],\n ["198.27.74.5:31245", "N1FoYxXoSC39ZamAvwi7srz3oRrJ8JC3EvRhcqXPCD7vaQZTHKV"],\n ["51.75.60.228:31245", "N1nRDdGq7DFD7AvSz5pgAsXCvkcqoL5Xf3kHr8Yd3TTUgtBcBun"],\n ["[2001:41d0:1004:67::]:31245", "N16noomm9akwBSTkvhs4KX6kjbhVhYkLqrzneCwBdo2SUE8axHx"],\n ["[2001:41d0:a:7f7d::]:31245", "N12bYghvuhCuQ38iSAGQvKTb1iXtwzPZhNJLhWQPYcmgz8PDPAGo"],\n ["[2001:41d0:602:21e4::]:31245", "N1nRDdGq7DFD7AvSz5pgAsXCvkcqoL5Xf3kHr8Yd3TTUgtBcBun"],\n ]\n # force the bootstrap protocol to use: "IPv4", "IPv6", or "Both". Defaults to using both protocols.\n bootstrap_protocol = "Both"\n # path to the bootstrap whitelist file. This whitelist define IPs that can bootstrap on your node.\n bootstrap_whitelist_path = "base_config/bootstrap_whitelist.json"\n # path to the bootstrap blacklist file. This whitelist define IPs that will not be able to bootstrap on your node. This list is optional.\n bootstrap_blacklist_path = "base_config/bootstrap_blacklist.json"\n # [optional] port on which to listen for incoming bootstrap requests. You may need to change this to "0.0.0.0:port" if IPv6 is disabled system-wide.\n bind = "[::]:31245"\n # timeout to establish a bootstrap connection\n connect_timeout = 15000\n # timeout for providing the bootstrap to a connection\n bootstrap_timeout = 600000 # 10 mins\n # delay in milliseconds to wait between consecutive bootstrap attempts\n retry_delay = 60000\n # if ping is too high bootstrap will be interrupted after max_ping milliseconds\n max_ping = 10000\n # timeout for incoming message readout\n read_timeout = 30000\n # timeout for message sending\n write_timeout = 30000\n # timeout for incoming error message readout\n read_error_timeout = 200\n # timeout for message error sending\n write_error_timeout = 200\n # max allowed difference between client and servers clocks in ms\n max_clock_delta = 5000\n # [server] data is cached for cache duration milliseconds\n cache_duration = 15000\n # max number of simulataneous bootstraps for server\n max_simultaneous_bootstraps = 2\n # max size of recently bootstrapped IP cache\n ip_list_max_size = 10000\n # refuse consecutive bootstrap attempts from a given IP when the interval between them is lower than per_ip_min_interval milliseconds\n per_ip_min_interval = 180000\n # read-write limitation for a connection in bytes per seconds (about the bootstrap specifically)\n rate_limit = 20_971_520 # 20 MiB /sec\n\n[pool]\n # max number of operations kept in the pool\n max_operation_pool_size = 500000\n # max excess number of operations kept in pool in-between refreshes\n max_operation_pool_excess_items = 100000\n # refresh interval of the operation pool scoring (milliseconds)\n operation_pool_refresh_interval = 5000\n # if an operation is too much in the future it will be ignored (milliseconds)\n operation_max_future_start_delay = 50000\n # max number of endorsements kept per thread\n max_endorsements_pool_size_per_thread = 25000\n # max number of items returned per query\n max_item_return_count = 100\n # endorsements channel capacity\n broadcast_endorsements_channel_capacity = 2000\n # operations channel capacity\n broadcast_operations_channel_capacity = 5000\n\n\n[selector]\n # path to the initial roll distribution\n initial_rolls_path = "base_config/initial_rolls.json"\n\n[factory]\n # initial delay in milliseconds to wait before starting production to avoid double staking on node restart\n initial_delay = 100\n # path to your staking wallets\n staking_wallet_path = "config/staking_wallets"\n # stop or not the production in case we are not connected to anyone\n stop_production_when_zero_connections = true\n\n[versioning]\n # Warn user to update its node if we reach this percentage for announced network versions\n mip_stats_warn_announced_version = 30\n\n'))),(0,o.kt)(r.Z,{value:"buildnet",label:"\ud83d\udc77 BuildNet",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[logging]\nlevel = 2\n\n[api]\ndraw_lookahead_period_count = 10\nbind_private = "127.0.0.1:33034"\nbind_public = "0.0.0.0:33035"\nbind_api = "0.0.0.0:33036"\nmax_arguments = 128\nopenrpc_spec_path = "base_config/openrpc.json"\nmax_request_body_size = 52428800\nmax_response_body_size = 52428800\nmax_connections = 100\nmax_subscriptions_per_connection = 100\nmax_log_length = 4096\nallow_hosts = []\nbatch_request_limit = 16\nping_interval = 60000\nenable_http = true\nenable_ws = true\nenable_broadcast = false\n\n[execution]\nmax_final_events = 10000\nreadonly_queue_length = 10\ncursor_delay = 2000\nstats_time_window_duration = 60000\nmax_read_only_gas = 4294967295\nabi_gas_costs_file = "base_config/gas_costs/abi_gas_costs.json"\nwasm_gas_costs_file = "base_config/gas_costs/wasm_gas_costs.json"\nhd_cache_path = "storage/cache/rocks_db"\nlru_cache_size = 200\nhd_cache_size = 2000\nsnip_amount = 10\nbroadcast_slot_execution_output_channel_capacity = 5000\n\n[ledger]\ninitial_ledger_path = "base_config/initial_ledger.json"\ndisk_ledger_path = "storage/ledger/rocks_db"\nfinal_history_length = 100\ninitial_deferred_credits_path = "base_config/deferred_credits.json"\n\n[consensus]\nmax_discarded_blocks = 100\nmax_future_processing_blocks = 400\nmax_dependency_blocks = 2048\nforce_keep_final_periods_without_ops = 32\nforce_keep_final_periods = 5\nblock_db_prune_interval = 5000\nstats_timespan = 60000\nbroadcast_blocks_headers_channel_capacity = 128\nbroadcast_blocks_channel_capacity = 128\nbroadcast_filled_blocks_channel_capacity = 128\n\n[protocol]\nbind = "[::]:31244"\nconnect_timeout = 3000\nkeypair_file = "config/node_privkey.key"\ninitial_peers_file = "base_config/initial_peers.json"\nread_write_limit_bytes_per_second = 2000000000\nmessage_timeout = 5000\ntester_timeout = 10000\nask_block_timeout = 10000\nmax_blocks_kept_for_propagation = 300\nmax_block_propagation_time = 40000\nblock_propagation_tick = 1000\nmax_known_blocks_size = 1024\nmax_node_known_blocks_size = 1024\nmax_node_wanted_blocks_size = 1024\nmax_simultaneous_ask_blocks_per_node = 128\nmax_send_wait = 0\nmax_known_ops_size = 1000000\nasked_operations_buffer_capacity = 600000\nmax_node_known_ops_size = 200000\nmax_known_endorsements_size = 2048\nmax_node_known_endorsements_size = 2048\noperation_batch_buffer_capacity = 10024\noperation_announcement_buffer_capacity = 2000\noperation_batch_proc_period = 500\noperation_announcement_interval = 300\nmax_operations_per_message = 5000\ntry_connection_timer = 250\ntry_connection_timer_same_peer = 10000\nunban_everyone_timer = 86400000\ntimeout_connection = 1000\nmax_ops_kept_for_propagation = 320000\nmax_operations_propagation_time = 32000\nmax_endorsements_propagation_time = 32000\nthread_tester_count = 25\nmax_in_connections = 250\ntest_oldest_peer_cooldown = 720000\nrate_limit = 5242880\n\n[network]\n\n[metrics]\nenabled = true\nbind = "[::]:31248"\ntick_delay = 5000\n\n[bootstrap]\nbootstrap_list = [ [ "149.202.84.7:31245", "N1kKfgrCveVnosUkxTzaBw5cf9f2cbTvK3R5Ssb2Pf76au8xwmH",], [ "149.202.84.39:31245", "N12sNdL7YwSawpnJrk9XCWDjKbgfNamAobp62AX5qfkgpBkGh2wC",], [ "37.187.156.118:31245", "N1NnuSW48GKGaYZamAVKXfXbbnt3StxWoHpYtBZSJvY9e8U1BTC",],]\nbootstrap_protocol = "Both"\nbootstrap_whitelist_path = "base_config/bootstrap_whitelist.json"\nbootstrap_blacklist_path = "base_config/bootstrap_blacklist.json"\nbind = "[::]:31245"\nconnect_timeout = 15000\nbootstrap_timeout = 600000\nretry_delay = 60000\nmax_ping = 10000\nread_timeout = 30000\nwrite_timeout = 30000\nread_error_timeout = 200\nwrite_error_timeout = 200\nmax_clock_delta = 5000\ncache_duration = 15000\nmax_simultaneous_bootstraps = 2\nip_list_max_size = 10000\nper_ip_min_interval = 1000\nrate_limit = 20971520\n\n[pool]\nmax_operation_pool_size = 500000\nmax_operation_pool_excess_items = 100000\noperation_pool_refresh_interval = 5000\noperation_max_future_start_delay = 50000\nmax_endorsements_pool_size_per_thread = 25000\nmax_item_return_count = 100\nbroadcast_endorsements_channel_capacity = 2000\nbroadcast_operations_channel_capacity = 5000\n\n[selector]\ninitial_rolls_path = "base_config/initial_rolls.json"\n\n[factory]\ninitial_delay = 100\nstaking_wallet_path = "config/staking_wallets"\nstop_production_when_zero_connections = true\n\n[versioning]\nmip_stats_warn_announced_version = 30\n\n[grpc.public]\nenabled = true\naccept_http1 = false\nenable_cors = false\nenable_health = true\nenable_reflection = true\nenable_tls = false\nenable_mtls = false\ngenerate_self_signed_certificates = true\nsubject_alt_names = []\nbind = "0.0.0.0:33037"\naccept_compressed = "Gzip"\nsend_compressed = "Gzip"\nmax_decoding_message_size = 52428800\nmax_encoding_message_size = 52428800\nmax_channel_size = 128\ntimeout = 60\nmax_frame_size = 16384\nconcurrency_limit_per_connection = 100\nmax_concurrent_streams = 100\nmax_arguments = 128\ntcp_nodelay = true\ndraw_lookahead_period_count = 10\nmax_addresses_per_request = 50\nmax_slot_ranges_per_request = 50\nmax_block_ids_per_request = 50\nmax_endorsement_ids_per_request = 100\nmax_operation_ids_per_request = 250\nmax_datastore_entries_per_request = 128\nmax_filters_per_request = 32\nmax_query_items_per_request = 128\ncertificate_authority_root_path = "config/tls_public_ca.pem"\nserver_certificate_path = "config/tls_public_server.pem"\nserver_private_key_path = "config/tls_public_server.key"\nclient_certificate_authority_root_path = "config/tls_public_client_ca.pem"\nclient_certificate_path = "../massa-client/config/tls_public_client.pem"\nclient_private_key_path = "../massa-client/config/tls_public_client.key"\n\n[grpc.private]\nenabled = true\naccept_http1 = false\nenable_cors = false\nenable_health = true\nenable_reflection = true\nenable_tls = false\nenable_mtls = true\ngenerate_self_signed_certificates = true\nsubject_alt_names = []\nbind = "127.0.0.1:33038"\naccept_compressed = "Gzip"\nsend_compressed = "Gzip"\nmax_decoding_message_size = 52428800\nmax_encoding_message_size = 52428800\nmax_channel_size = 128\ntimeout = 60\nmax_frame_size = 16384\nconcurrency_limit_per_connection = 100\nmax_concurrent_streams = 100\nmax_arguments = 128\ntcp_nodelay = true\ndraw_lookahead_period_count = 10\nmax_addresses_per_request = 50\nmax_slot_ranges_per_request = 50\nmax_block_ids_per_request = 50\nmax_endorsement_ids_per_request = 100\nmax_operation_ids_per_request = 250\nmax_datastore_entries_per_request = 128\nmax_filters_per_request = 32\nmax_query_items_per_request = 128\ncertificate_authority_root_path = "config/tls_private_ca.pem"\nserver_certificate_path = "config/tls_private_server.pem"\nserver_private_key_path = "config/tls_private_server.key"\nclient_certificate_authority_root_path = "config/tls_private_client_ca.pem"\nclient_certificate_path = "../massa-client/config/tls_private_client.pem"\nclient_private_key_path = "../massa-client/config/tls_private_client.key"\n\n[protocol.default_category_info]\ntarget_out_connections = 10\nmax_in_connections_per_ip = 2\nmax_in_connections = 15\nallow_local_peers = false\n\n[protocol.peers_categories.Bootstrap]\ntarget_out_connections = 1\nmax_in_connections_per_ip = 1\nmax_in_connections = 1\nallow_local_peers = false\n\n')))),(0,o.kt)("h2",{id:"client-configuration"},"Client configuration"),(0,o.kt)("p",null,"You can override the default configuration via\nthe ",(0,o.kt)("inlineCode",{parentName:"p"},"massa-client/config/config.toml")," file."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{value:"mainnet",label:"\ud83d\udda5 MainNet",default:!0,mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'history = 10\nhistory_file_path = "config/.massa_history"\ntimeout = 1000\n\n[default_node]\n# The IP of your node. Works both with IPv4 (like 127.0.0.1) and IPv6 (like ::1) addresses, if the node is bound to the correct protocol.\nip = "127.0.0.1"\nprivate_port = 33034\npublic_port = 33035\ngrpc_public_port = 33037\ngrpc_private_port = 33038\n# Chain id for MainNet, please update to match the target node chain id\nchain_id = 77658377\n\n[client]\n # maximum size in bytes of a request. Defaults to 50MB\n max_request_body_size = 52428800\n # request timeout\n request_timeout = 60000\n # maximum number of outcoming connections allowed\n max_concurrent_requests = 100\n # certificate_store, `Native` or `WebPki`\n certificate_store = "Native"\n # JSON-RPC request object id data type, `String` or `Number`\n id_kind = "Number"\n # max length for logging for requests and responses. Logs bigger than this limit will be truncated\n max_log_length = 4096\n # custom headers passed to the server with every request (default is empty).\n headers = []\n\n [client.http]\n # whether to enable HTTP.\n enabled = true\n\n'))),(0,o.kt)(r.Z,{value:"buildnet",label:"\ud83d\udc77 BuildNet",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'history = 10\nhistory_file_path = "config/.massa_history"\ntimeout = 1000\n\n[default_node]\n# The IP of your node. Works both with IPv4 (like 127.0.0.1) and IPv6 (like ::1) addresses, if the node is bound to the correct protocol.\nip = "127.0.0.1"\nprivate_port = 33034\npublic_port = 33035\ngrpc_public_port = 33037\ngrpc_private_port = 33038\n# Chain id for BuildNet, please update to match the target node chain id\nchain_id = 77658366\n\n[client]\n # maximum size in bytes of a request. Defaults to 50MB\n max_request_body_size = 52428800\n # request timeout\n request_timeout = 60000\n # maximum number of outcoming connections allowed\n max_concurrent_requests = 100\n # certificate_store, `Native` or `WebPki`\n certificate_store = "Native"\n # JSON-RPC request object id data type, `String` or `Number`\n id_kind = "Number"\n # max length for logging for requests and responses. Logs bigger than this limit will be truncated\n max_log_length = 4096\n # custom headers passed to the server with every request (default is empty).\n headers = []\n\n [client.http]\n # whether to enable HTTP.\n enabled = true\n\n')))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/28eb6811.6b87d377.js b/assets/js/28eb6811.6b87d377.js new file mode 100644 index 000000000..81292c890 --- /dev/null +++ b/assets/js/28eb6811.6b87d377.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[6952],{3905:(e,n,t)=>{t.d(n,{Zo:()=>_,kt:()=>d});var a=t(7294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function r(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=a.createContext({}),l=function(e){var n=a.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},_=function(e){var n=l(e.components);return a.createElement(c.Provider,{value:n},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},m=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,_=s(e,["components","mdxType","originalType","parentName"]),u=l(t),m=o,d=u["".concat(c,".").concat(m)]||u[m]||p[m]||i;return t?a.createElement(d,r(r({ref:n},_),{},{components:t})):a.createElement(d,r({ref:n},_))}));function d(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=t.length,r=new Array(i);r[0]=m;var s={};for(var c in n)hasOwnProperty.call(n,c)&&(s[c]=n[c]);s.originalType=e,s[u]="string"==typeof e?e:o,r[1]=s;for(var l=2;l{t.d(n,{Z:()=>r});var a=t(7294),o=t(6010);const i={tabItem:"tabItem_Ymn6"};function r(e){let{children:n,hidden:t,className:r}=e;return a.createElement("div",{role:"tabpanel",className:(0,o.Z)(i.tabItem,r),hidden:t},n)}},4866:(e,n,t)=>{t.d(n,{Z:()=>y});var a=t(7462),o=t(7294),i=t(6010),r=t(2466),s=t(6550),c=t(1980),l=t(7392),_=t(12);function u(e){return function(e){return o.Children.map(e,(e=>{if(!e||(0,o.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:n,label:t,attributes:a,default:o}}=e;return{value:n,label:t,attributes:a,default:o}}))}function p(e){const{values:n,children:t}=e;return(0,o.useMemo)((()=>{const e=n??u(t);return function(e){const n=(0,l.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,t])}function m(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function d(e){let{queryString:n=!1,groupId:t}=e;const a=(0,s.k6)(),i=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,c._X)(i),(0,o.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(a.location.search);n.set(i,e),a.replace({...a.location,search:n.toString()})}),[i,a])]}function h(e){const{defaultValue:n,queryString:t=!1,groupId:a}=e,i=p(e),[r,s]=(0,o.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!m({value:n,tabValues:t}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const a=t.find((e=>e.default))??t[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:n,tabValues:i}))),[c,l]=d({queryString:t,groupId:a}),[u,h]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[a,i]=(0,_.Nk)(t);return[a,(0,o.useCallback)((e=>{t&&i.set(e)}),[t,i])]}({groupId:a}),f=(()=>{const e=c??u;return m({value:e,tabValues:i})?e:null})();(0,o.useLayoutEffect)((()=>{f&&s(f)}),[f]);return{selectedValue:r,selectValue:(0,o.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);s(e),l(e),h(e)}),[l,h,i]),tabValues:i}}var f=t(2389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function g(e){let{className:n,block:t,selectedValue:s,selectValue:c,tabValues:l}=e;const _=[],{blockElementScrollPositionUntilNextRender:u}=(0,r.o5)(),p=e=>{const n=e.currentTarget,t=_.indexOf(n),a=l[t].value;a!==s&&(u(n),c(a))},m=e=>{let n=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const t=_.indexOf(e.currentTarget)+1;n=_[t]??_[0];break}case"ArrowLeft":{const t=_.indexOf(e.currentTarget)-1;n=_[t]??_[_.length-1];break}}n?.focus()};return o.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":t},n)},l.map((e=>{let{value:n,label:t,attributes:r}=e;return o.createElement("li",(0,a.Z)({role:"tab",tabIndex:s===n?0:-1,"aria-selected":s===n,key:n,ref:e=>_.push(e),onKeyDown:m,onClick:p},r,{className:(0,i.Z)("tabs__item",b.tabItem,r?.className,{"tabs__item--active":s===n})}),t??n)})))}function x(e){let{lazy:n,children:t,selectedValue:a}=e;const i=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=i.find((e=>e.props.value===a));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return o.createElement("div",{className:"margin-top--md"},i.map(((e,n)=>(0,o.cloneElement)(e,{key:n,hidden:e.props.value!==a}))))}function k(e){const n=h(e);return o.createElement("div",{className:(0,i.Z)("tabs-container",b.tabList)},o.createElement(g,(0,a.Z)({},e,n)),o.createElement(x,(0,a.Z)({},e,n)))}function y(e){const n=(0,f.Z)();return o.createElement(k,(0,a.Z)({key:String(n)},e))}},3353:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>_,contentTitle:()=>c,default:()=>d,frontMatter:()=>s,metadata:()=>l,toc:()=>u});var a=t(7462),o=(t(7294),t(3905)),i=t(4866),r=t(5162);const s={id:"all-configs",sidebar_label:"Node and client configuration"},c="Node and client configuration",l={unversionedId:"node/all-configs",id:"node/all-configs",title:"Node and client configuration",description:"Use with caution, overriding some configurations could lead to node",source:"@site/docs/node/all-configs.mdx",sourceDirName:"node",slug:"/node/all-configs",permalink:"/docs/node/all-configs",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/node/all-configs.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"all-configs",sidebar_label:"Node and client configuration"},sidebar:"nodeSidebar",previous:{title:"Check your node's status",permalink:"/docs/node/check_status"},next:{title:"Updating a node",permalink:"/docs/node/update"}},_={},u=[{value:"Node configuration",id:"node-configuration",level:2},{value:"Client configuration",id:"client-configuration",level:2}],p={toc:u},m="wrapper";function d(e){let{components:n,...t}=e;return(0,o.kt)(m,(0,a.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"node-and-client-configuration"},"Node and client configuration"),(0,o.kt)("admonition",{type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Use with caution, overriding some configurations could lead to node\ninstability and/or a complete desynchronization from Massa blockchain.")),(0,o.kt)("h2",{id:"node-configuration"},"Node configuration"),(0,o.kt)("p",null,"You can override the default configuration via\nthe ",(0,o.kt)("inlineCode",{parentName:"p"},"massa-node/config/config.toml")," file."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{value:"mainnet",label:"\ud83d\udda5 MainNet",default:!0,mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[logging]\n # Logging level. High log levels might impact performance. 0: ERROR, 1: WARN, 2: INFO, 3: DEBUG, 4: TRACE\n level = 2\n\n[api]\n # max number of future periods considered during requests\n draw_lookahead_period_count = 10\n # port on which the node API listens for admin and node management requests. Dangerous if publicly exposed. Bind to "[::1]:port" for IPv6\n bind_private = "127.0.0.1:33034"\n # port on which the node API listens for public requests. Can be exposed to the Internet. Bind to "[::]:port" for IPv6\n bind_public = "0.0.0.0:33035"\n # port on which the node API(V2) listens for HTTP requests and WebSockets subscriptions. Can be exposed to the Internet. Bind to "[::]:port" for IPv6\n bind_api = "0.0.0.0:33036"\n # max number of arguments per RPC call\n max_arguments = 128\n # path to the openrpc specification file used in `rpc.discover` method\n openrpc_spec_path = "base_config/openrpc.json"\n # maximum size in bytes of a request. Defaults to 50MB\n max_request_body_size = 52428800\n # maximum size in bytes of a response. Defaults to 50MB\n max_response_body_size = 52428800\n # maximum number of incoming connections allowed\n max_connections = 100\n # maximum number of subscriptions per connection\n max_subscriptions_per_connection = 100\n # max length for logging for requests and responses. Logs bigger than this limit will be truncated\n max_log_length = 4096\n # host filtering\n allow_hosts = []\n # batch request limit. 0 means disabled\n batch_request_limit = 16\n # the interval at which `Ping` frames are submitted in milliseconds\n ping_interval = 60000\n # whether to enable HTTP.\n enable_http = true\n # whether to enable WS.\n enable_ws = false\n # whether to broadcast for blocks, endorsements and operations\n enable_broadcast = false\n # deferred credits delta (in milliseconds)\n deferred_credits_delta = 7776000000 # ~ 3 months (90\xd724\xd760\xd760\xd71000) in milliseconds\n\n[grpc]\n [grpc.public]\n # whether to enable gRPC\n enabled = true\n # whether to add HTTP 1 layer\n accept_http1 = false\n # whether to enable CORS. works only if `accept_http1` is true\n enable_cors = false\n # whether to enable gRPC health service\n enable_health = true\n # whether to enable gRPC reflection(introspection)\n enable_reflection = true\n # whether to enable TLS\n enable_tls = false\n # whether to enable mTLS (requires `enable_tls` to be true)\n enable_mtls = false\n # whether to generate a self-signed certificate if none is provided(ignored if `enable_tls` is false)\n generate_self_signed_certificates = true\n # list of subject alternative names for the server certificate(requires `generate_self_signed_certificates` to be true)\n subject_alt_names = []\n # bind for the Massa gRPC API\n bind = "0.0.0.0:33037"\n # which compression encodings does the server accept for requests\n accept_compressed = "Gzip"\n # which compression encodings might the server use for responses\n send_compressed = "Gzip"\n # limits the maximum size of a decoded message. Defaults to 50MB\n max_decoding_message_size = 52428800\n # limits the maximum size of an encoded message. Defaults to 50MB\n max_encoding_message_size = 52428800\n # limits the maximum size of streaming channel\n max_channel_size = 128\n # set a timeout on for all request handlers in seconds. Defaults to 60s\n timeout = 60\n # sets the maximum frame size to use for HTTP2(must be within 16384(16KB) and 16777215(16MB)). Defaults to 16KB\n max_frame_size = 16384\n # set the concurrency limit applied to on requests inbound per connection. Defaults to 32\n concurrency_limit_per_connection = 100\n # sets the SETTINGS_MAX_CONCURRENT_STREAMS spec option for HTTP2 connections\n max_concurrent_streams = 100\n # max number of arguments per gRPC request\n max_arguments = 128\n # set the value of `TCP_NODELAY` option for accepted connections. Enabled by default\n tcp_nodelay = true\n # max number of future periods considered during requests\n draw_lookahead_period_count = 10\n # max number of addresses that can be included in a single request\n max_addresses_per_request = 50\n # max number of slot ranges that can be included in a single request\n max_slot_ranges_per_request = 50\n # max number of block ids that can be included in a single request\n max_block_ids_per_request = 50\n # max number of endorsement ids that can be included in a single request\n max_endorsement_ids_per_request = 100\n # max number of operation ids that can be included in a single request\n max_operation_ids_per_request = 250\n # max op datastore entries per request\n max_datastore_entries_per_request = 128\n # max number of filters that can be included in a single request\n max_filters_per_request = 32\n # max number of query items that can be included in a single request\n max_query_items_per_request = 128\n # certificate authority root path\n certificate_authority_root_path = "config/tls_public_ca.pem"\n # server certificate path\n server_certificate_path = "config/tls_public_server.pem"\n # server private key path\n server_private_key_path = "config/tls_public_server.key"\n # client certificate authority root path\n client_certificate_authority_root_path = "config/tls_public_client_ca.pem"\n # client certificate path\n client_certificate_path = "../massa-client/config/tls_public_client.pem"\n # client private key path\n client_private_key_path = "../massa-client/config/tls_public_client.key"\n [grpc.private]\n # whether to enable gRPC\n enabled = true\n # whether to add HTTP 1 layer\n accept_http1 = false\n # whether to enable CORS. works only if `accept_http1` is true\n enable_cors = false\n # whether to enable gRPC health service\n enable_health = true\n # whether to enable gRPC reflection(introspection)\n enable_reflection = true\n # whether to enable TLS\n enable_tls = false\n # whether to enable mTLS (requires `enable_tls` to be true)\n enable_mtls = true\n # whether to generate a self-signed certificate if none is provided(ignored if `enable_tls` is false)\n generate_self_signed_certificates = true\n # list of subject alternative names for the server certificate(requires `generate_self_signed_certificates` to be true)\n subject_alt_names = []\n # bind for the Massa gRPC API\n bind = "127.0.0.1:33038"\n # which compression encodings does the server accept for requests\n accept_compressed = "Gzip"\n # which compression encodings might the server use for responses\n send_compressed = "Gzip"\n # limits the maximum size of a decoded message. Defaults to 50MB\n max_decoding_message_size = 52428800\n # limits the maximum size of an encoded message. Defaults to 50MB\n max_encoding_message_size = 52428800\n # limits the maximum size of streaming channel\n max_channel_size = 128\n # set a timeout on for all request handlers in seconds. Defaults to 60s\n timeout = 60\n # sets the maximum frame size to use for HTTP2(must be within 16384(16KB) and 16777215(16MB)). Defaults to 16KB\n max_frame_size = 16384\n # set the concurrency limit applied to on requests inbound per connection. Defaults to 32\n concurrency_limit_per_connection = 100\n # sets the SETTINGS_MAX_CONCURRENT_STREAMS spec option for HTTP2 connections\n max_concurrent_streams = 100\n # max number of arguments per gRPC request\n max_arguments = 128\n # set the value of `TCP_NODELAY` option for accepted connections. Enabled by default\n tcp_nodelay = true\n # max number of future periods considered during requests\n draw_lookahead_period_count = 10\n # max number of addresses that can be included in a single request\n max_addresses_per_request = 50\n # max number of slot ranges that can be included in a single request\n max_slot_ranges_per_request = 50\n # max number of block ids that can be included in a single request\n max_block_ids_per_request = 50\n # max number of endorsement ids that can be included in a single request\n max_endorsement_ids_per_request = 100\n # max number of operation ids that can be included in a single request\n max_operation_ids_per_request = 250\n # max op datastore entries per request\n max_datastore_entries_per_request = 128\n # max number of filters that can be included in a single request\n max_filters_per_request = 32\n # max number of query items that can be included in a single request\n max_query_items_per_request = 128\n # certificate authority root path\n certificate_authority_root_path = "config/tls_private_ca.pem"\n # server certificate path\n server_certificate_path = "config/tls_private_server.pem"\n # server private key path\n server_private_key_path = "config/tls_private_server.key"\n # client certificate authority root path\n client_certificate_authority_root_path = "config/tls_private_client_ca.pem"\n # client certificate path\n client_certificate_path = "../massa-client/config/tls_private_client.pem"\n # client private key path\n client_private_key_path = "../massa-client/config/tls_private_client.key"\n[execution]\n # max number of generated events kept in RAM\n max_final_events = 10000\n # maximum length of the read-only execution requests queue\n readonly_queue_length = 10\n # by how many milliseconds should the execution lag behind real time\n # higher values increase speculative execution lag but improve performance\n cursor_delay = 2000\n # duration of the statistics time window in milliseconds\n stats_time_window_duration = 60000\n # maximum allowed gas for read only executions\n max_read_only_gas = 4_294_967_295\n # gas cost for ABIs\n abi_gas_costs_file = "base_config/gas_costs/abi_gas_costs.json"\n # gas cost for wasm operator\n wasm_gas_costs_file = "base_config/gas_costs/wasm_gas_costs.json"\n # path to the hard drive cache storage\n hd_cache_path = "storage/cache/rocks_db"\n # maximum number of entries we want to keep in the LRU cache\n # in the worst case scenario this is equivalent to 2Gb\n lru_cache_size = 200\n # maximum number of entries we want to keep in the HD cache\n # in the worst case scenario this is equivalent to 20Gb\n hd_cache_size = 2000\n # amount of entries removed when `hd_cache_size` is reached\n snip_amount = 10\n # slot execution outputs channel capacity\n broadcast_slot_execution_output_channel_capacity = 5000\n\n[ledger]\n # path to the initial ledger\n initial_ledger_path = "base_config/initial_ledger.json"\n # path to the disk ledger db directory\n disk_ledger_path = "storage/ledger/rocks_db"\n # length of the changes history. Higher values allow bootstrapping nodes with slower connections\n final_history_length = 100\n # path of the initial deferred credits file\n initial_deferred_credits_path = "base_config/deferred_credits.json"\n\n[consensus]\n # max number of previously discarded blocks kept in RAM\n max_discarded_blocks = 100\n # max number of blocks in the future kept in RAM\n max_future_processing_blocks = 400\n # max number of blocks waiting for dependencies\n max_dependency_blocks = 2048\n # number of final periods that must be kept without operations (increase improve bootstrap process, high values will increase RAM usage.)\n force_keep_final_periods_without_ops = 32\n # number of final periods that must be kept with operations (increase to more resilience to short network disconnections, high values will increase RAM usage.)\n force_keep_final_periods = 5\n # useless blocks are pruned every block_db_prune_interval ms\n block_db_prune_interval = 5000\n # considered timespan for stats info\n stats_timespan = 60000\n # blocks headers channel capacity\n broadcast_blocks_headers_channel_capacity = 128\n # blocks channel capacity\n broadcast_blocks_channel_capacity = 128\n # filled blocks channel capacity\n broadcast_filled_blocks_channel_capacity = 128\n\n[protocol]\n # port on which to listen for protocol communication. You may need to change this to "0.0.0.0:port" if IPv6 is disabled system-wide.\n bind = "[::]:31244"\n # timeout for connection establishment\n connect_timeout = 3000\n # path to the node key (not the staking key)\n keypair_file = "config/node_privkey.key"\n # path to the initial peers file\n initial_peers_file = "base_config/initial_peers.json"\n # Limit of read/write number of bytes per second with a peer (Should be a 10 multiple)\n read_write_limit_bytes_per_second = 2_000_000_000\n # timeout after which without answer a handshake is ended\n message_timeout = 5000\n # timeout after which a peer tester will consider the peer unreachable\n tester_timeout = 10000\n # timeout after whick we consider a node does not have the block we asked for\n ask_block_timeout = 10000\n # Max known blocks we keep during their propagation\n max_blocks_kept_for_propagation = 300\n # Time during which a block is expected to propagate (in milliseconds)\n max_block_propagation_time = 40000\n # Block propagation tick interval, useful for propagating blocks quickly to newly connected peers (in milliseconds)\n block_propagation_tick = 1000\n # max cache size for which blocks our node knows about\n max_known_blocks_size = 1024\n # max cache size for which blocks a foreign node knows about\n max_node_known_blocks_size = 1024\n # max cache size for which blocks a foreign node asked for\n max_node_wanted_blocks_size = 1024\n # max number of blocks we can ask simultaneously per node\n max_simultaneous_ask_blocks_per_node = 128\n # max milliseconds to wait while sending an event before dropping it\n max_send_wait = 0\n # max cache size for which operations your node knows about\n max_known_ops_size = 1000000\n # max size of the cache of asked operations\n asked_operations_buffer_capacity = 600000\n # max cache size for which operations a foreign node knows about\n max_node_known_ops_size = 200000\n # max cache size for which endorsements our node knows about\n max_known_endorsements_size = 2048\n # max cache size for which endorsements a foreign node knows about\n max_node_known_endorsements_size = 2048\n # maximum number of batches in the memory buffer.\n # dismiss the new batches if overflow\n operation_batch_buffer_capacity = 10024\n # immediately announce ops if overflow\n operation_announcement_buffer_capacity = 2000\n # start processing batches in the buffer each `operation_batch_proc_period` in millisecond\n operation_batch_proc_period = 500\n # interval at which operations are announced in batches.\n operation_announcement_interval = 300\n # max number of operation per message, same as network param but can be smaller\n max_operations_per_message = 5000\n # Number of millis seconds between each try out connections\n try_connection_timer = 250\n # Number of millis seconds between each try out connections for same peer\n try_connection_timer_same_peer = 10000\n # Number of millis seconds between each unban of every peer\n unban_everyone_timer = 86400000\n # Number of millis seconds that create a timeout for out connections\n timeout_connection = 1000\n # max number of operations kept for propagation\n max_ops_kept_for_propagation = 320000\n # time threshold after which operation are not propagated\n max_operations_propagation_time = 32000\n # time threshold after which endorsement are not propagated\n max_endorsements_propagation_time = 32000\n # number of thread tester\n thread_tester_count = 25\n # Nb max in connections that we accept\n max_in_connections = 250\n # Cooldown before testing again old peer\n test_oldest_peer_cooldown = 720000\n # Rate limitation on the data streams (per second)\n rate_limit = 5_242_880 # 5 MiB / secs\n # Peer default category limits\n default_category_info = { target_out_connections = 10, max_in_connections_per_ip = 2, max_in_connections = 15, allow_local_peers = false }\n # Peer categories limits\n [protocol.peers_categories]\n Bootstrap = { target_out_connections = 1, max_in_connections_per_ip = 1, max_in_connections = 1, allow_local_peers = false }\n\n[network]\n\n[metrics]\n # enable prometheus metrics\n enabled = true\n # port on which to listen for prometheus metrics\n bind = "[::]:31248"\n # interval at which to update metrics\n tick_delay = 5000\n\n[bootstrap]\n # list of bootstrap (ip, node id)\n bootstrap_list = [\n ["149.202.86.103:31245", "N16noomm9akwBSTkvhs4KX6kjbhVhYkLqrzneCwBdo2SUE8axHx"],\n ["149.202.89.125:31245", "N12bYghvuhCuQ38iSAGQvKTb1iXtwzPZhNJLhWQPYcmgz8PDPAGo"],\n ["158.69.120.215:31245", "N1jRVjMZK8ZEmUGxDbLgHv3BTeQy8wHnazKCdcpQy4sFxu9d8GW"],\n ["158.69.23.120:31245", "N12B7LqdyVVBXr8TMygU28R7JYxUR2dsLLp63YXtH9XAR1R2NUrY"],\n ["198.27.74.5:31245", "N1FoYxXoSC39ZamAvwi7srz3oRrJ8JC3EvRhcqXPCD7vaQZTHKV"],\n ["51.75.60.228:31245", "N1nRDdGq7DFD7AvSz5pgAsXCvkcqoL5Xf3kHr8Yd3TTUgtBcBun"],\n ["[2001:41d0:1004:67::]:31245", "N16noomm9akwBSTkvhs4KX6kjbhVhYkLqrzneCwBdo2SUE8axHx"],\n ["[2001:41d0:a:7f7d::]:31245", "N12bYghvuhCuQ38iSAGQvKTb1iXtwzPZhNJLhWQPYcmgz8PDPAGo"],\n ["[2001:41d0:602:21e4::]:31245", "N1nRDdGq7DFD7AvSz5pgAsXCvkcqoL5Xf3kHr8Yd3TTUgtBcBun"],\n ]\n # force the bootstrap protocol to use: "IPv4", "IPv6", or "Both". Defaults to using both protocols.\n bootstrap_protocol = "Both"\n # path to the bootstrap whitelist file. This whitelist define IPs that can bootstrap on your node.\n bootstrap_whitelist_path = "base_config/bootstrap_whitelist.json"\n # path to the bootstrap blacklist file. This whitelist define IPs that will not be able to bootstrap on your node. This list is optional.\n bootstrap_blacklist_path = "base_config/bootstrap_blacklist.json"\n # [optional] port on which to listen for incoming bootstrap requests. You may need to change this to "0.0.0.0:port" if IPv6 is disabled system-wide.\n bind = "[::]:31245"\n # timeout to establish a bootstrap connection\n connect_timeout = 15000\n # timeout for providing the bootstrap to a connection\n bootstrap_timeout = 600000 # 10 mins\n # delay in milliseconds to wait between consecutive bootstrap attempts\n retry_delay = 60000\n # if ping is too high bootstrap will be interrupted after max_ping milliseconds\n max_ping = 10000\n # timeout for incoming message readout\n read_timeout = 30000\n # timeout for message sending\n write_timeout = 30000\n # timeout for incoming error message readout\n read_error_timeout = 200\n # timeout for message error sending\n write_error_timeout = 200\n # max allowed difference between client and servers clocks in ms\n max_clock_delta = 5000\n # [server] data is cached for cache duration milliseconds\n cache_duration = 15000\n # max number of simulataneous bootstraps for server\n max_simultaneous_bootstraps = 2\n # max size of recently bootstrapped IP cache\n ip_list_max_size = 10000\n # refuse consecutive bootstrap attempts from a given IP when the interval between them is lower than per_ip_min_interval milliseconds\n per_ip_min_interval = 180000\n # read-write limitation for a connection in bytes per seconds (about the bootstrap specifically)\n rate_limit = 20_971_520 # 20 MiB /sec\n\n[pool]\n # max number of operations kept in the pool\n max_operation_pool_size = 500000\n # max excess number of operations kept in pool in-between refreshes\n max_operation_pool_excess_items = 100000\n # refresh interval of the operation pool scoring (milliseconds)\n operation_pool_refresh_interval = 5000\n # if an operation is too much in the future it will be ignored (milliseconds)\n operation_max_future_start_delay = 50000\n # max number of endorsements kept per thread\n max_endorsements_pool_size_per_thread = 25000\n # max number of items returned per query\n max_item_return_count = 100\n # endorsements channel capacity\n broadcast_endorsements_channel_capacity = 2000\n # operations channel capacity\n broadcast_operations_channel_capacity = 5000\n\n\n[selector]\n # path to the initial roll distribution\n initial_rolls_path = "base_config/initial_rolls.json"\n\n[factory]\n # initial delay in milliseconds to wait before starting production to avoid double staking on node restart\n initial_delay = 100\n # path to your staking wallets\n staking_wallet_path = "config/staking_wallets"\n # stop or not the production in case we are not connected to anyone\n stop_production_when_zero_connections = true\n\n[versioning]\n # Warn user to update its node if we reach this percentage for announced network versions\n mip_stats_warn_announced_version = 30\n\n'))),(0,o.kt)(r.Z,{value:"buildnet",label:"\ud83d\udc77 BuildNet",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[logging]\nlevel = 2\n\n[api]\ndraw_lookahead_period_count = 10\nbind_private = "127.0.0.1:33034"\nbind_public = "0.0.0.0:33035"\nbind_api = "0.0.0.0:33036"\nmax_arguments = 128\nopenrpc_spec_path = "base_config/openrpc.json"\nmax_request_body_size = 52428800\nmax_response_body_size = 52428800\nmax_connections = 100\nmax_subscriptions_per_connection = 100\nmax_log_length = 4096\nallow_hosts = []\nbatch_request_limit = 16\nping_interval = 60000\nenable_http = true\nenable_ws = true\nenable_broadcast = false\n\n[execution]\nmax_final_events = 10000\nreadonly_queue_length = 10\ncursor_delay = 2000\nstats_time_window_duration = 60000\nmax_read_only_gas = 4294967295\nabi_gas_costs_file = "base_config/gas_costs/abi_gas_costs.json"\nwasm_gas_costs_file = "base_config/gas_costs/wasm_gas_costs.json"\nhd_cache_path = "storage/cache/rocks_db"\nlru_cache_size = 200\nhd_cache_size = 2000\nsnip_amount = 10\nbroadcast_slot_execution_output_channel_capacity = 5000\n\n[ledger]\ninitial_ledger_path = "base_config/initial_ledger.json"\ndisk_ledger_path = "storage/ledger/rocks_db"\nfinal_history_length = 100\ninitial_deferred_credits_path = "base_config/deferred_credits.json"\n\n[consensus]\nmax_discarded_blocks = 100\nmax_future_processing_blocks = 400\nmax_dependency_blocks = 2048\nforce_keep_final_periods_without_ops = 32\nforce_keep_final_periods = 5\nblock_db_prune_interval = 5000\nstats_timespan = 60000\nbroadcast_blocks_headers_channel_capacity = 128\nbroadcast_blocks_channel_capacity = 128\nbroadcast_filled_blocks_channel_capacity = 128\n\n[protocol]\nbind = "[::]:31244"\nconnect_timeout = 3000\nkeypair_file = "config/node_privkey.key"\ninitial_peers_file = "base_config/initial_peers.json"\nread_write_limit_bytes_per_second = 2000000000\nmessage_timeout = 5000\ntester_timeout = 10000\nask_block_timeout = 10000\nmax_blocks_kept_for_propagation = 300\nmax_block_propagation_time = 40000\nblock_propagation_tick = 1000\nmax_known_blocks_size = 1024\nmax_node_known_blocks_size = 1024\nmax_node_wanted_blocks_size = 1024\nmax_simultaneous_ask_blocks_per_node = 128\nmax_send_wait = 0\nmax_known_ops_size = 1000000\nasked_operations_buffer_capacity = 600000\nmax_node_known_ops_size = 200000\nmax_known_endorsements_size = 2048\nmax_node_known_endorsements_size = 2048\noperation_batch_buffer_capacity = 10024\noperation_announcement_buffer_capacity = 2000\noperation_batch_proc_period = 500\noperation_announcement_interval = 300\nmax_operations_per_message = 5000\ntry_connection_timer = 250\ntry_connection_timer_same_peer = 10000\nunban_everyone_timer = 86400000\ntimeout_connection = 1000\nmax_ops_kept_for_propagation = 320000\nmax_operations_propagation_time = 32000\nmax_endorsements_propagation_time = 32000\nthread_tester_count = 25\nmax_in_connections = 250\ntest_oldest_peer_cooldown = 720000\nrate_limit = 5242880\n\n[network]\n\n[metrics]\nenabled = true\nbind = "[::]:31248"\ntick_delay = 5000\n\n[bootstrap]\nbootstrap_list = [ [ "149.202.84.7:31245", "N1kKfgrCveVnosUkxTzaBw5cf9f2cbTvK3R5Ssb2Pf76au8xwmH",], [ "149.202.84.39:31245", "N12sNdL7YwSawpnJrk9XCWDjKbgfNamAobp62AX5qfkgpBkGh2wC",], [ "37.187.156.118:31245", "N1NnuSW48GKGaYZamAVKXfXbbnt3StxWoHpYtBZSJvY9e8U1BTC",],]\nbootstrap_protocol = "Both"\nbootstrap_whitelist_path = "base_config/bootstrap_whitelist.json"\nbootstrap_blacklist_path = "base_config/bootstrap_blacklist.json"\nbind = "[::]:31245"\nconnect_timeout = 15000\nbootstrap_timeout = 600000\nretry_delay = 60000\nmax_ping = 10000\nread_timeout = 30000\nwrite_timeout = 30000\nread_error_timeout = 200\nwrite_error_timeout = 200\nmax_clock_delta = 5000\ncache_duration = 15000\nmax_simultaneous_bootstraps = 2\nip_list_max_size = 10000\nper_ip_min_interval = 1000\nrate_limit = 20971520\n\n[pool]\nmax_operation_pool_size = 500000\nmax_operation_pool_excess_items = 100000\noperation_pool_refresh_interval = 5000\noperation_max_future_start_delay = 50000\nmax_endorsements_pool_size_per_thread = 25000\nmax_item_return_count = 100\nbroadcast_endorsements_channel_capacity = 2000\nbroadcast_operations_channel_capacity = 5000\n\n[selector]\ninitial_rolls_path = "base_config/initial_rolls.json"\n\n[factory]\ninitial_delay = 100\nstaking_wallet_path = "config/staking_wallets"\nstop_production_when_zero_connections = true\n\n[versioning]\nmip_stats_warn_announced_version = 30\n\n[grpc.public]\nenabled = true\naccept_http1 = false\nenable_cors = false\nenable_health = true\nenable_reflection = true\nenable_tls = false\nenable_mtls = false\ngenerate_self_signed_certificates = true\nsubject_alt_names = []\nbind = "0.0.0.0:33037"\naccept_compressed = "Gzip"\nsend_compressed = "Gzip"\nmax_decoding_message_size = 52428800\nmax_encoding_message_size = 52428800\nmax_channel_size = 128\ntimeout = 60\nmax_frame_size = 16384\nconcurrency_limit_per_connection = 100\nmax_concurrent_streams = 100\nmax_arguments = 128\ntcp_nodelay = true\ndraw_lookahead_period_count = 10\nmax_addresses_per_request = 50\nmax_slot_ranges_per_request = 50\nmax_block_ids_per_request = 50\nmax_endorsement_ids_per_request = 100\nmax_operation_ids_per_request = 250\nmax_datastore_entries_per_request = 128\nmax_filters_per_request = 32\nmax_query_items_per_request = 128\ncertificate_authority_root_path = "config/tls_public_ca.pem"\nserver_certificate_path = "config/tls_public_server.pem"\nserver_private_key_path = "config/tls_public_server.key"\nclient_certificate_authority_root_path = "config/tls_public_client_ca.pem"\nclient_certificate_path = "../massa-client/config/tls_public_client.pem"\nclient_private_key_path = "../massa-client/config/tls_public_client.key"\n\n[grpc.private]\nenabled = true\naccept_http1 = false\nenable_cors = false\nenable_health = true\nenable_reflection = true\nenable_tls = false\nenable_mtls = true\ngenerate_self_signed_certificates = true\nsubject_alt_names = []\nbind = "127.0.0.1:33038"\naccept_compressed = "Gzip"\nsend_compressed = "Gzip"\nmax_decoding_message_size = 52428800\nmax_encoding_message_size = 52428800\nmax_channel_size = 128\ntimeout = 60\nmax_frame_size = 16384\nconcurrency_limit_per_connection = 100\nmax_concurrent_streams = 100\nmax_arguments = 128\ntcp_nodelay = true\ndraw_lookahead_period_count = 10\nmax_addresses_per_request = 50\nmax_slot_ranges_per_request = 50\nmax_block_ids_per_request = 50\nmax_endorsement_ids_per_request = 100\nmax_operation_ids_per_request = 250\nmax_datastore_entries_per_request = 128\nmax_filters_per_request = 32\nmax_query_items_per_request = 128\ncertificate_authority_root_path = "config/tls_private_ca.pem"\nserver_certificate_path = "config/tls_private_server.pem"\nserver_private_key_path = "config/tls_private_server.key"\nclient_certificate_authority_root_path = "config/tls_private_client_ca.pem"\nclient_certificate_path = "../massa-client/config/tls_private_client.pem"\nclient_private_key_path = "../massa-client/config/tls_private_client.key"\n\n[protocol.default_category_info]\ntarget_out_connections = 10\nmax_in_connections_per_ip = 2\nmax_in_connections = 15\nallow_local_peers = false\n\n[protocol.peers_categories.Bootstrap]\ntarget_out_connections = 1\nmax_in_connections_per_ip = 1\nmax_in_connections = 1\nallow_local_peers = false\n\n')))),(0,o.kt)("h2",{id:"client-configuration"},"Client configuration"),(0,o.kt)("p",null,"You can override the default configuration via\nthe ",(0,o.kt)("inlineCode",{parentName:"p"},"massa-client/config/config.toml")," file."),(0,o.kt)(i.Z,{mdxType:"Tabs"},(0,o.kt)(r.Z,{value:"mainnet",label:"\ud83d\udda5 MainNet",default:!0,mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'history = 10\nhistory_file_path = "config/.massa_history"\ntimeout = 1000\n\n[default_node]\n# The IP of your node. Works both with IPv4 (like 127.0.0.1) and IPv6 (like ::1) addresses, if the node is bound to the correct protocol.\nip = "127.0.0.1"\nprivate_port = 33034\npublic_port = 33035\ngrpc_public_port = 33037\ngrpc_private_port = 33038\n# Chain id for MainNet, please update to match the target node chain id\nchain_id = 77658377\n\n[client]\n # maximum size in bytes of a request. Defaults to 50MB\n max_request_body_size = 52428800\n # request timeout\n request_timeout = 60000\n # maximum number of outcoming connections allowed\n max_concurrent_requests = 100\n # certificate_store, `Native` or `WebPki`\n certificate_store = "Native"\n # JSON-RPC request object id data type, `String` or `Number`\n id_kind = "Number"\n # max length for logging for requests and responses. Logs bigger than this limit will be truncated\n max_log_length = 4096\n # custom headers passed to the server with every request (default is empty).\n headers = []\n\n [client.http]\n # whether to enable HTTP.\n enabled = true\n\n'))),(0,o.kt)(r.Z,{value:"buildnet",label:"\ud83d\udc77 BuildNet",mdxType:"TabItem"},(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'history = 10\nhistory_file_path = "config/.massa_history"\ntimeout = 1000\n\n[default_node]\n# The IP of your node. Works both with IPv4 (like 127.0.0.1) and IPv6 (like ::1) addresses, if the node is bound to the correct protocol.\nip = "127.0.0.1"\nprivate_port = 33034\npublic_port = 33035\ngrpc_public_port = 33037\ngrpc_private_port = 33038\n# Chain id for BuildNet, please update to match the target node chain id\nchain_id = 77658366\n\n[client]\n # maximum size in bytes of a request. Defaults to 50MB\n max_request_body_size = 52428800\n # request timeout\n request_timeout = 60000\n # maximum number of outcoming connections allowed\n max_concurrent_requests = 100\n # certificate_store, `Native` or `WebPki`\n certificate_store = "Native"\n # JSON-RPC request object id data type, `String` or `Number`\n id_kind = "Number"\n # max length for logging for requests and responses. Logs bigger than this limit will be truncated\n max_log_length = 4096\n # custom headers passed to the server with every request (default is empty).\n headers = []\n\n [client.http]\n # whether to enable HTTP.\n enabled = true\n\n')))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2e7e0665.787d2ced.js b/assets/js/2e7e0665.787d2ced.js deleted file mode 100644 index 3c5f702fc..000000000 --- a/assets/js/2e7e0665.787d2ced.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[4266],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>b});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var s=r.createContext({}),l=function(e){var t=r.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=l(e.components);return r.createElement(s.Provider,{value:t},e.children)},d="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),d=l(a),u=n,b=d["".concat(s,".").concat(u)]||d[u]||m[u]||o;return a?r.createElement(b,i(i({ref:t},p),{},{components:a})):r.createElement(b,i({ref:t},p))}));function b(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=u;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[d]="string"==typeof e?e:n,i[1]=c;for(var l=2;l{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>m,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=a(7462),n=(a(7294),a(3905));const o={id:"browse-decentralized-application",title:"Browse Decentralized Application"},i=void 0,c={unversionedId:"massaStation/browse-decentralized-application",id:"massaStation/browse-decentralized-application",title:"Browse Decentralized Application",description:"Browse Decentralized Application",source:"@site/docs/massaStation/browse-decentralized-application.mdx",sourceDirName:"massaStation",slug:"/massaStation/browse-decentralized-application",permalink:"/docs/massaStation/browse-decentralized-application",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/massaStation/browse-decentralized-application.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"browse-decentralized-application",title:"Browse Decentralized Application"},sidebar:"massaStationSidebar",previous:{title:"Account Restore",permalink:"/docs/massaStation/massa-wallet/account-restore"},next:{title:"FAQ",permalink:"/docs/massaStation/faq"}},s={},l=[{value:"Browse Decentralized Application",id:"browse-decentralized-application",level:2},{value:"Browsing Steps",id:"browsing-steps",level:3}],p={toc:l},d="wrapper";function m(e){let{components:t,...o}=e;return(0,n.kt)(d,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h2",{id:"browse-decentralized-application"},"Browse Decentralized Application"),(0,n.kt)("p",null,(0,n.kt)("em",{parentName:"p"},"Massa Station")," enables you to browse decentralized applications (dApps) hosted on the blockchain and interact with them."),(0,n.kt)("h3",{id:"browsing-steps"},"Browsing Steps"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"Open ",(0,n.kt)("em",{parentName:"li"},"Massa Station"),"."),(0,n.kt)("li",{parentName:"ol"},"Click on the ",(0,n.kt)("strong",{parentName:"li"},"Search Massa ecosystem")," button.")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Search Massa ecosystem",src:a(8608).Z,width:"2000",height:"987"})),(0,n.kt)("ol",{start:3},(0,n.kt)("li",{parentName:"ol"},"Search for the website you want to browse.")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Scroll websites",src:a(3328).Z,width:"2000",height:"1006"})),(0,n.kt)("ol",{start:4},(0,n.kt)("li",{parentName:"ol"},"Click on it to open it in your web browser.")))}m.isMDXComponent=!0},3328:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/browse-decentralized-application_scroll-395bf1a6228c163add620c5ce65325c9.png"},8608:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/browse-decentralized-application_search_ecosystem-88e7a14cc85f17dca757ca6c59cc2b9b.png"}}]); \ No newline at end of file diff --git a/assets/js/2e7e0665.fc80f398.js b/assets/js/2e7e0665.fc80f398.js new file mode 100644 index 000000000..7393ab4e7 --- /dev/null +++ b/assets/js/2e7e0665.fc80f398.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[4266],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>b});var r=a(7294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function i(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var c=r.createContext({}),l=function(e){var t=r.useContext(c),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},p=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(a),m=n,b=d["".concat(c,".").concat(m)]||d[m]||u[m]||o;return a?r.createElement(b,i(i({ref:t},p),{},{components:a})):r.createElement(b,i({ref:t},p))}));function b(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,i=new Array(o);i[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[d]="string"==typeof e?e:n,i[1]=s;for(var l=2;l{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var r=a(7462),n=(a(7294),a(3905));const o={id:"browse-decentralized-application",title:"Browse Decentralized Application"},i=void 0,s={unversionedId:"massaStation/browse-decentralized-application",id:"massaStation/browse-decentralized-application",title:"Browse Decentralized Application",description:"Browse Decentralized Application",source:"@site/docs/massaStation/browse-decentralized-application.mdx",sourceDirName:"massaStation",slug:"/massaStation/browse-decentralized-application",permalink:"/docs/massaStation/browse-decentralized-application",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/massaStation/browse-decentralized-application.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"browse-decentralized-application",title:"Browse Decentralized Application"},sidebar:"massaStationSidebar",previous:{title:"Account Restore",permalink:"/docs/massaStation/massa-wallet/account-restore"},next:{title:"FAQ",permalink:"/docs/massaStation/faq"}},c={},l=[{value:"Browse Decentralized Application",id:"browse-decentralized-application",level:2},{value:"Browsing Steps",id:"browsing-steps",level:3}],p={toc:l},d="wrapper";function u(e){let{components:t,...o}=e;return(0,n.kt)(d,(0,r.Z)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h2",{id:"browse-decentralized-application"},"Browse Decentralized Application"),(0,n.kt)("p",null,(0,n.kt)("em",{parentName:"p"},"Massa Station")," enables you to browse decentralized applications (dApps) hosted on the blockchain and interact with them."),(0,n.kt)("h3",{id:"browsing-steps"},"Browsing Steps"),(0,n.kt)("ol",null,(0,n.kt)("li",{parentName:"ol"},"Open ",(0,n.kt)("em",{parentName:"li"},"Massa Station"),"."),(0,n.kt)("li",{parentName:"ol"},"Click on the ",(0,n.kt)("strong",{parentName:"li"},"Search Massa ecosystem")," button.")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Search Massa ecosystem",src:a(8608).Z,width:"2000",height:"987"})),(0,n.kt)("ol",{start:3},(0,n.kt)("li",{parentName:"ol"},"Search for the website you want to browse.")),(0,n.kt)("p",null,(0,n.kt)("img",{alt:"Scroll websites",src:a(3328).Z,width:"2000",height:"1006"})),(0,n.kt)("ol",{start:4},(0,n.kt)("li",{parentName:"ol"},"Click on it to open it in your web browser.")))}u.isMDXComponent=!0},3328:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/browse-decentralized-application_scroll-395bf1a6228c163add620c5ce65325c9.png"},8608:(e,t,a)=>{a.d(t,{Z:()=>r});const r=a.p+"assets/images/browse-decentralized-application_search_ecosystem-88e7a14cc85f17dca757ca6c59cc2b9b.png"}}]); \ No newline at end of file diff --git a/assets/js/31043fb2.6b93b161.js b/assets/js/31043fb2.e5aac349.js similarity index 56% rename from assets/js/31043fb2.6b93b161.js rename to assets/js/31043fb2.e5aac349.js index 6bef3cae1..dfe509a8e 100644 --- a/assets/js/31043fb2.6b93b161.js +++ b/assets/js/31043fb2.e5aac349.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[4764],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>m});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function s(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},b=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,s=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=c(a),b=r,m=p["".concat(l,".").concat(b)]||p[b]||d[b]||s;return a?n.createElement(m,o(o({ref:t},u),{},{components:a})):n.createElement(m,o({ref:t},u))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=a.length,o=new Array(s);o[0]=b;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:r,o[1]=i;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var n=a(7462),r=(a(7294),a(3905));const s={id:"backend-usage-massa-web3",title:"Backend Usage"},o=void 0,i={unversionedId:"build/massa-web3/backend-usage-massa-web3",id:"build/massa-web3/backend-usage-massa-web3",title:"Backend Usage",description:"If you need to interact with the Massa network for your backend, you can use the Massa Web3 API without the wallet provider.",source:"@site/docs/build/massa-web3/backend-usage-massa-web3.mdx",sourceDirName:"build/massa-web3",slug:"/build/massa-web3/backend-usage-massa-web3",permalink:"/docs/build/massa-web3/backend-usage-massa-web3",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/massa-web3/backend-usage-massa-web3.mdx",tags:[],version:"current",lastUpdatedBy:"Damir Vodenicarevic",lastUpdatedAt:1707293576,formattedLastUpdatedAt:"Feb 7, 2024",frontMatter:{id:"backend-usage-massa-web3",title:"Backend Usage"},sidebar:"buildSidebar",previous:{title:"dApp Usage",permalink:"/docs/build/massa-web3/dapp-usage-massa-web3"},next:{title:"Utils",permalink:"/docs/build/massa-web3/massa-web3-utils"}},l={},c=[{value:"Wallet & Account Management",id:"wallet--account-management",level:2},{value:"Private and Public API",id:"private-and-public-api",level:2}],u={toc:c},p="wrapper";function d(e){let{components:t,...a}=e;return(0,r.kt)(p,(0,n.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"If you need to interact with the Massa network for your backend, you can use the Massa Web3 API without the wallet provider.\nInitialization of the client is shown in the ",(0,r.kt)("a",{parentName:"p",href:"/docs/build/massa-web3#without-wallet-provider"},"introduction"),"\nof the Massa Web3."),(0,r.kt)("h2",{id:"wallet--account-management"},"Wallet & Account Management"),(0,r.kt)("p",null,"The Wallet API provides a range of methods for creating or importing an account, getting account information, sending transactions, signing\nmessages, etc."),(0,r.kt)("p",null,"A ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/massalabs/massa-web3/blob/main/packages/massa-web3/examples/wallet/index.ts"},"complete example")," of how to use the Wallet\nAPI is also available."),(0,r.kt)("p",null,"You can also find the full typescript documentation ",(0,r.kt)("a",{parentName:"p",href:"https://web3.docs.massa.net/classes/WalletClient.html"},"here"),"."),(0,r.kt)("h2",{id:"private-and-public-api"},"Private and Public API"),(0,r.kt)("p",null,"All the operations needed to manage a node are available through the private API. The corresponding Typescript documentation can be found ",(0,r.kt)("a",{parentName:"p",href:"https://web3.docs.massa.net/classes/PrivateApiClient.html"},"here"),"."),(0,r.kt)("p",null,"Reading the state of the blockchain can be done through the public API. The corresponding Typescript documentation can be found\n",(0,r.kt)("a",{parentName:"p",href:"https://web3.docs.massa.net/classes/PublicApiClient.html"},"here"),"."))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[4764],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>m});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function s(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),c=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},u=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},b=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,s=e.originalType,l=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),p=c(a),b=r,m=p["".concat(l,".").concat(b)]||p[b]||d[b]||s;return a?n.createElement(m,o(o({ref:t},u),{},{components:a})):n.createElement(m,o({ref:t},u))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=a.length,o=new Array(s);o[0]=b;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:r,o[1]=i;for(var c=2;c{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var n=a(7462),r=(a(7294),a(3905));const s={id:"backend-usage-massa-web3",title:"Backend Usage"},o=void 0,i={unversionedId:"build/massa-web3/backend-usage-massa-web3",id:"build/massa-web3/backend-usage-massa-web3",title:"Backend Usage",description:"If you need to interact with the Massa network for your backend, you can use the Massa Web3 API without the wallet provider.",source:"@site/docs/build/massa-web3/backend-usage-massa-web3.mdx",sourceDirName:"build/massa-web3",slug:"/build/massa-web3/backend-usage-massa-web3",permalink:"/docs/build/massa-web3/backend-usage-massa-web3",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/massa-web3/backend-usage-massa-web3.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"backend-usage-massa-web3",title:"Backend Usage"},sidebar:"buildSidebar",previous:{title:"dApp Usage",permalink:"/docs/build/massa-web3/dapp-usage-massa-web3"},next:{title:"Utils",permalink:"/docs/build/massa-web3/massa-web3-utils"}},l={},c=[{value:"Wallet & Account Management",id:"wallet--account-management",level:2},{value:"Private and Public API",id:"private-and-public-api",level:2}],u={toc:c},p="wrapper";function d(e){let{components:t,...a}=e;return(0,r.kt)(p,(0,n.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"If you need to interact with the Massa network for your backend, you can use the Massa Web3 API without the wallet provider.\nInitialization of the client is shown in the ",(0,r.kt)("a",{parentName:"p",href:"/docs/build/massa-web3#without-wallet-provider"},"introduction"),"\nof the Massa Web3."),(0,r.kt)("h2",{id:"wallet--account-management"},"Wallet & Account Management"),(0,r.kt)("p",null,"The Wallet API provides a range of methods for creating or importing an account, getting account information, sending transactions, signing\nmessages, etc."),(0,r.kt)("p",null,"A ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/massalabs/massa-web3/blob/main/packages/massa-web3/examples/wallet/index.ts"},"complete example")," of how to use the Wallet\nAPI is also available."),(0,r.kt)("p",null,"You can also find the full typescript documentation ",(0,r.kt)("a",{parentName:"p",href:"https://web3.docs.massa.net/classes/WalletClient.html"},"here"),"."),(0,r.kt)("h2",{id:"private-and-public-api"},"Private and Public API"),(0,r.kt)("p",null,"All the operations needed to manage a node are available through the private API. The corresponding Typescript documentation can be found ",(0,r.kt)("a",{parentName:"p",href:"https://web3.docs.massa.net/classes/PrivateApiClient.html"},"here"),"."),(0,r.kt)("p",null,"Reading the state of the blockchain can be done through the public API. The corresponding Typescript documentation can be found\n",(0,r.kt)("a",{parentName:"p",href:"https://web3.docs.massa.net/classes/PublicApiClient.html"},"here"),"."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/330b5f37.1715192e.js b/assets/js/330b5f37.1715192e.js new file mode 100644 index 000000000..ca1e09b7f --- /dev/null +++ b/assets/js/330b5f37.1715192e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocu_dev=self.webpackChunkdocu_dev||[]).push([[4956],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>b});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var o=n.createContext({}),c=function(e){var t=n.useContext(o),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},u=function(e){var t=c(e.components);return n.createElement(o.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,l=e.originalType,o=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),d=c(a),m=r,b=d["".concat(o,".").concat(m)]||d[m]||p[m]||l;return a?n.createElement(b,i(i({ref:t},u),{},{components:a})):n.createElement(b,i({ref:t},u))}));function b(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=a.length,i=new Array(l);i[0]=m;var s={};for(var o in t)hasOwnProperty.call(t,o)&&(s[o]=t[o]);s.originalType=e,s[d]="string"==typeof e?e:r,i[1]=s;for(var c=2;c{a.d(t,{Z:()=>i});var n=a(7294),r=a(6010);const l={tabItem:"tabItem_Ymn6"};function i(e){let{children:t,hidden:a,className:i}=e;return n.createElement("div",{role:"tabpanel",className:(0,r.Z)(l.tabItem,i),hidden:a},t)}},4866:(e,t,a)=>{a.d(t,{Z:()=>k});var n=a(7462),r=a(7294),l=a(6010),i=a(2466),s=a(6550),o=a(1980),c=a(7392),u=a(12);function d(e){return function(e){return r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:t,label:a,attributes:n,default:r}}=e;return{value:t,label:a,attributes:n,default:r}}))}function p(e){const{values:t,children:a}=e;return(0,r.useMemo)((()=>{const e=t??d(a);return function(e){const t=(0,c.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,a])}function m(e){let{value:t,tabValues:a}=e;return a.some((e=>e.value===t))}function b(e){let{queryString:t=!1,groupId:a}=e;const n=(0,s.k6)(),l=function(e){let{queryString:t=!1,groupId:a}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!a)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return a??null}({queryString:t,groupId:a});return[(0,o._X)(l),(0,r.useCallback)((e=>{if(!l)return;const t=new URLSearchParams(n.location.search);t.set(l,e),n.replace({...n.location,search:t.toString()})}),[l,n])]}function h(e){const{defaultValue:t,queryString:a=!1,groupId:n}=e,l=p(e),[i,s]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:a}=e;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:a}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${a.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=a.find((e=>e.default))??a[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:l}))),[o,c]=b({queryString:a,groupId:n}),[d,h]=function(e){let{groupId:t}=e;const a=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,l]=(0,u.Nk)(a);return[n,(0,r.useCallback)((e=>{a&&l.set(e)}),[a,l])]}({groupId:n}),f=(()=>{const e=o??d;return m({value:e,tabValues:l})?e:null})();(0,r.useLayoutEffect)((()=>{f&&s(f)}),[f]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);s(e),c(e),h(e)}),[c,h,l]),tabValues:l}}var f=a(2389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};function y(e){let{className:t,block:a,selectedValue:s,selectValue:o,tabValues:c}=e;const u=[],{blockElementScrollPositionUntilNextRender:d}=(0,i.o5)(),p=e=>{const t=e.currentTarget,a=u.indexOf(t),n=c[a].value;n!==s&&(d(t),o(n))},m=e=>{let t=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{const a=u.indexOf(e.currentTarget)+1;t=u[a]??u[0];break}case"ArrowLeft":{const a=u.indexOf(e.currentTarget)-1;t=u[a]??u[u.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":a},t)},c.map((e=>{let{value:t,label:a,attributes:i}=e;return r.createElement("li",(0,n.Z)({role:"tab",tabIndex:s===t?0:-1,"aria-selected":s===t,key:t,ref:e=>u.push(e),onKeyDown:m,onClick:p},i,{className:(0,l.Z)("tabs__item",v.tabItem,i?.className,{"tabs__item--active":s===t})}),a??t)})))}function w(e){let{lazy:t,children:a,selectedValue:n}=e;const l=(Array.isArray(a)?a:[a]).filter(Boolean);if(t){const e=l.find((e=>e.props.value===n));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},l.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function g(e){const t=h(e);return r.createElement("div",{className:(0,l.Z)("tabs-container",v.tabList)},r.createElement(y,(0,n.Z)({},e,t)),r.createElement(w,(0,n.Z)({},e,t)))}function k(e){const t=(0,f.Z)();return r.createElement(g,(0,n.Z)({key:String(t)},e))}},3436:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>u,contentTitle:()=>o,default:()=>b,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var n=a(7462),r=(a(7294),a(3905)),l=a(4866),i=a(5162);const s={id:"massa-web3-main",title:"Introduction"},o="Leveraging Javascript API for Massa interaction",c={unversionedId:"build/massa-web3/massa-web3-main",id:"build/massa-web3/massa-web3-main",title:"Introduction",description:"What is Massa-Web3?",source:"@site/docs/build/massa-web3/massa-web3.mdx",sourceDirName:"build/massa-web3",slug:"/build/massa-web3/",permalink:"/docs/build/massa-web3/",draft:!1,editUrl:"https://github.com/massalabs/docs/tree/main/docs/build/massa-web3/massa-web3.mdx",tags:[],version:"current",lastUpdatedBy:"BenRey",lastUpdatedAt:1707481750,formattedLastUpdatedAt:"Feb 9, 2024",frontMatter:{id:"massa-web3-main",title:"Introduction"},sidebar:"buildSidebar",previous:{title:"Community Wallets",permalink:"/docs/build/wallet/community-wallets"},next:{title:"dApp Usage",permalink:"/docs/build/massa-web3/dapp-usage-massa-web3"}},u={},d=[{value:"What is Massa-Web3?",id:"what-is-massa-web3",level:2},{value:"Installation",id:"installation",level:2},{value:"Requirements",id:"requirements",level:3},{value:"As a library (Node.js/React/Vue.js)",id:"as-a-library-nodejsreactvuejs",level:3},{value:"In a browser",id:"in-a-browser",level:3},{value:"Initialization",id:"initialization",level:2},{value:"With Wallet-provider",id:"with-wallet-provider",level:3},{value:"Without Wallet-provider",id:"without-wallet-provider",level:3},{value:"Client exposed APIs",id:"client-exposed-apis",level:3}],p={toc:d},m="wrapper";function b(e){let{components:t,...a}=e;return(0,r.kt)(m,(0,n.Z)({},p,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"leveraging-javascript-api-for-massa-interaction"},"Leveraging Javascript API for Massa interaction"),(0,r.kt)("h2",{id:"what-is-massa-web3"},"What is Massa-Web3?"),(0,r.kt)("p",null,"Massa-web3 is an exhaustive library enabling interaction with the Massa blockchain. It can be used in a browser environment and Node.js runtime."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Massa-web3 operates by utilizing JsonRPC API in the background to facilitate blockchain communication. The API is divided into a Private and a Public segment, used for node management and blockchain interactions, respectively. For more information on the API, please refer to the ",(0,r.kt)("a",{parentName:"p",href:"/docs/build/api/jsonrpc"},"JsonRPC API documentation"),".")),(0,r.kt)("p",null,"Massa-web3 will allow you to interact with the Massa blockchain in a variety of ways:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Send transactions"),(0,r.kt)("li",{parentName:"ul"},"Deploy smart contracts"),(0,r.kt)("li",{parentName:"ul"},"Create, manage and inspect addresses"),(0,r.kt)("li",{parentName:"ul"},"Manage your node"),(0,r.kt)("li",{parentName:"ul"},"Fetch events from the blockchain"),(0,r.kt)("li",{parentName:"ul"},"And much more!")),(0,r.kt)("p",null,"In addition, the library includes a ",(0,r.kt)("a",{parentName:"p",href:"/docs/build/massa-web3/massa-web3-utils"},"collection of handy utility functions")," (e.g conversion between different units, etc)."),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"For a quick integration of Massa within a web browser, consider reading our Web Frontend Integration Guide.")),(0,r.kt)("h2",{id:"installation"},"Installation"),(0,r.kt)("p",null,"Massa-web3 can be used as a library for frameworks or as a stand-alone bundled js file which can be easily loaded into the browser."),(0,r.kt)("h3",{id:"requirements"},"Requirements"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"NodeJS 14+"),(0,r.kt)("li",{parentName:"ul"},"npm / yarn (see package.json)")),(0,r.kt)("h3",{id:"as-a-library-nodejsreactvuejs"},"As a library (Node.js/React/Vue.js)"),(0,r.kt)("p",null,"Just install the library using npm:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-shell"},"npm install @massalabs/massa-web3\n")),(0,r.kt)("h3",{id:"in-a-browser"},"In a browser"),(0,r.kt)("p",null,"If you want to use the library in a vanilla javascript project, please add the following script tag to your html file:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-html"},'<\/script>\n')),(0,r.kt)("p",null,"whereby the x.x.x is one of the available released versions under ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/massalabs/massa-web3/releases"},"Massa-web3's releases page"),":"),(0,r.kt)("p",null,"In your code, once the script is fully loaded, just use window.massa to access all massa-web3 exports."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},'

· One min read
Sébastien Lorber
Yangshun Tay

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.

· One min read
Gao Wei

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

- + \ No newline at end of file diff --git a/blog/archive.html b/blog/archive.html index a87e10b8a..9e079b96c 100644 --- a/blog/archive.html +++ b/blog/archive.html @@ -10,13 +10,13 @@ - + - + \ No newline at end of file diff --git a/blog/first-blog-post.html b/blog/first-blog-post.html index 79ec66a8c..ee733cc93 100644 --- a/blog/first-blog-post.html +++ b/blog/first-blog-post.html @@ -10,13 +10,13 @@ - +

First Blog Post

· One min read
Gao Wei

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

- + \ No newline at end of file diff --git a/blog/long-blog-post.html b/blog/long-blog-post.html index 6138c9e13..ecb4570a4 100644 --- a/blog/long-blog-post.html +++ b/blog/long-blog-post.html @@ -10,13 +10,13 @@ - +

Long Blog Post

· 3 min read
Endilie Yacop Sucipto

This is the summary of a very long blog post,

Use a <!-- truncate --> comment to limit blog post size in the list view.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

- + \ No newline at end of file diff --git a/blog/mdx-blog-post.html b/blog/mdx-blog-post.html index 12d6d1939..214058c73 100644 --- a/blog/mdx-blog-post.html +++ b/blog/mdx-blog-post.html @@ -10,13 +10,13 @@ - +

MDX Blog Post

· One min read
Sébastien Lorber

Blog posts support Docusaurus Markdown features, such as MDX.

tip

Use the power of React to create interactive blog posts.

<button onClick={() => alert('button clicked!')}>Click me!</button>
- + \ No newline at end of file diff --git a/blog/tags.html b/blog/tags.html index 348f3b0dd..9eab375db 100644 --- a/blog/tags.html +++ b/blog/tags.html @@ -10,13 +10,13 @@ - + - + \ No newline at end of file diff --git a/blog/tags/docusaurus.html b/blog/tags/docusaurus.html index 645525133..d9728ffe7 100644 --- a/blog/tags/docusaurus.html +++ b/blog/tags/docusaurus.html @@ -10,13 +10,13 @@ - +

4 posts tagged with "docusaurus"

View All Tags

· One min read
Sébastien Lorber
Yangshun Tay

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.

· One min read
Gao Wei

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

- + \ No newline at end of file diff --git a/blog/tags/facebook.html b/blog/tags/facebook.html index 69eadb34c..751229ec9 100644 --- a/blog/tags/facebook.html +++ b/blog/tags/facebook.html @@ -10,13 +10,13 @@ - +

One post tagged with "facebook"

View All Tags

· One min read
Sébastien Lorber
Yangshun Tay

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.

- + \ No newline at end of file diff --git a/blog/tags/hello.html b/blog/tags/hello.html index 99f1e85b4..0d636c0ff 100644 --- a/blog/tags/hello.html +++ b/blog/tags/hello.html @@ -10,13 +10,13 @@ - +

2 posts tagged with "hello"

View All Tags

· One min read
Sébastien Lorber
Yangshun Tay

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.

- + \ No newline at end of file diff --git a/blog/tags/hola.html b/blog/tags/hola.html index 5b71a4502..5ef8e518a 100644 --- a/blog/tags/hola.html +++ b/blog/tags/hola.html @@ -10,13 +10,13 @@ - +

One post tagged with "hola"

View All Tags

· One min read
Gao Wei

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

- + \ No newline at end of file diff --git a/blog/welcome.html b/blog/welcome.html index 8da68b55c..efc070daf 100644 --- a/blog/welcome.html +++ b/blog/welcome.html @@ -10,13 +10,13 @@ - +

Welcome

· One min read
Sébastien Lorber
Yangshun Tay

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.

- + \ No newline at end of file diff --git a/docs/build/api/grpc.html b/docs/build/api/grpc.html index 5a9699f06..c1d988518 100644 --- a/docs/build/api/grpc.html +++ b/docs/build/api/grpc.html @@ -10,7 +10,7 @@ - + @@ -23,8 +23,8 @@ massa-proto-rs.

Code generation

Step 1: Clone massa-proto repository

git clone -b MASSA_PROTO_TAG https://github.com/massalabs/massa-proto.git --depth 1
note

If you are using an older version of the Massa node, please use the tag version or commit hash corresponding to your node version. Find all massa-proto tags here.

Step 2: Install Buf CLI

  1. Download the latest version of Buf CLI from the official website.
  2. Extract the downloaded file to a folder on your computer.
  3. Add the buf binary to your system PATH environment variable.

Step 3: Set up Buf

  1. Add the following content to buf.work.yml:
version: v1
directories:
- proto/apis
- proto/commons
- proto/third_party

By specifying the directories in the configuration file, Buf knows which [.proto]{.title-ref} files to include in the build process.

  1. Create a file called buf.gen.yml and add the following content:
version: v1
managed:
enabled: true
plugins:
- remote: buf.build/community/timostamm-protobuf-ts:v2.9.0
out: gen/ts

The configuration uses the official timostamm-protobuf-ts -plugin to generate gRPC client and classes in TypeScript.

info

For other languages check the complete list of official Buf plugins.

Step 4: Generate gRPC client/classes in TypeScript

  1. Launch the code generation:
buf generate
  1. Install the required dependencies for the generated code to your project:
npm install @protobuf-ts/runtime@^2.9.0 @protobuf-ts/runtime-rpc@^2.9.0
- +plugin to generate gRPC client and classes in TypeScript.

info

For other languages check the complete list of official Buf plugins.

Step 4: Generate gRPC client/classes in TypeScript

  1. Launch the code generation:
buf generate
  1. Install the required dependencies for the generated code to your project:
npm install @protobuf-ts/runtime@^2.9.0 @protobuf-ts/runtime-rpc@^2.9.0
+ \ No newline at end of file diff --git a/docs/build/api/jsonrpc.html b/docs/build/api/jsonrpc.html index be07e8990..5aa099975 100644 --- a/docs/build/api/jsonrpc.html +++ b/docs/build/api/jsonrpc.html @@ -10,7 +10,7 @@ - + @@ -48,8 +48,8 @@ massa-node/config/config.toml (create it if absent) with the following contents:

[api]
# whether to broadcast for blocks, endorsement and operations
enable_broadcast = true
# whether to enable WS.
enable_ws = true

Postman brings support for WebSocket APIs, more information about it here.

image

  • run the massa node
  • connect to ws://localhost:33036
  • send the request message:
{
"jsonrpc": "2.0",
"id": 1,
"method": "subscribe_new_filled_blocks",
"params": []
}
  • If the request succeed, the response will contains a subscription id:
{
"jsonrpc": "2.0",
"result": 3508678639232691,
"id": 1
}
  • Result:
{
"jsonrpc": "2.0",
"method": "new_filled_blocks",
"params": {
"subscription": 3508678639232691,
"result": "FILLED_BLOCK_CONTENT_0"
}
}
  • A message is received everytime a filled block is produced:
{
"jsonrpc": "2.0",
"method": "new_filled_blocks",
"params": {
"subscription": 3508678639232691,
"result": "FILLED_BLOCK_CONTENT_N"
}
}
  • unsubscribe and stop receiving new filled blocks:
{
"jsonrpc": "2.0",
"id": 1,
"method": "unsubscribe_new_filled_blocks",
"params": [
3508678639232691
]
}
  • Result:
{
"jsonrpc": "2.0",
"result": true,
"id": 1
}
note

Multiple subscriptions are supported

Error codes

When a call to Massa API fails, it MUST return a valid JSON-RPC -error object.

CodeMessageMeaning
-32600Invalid requestThe JSON sent is not a valid Request object
-32601Method not foundThe method does not exist / is not available
-32602Invalid paramsInvalid method parameter(s)
-32603Internal errorInternal JSON-RPC error
-32700Parse errorInvalid JSON, parsing issue
-32000Bad requestIndicates that the server cannot or will not process the request due to something that is perceived to be a client error
-32001Internal server errorThe server encountered an unexpected issue
-32003Service UnavailableIndicates that the server is not ready to handle the request
-32004Not foundIndicates that the server cannot find the requested resource
-32005Method not allowedIndicates that the server knows the request method, but the target resource doesn't support this method
-32006Send channel errorSend channel error
-32007Receive channel errorReceive channel error
-32008Massa hash errormassa_hash error
-32009Consensus errorError from Consensus module
-32010Execution errorError from Execution module
-32012Protocol errorError from Protocol module
-32013Models errorError in Models
-32014Time errorError from Time module
-32015Wallet errorError from Wallet module
-32016Inconsistency errorInconsistency in the result of request
-32017Missing command senderMissing command sender
-32018Missing configMissing configuration
-32019Wrong APIThe wrong API (either Public or Private) was called
Example error:

{
"jsonrpc": "2.0",
"error": {
"code": -32400,
"message": "Bad request: too many arguments, maximum authorized 2 but found 3"
},
"id": 1
}

- +error object.

CodeMessageMeaning
-32600Invalid requestThe JSON sent is not a valid Request object
-32601Method not foundThe method does not exist / is not available
-32602Invalid paramsInvalid method parameter(s)
-32603Internal errorInternal JSON-RPC error
-32700Parse errorInvalid JSON, parsing issue
-32000Bad requestIndicates that the server cannot or will not process the request due to something that is perceived to be a client error
-32001Internal server errorThe server encountered an unexpected issue
-32003Service UnavailableIndicates that the server is not ready to handle the request
-32004Not foundIndicates that the server cannot find the requested resource
-32005Method not allowedIndicates that the server knows the request method, but the target resource doesn't support this method
-32006Send channel errorSend channel error
-32007Receive channel errorReceive channel error
-32008Massa hash errormassa_hash error
-32009Consensus errorError from Consensus module
-32010Execution errorError from Execution module
-32012Protocol errorError from Protocol module
-32013Models errorError in Models
-32014Time errorError from Time module
-32015Wallet errorError from Wallet module
-32016Inconsistency errorInconsistency in the result of request
-32017Missing command senderMissing command sender
-32018Missing configMissing configuration
-32019Wrong APIThe wrong API (either Public or Private) was called
Example error:

{
"jsonrpc": "2.0",
"error": {
"code": -32400,
"message": "Bad request: too many arguments, maximum authorized 2 but found 3"
},
"id": 1
}

+ \ No newline at end of file diff --git a/docs/build/api/providers.html b/docs/build/api/providers.html index 399acb847..2d334afb0 100644 --- a/docs/build/api/providers.html +++ b/docs/build/api/providers.html @@ -10,15 +10,15 @@ - +

RPC Providers

To interact with the different networks of the Massa blockchain, you can select from any of the listed providers. Be aware that the latency you encounter may vary depending on the provider's geographical location. -To enhance redundancy and facilitate load balancing, consider using multiple providers.

ProviderProtocolEndpoint URL
Massa LabsJsonRPChttps://mainnet.massa.net/api/v2
Massa LabsgRPCgrpc://mainnet.massa.net:33037
- +To enhance redundancy and facilitate load balancing, consider using multiple providers.

ProviderProtocolEndpoint URL
Massa LabsJsonRPChttps://mainnet.massa.net/api/v2
Massa LabsgRPCgrpc://mainnet.massa.net:33037
+ \ No newline at end of file diff --git a/docs/build/hello-world-dapp.html b/docs/build/hello-world-dapp.html index c5b60fbcd..30d17d29a 100644 --- a/docs/build/hello-world-dapp.html +++ b/docs/build/hello-world-dapp.html @@ -10,7 +10,7 @@ - + @@ -30,8 +30,8 @@ , we created a .env file and added a JSON_RPC_URL variable to it. This variable was the URL of a node used to deploy our smart contract to the Massa blockchain. Here we are doing something similar but instead of using a node to deploy our smart contract, we are using a node to interact with our smart contract.

We are using the DefaultProviderUrls.BUILDNET constant as our provider URL. This constant points to a node on the Massa buildnet. The boolean is a flag that indicates whether or not we want to provide an wallet account to sign transactions. Here it is set to false because we are not going to sign any transactions. Finally, we are setting the client object to the web3client state variable using the setWeb3client function, so that the web3 client is available to the rest of our application.

info

The buildnet is a test network that is used to test smart contracts before deploying them to the mainnet. It is similar to the Ethereum Sepolia network. You can learn more about Massa networks here.

  • Retrieving the Greeting
 async function funcGetGreeting() {
if (web3client) {
let res = await web3client
.publicApi()
.getDatastoreEntries([
{ address: sc_addr, key: strToBytes("greeting") },
]);
if (res[0].candidate_value) {
let greetingDecoded = bytesToStr(res[0].candidate_value);
setGreeting(greetingDecoded);
}
}
}

In the code above, we are retrieving the "Hello, World!" greeting message by directly reading the smart contract's storage.

To do so, we are using the getDatastoreEntries method. This method takes an array of DatastoreEntry objects as a parameter. Each DatastoreEntry object contains the address of the smart contract and the key of the value we want to retrieve. In our case, the address of the smart contract is the one we got during contract deployment. The key is the string "greeting" that we used to store the greeting message in the smart contract's storage. -We retrieve the current greeting from the smart contract's storage and decode it using the bytesToStr function. Finally, we set the greeting to the greeting state variable using the setGreeting function.

info

As you can see, we cannot directly use the datastore entry returned by the smart contract. Indeed, the storage of the smart contract is a key value store that stores data in bytes. Thus, we need to decode the bytes returned by the smart contract to get the actual greeting message. That is why we have to use massa-web3 bytesToStr function. You can check massa-web3 utils here.

  • User Interface

The user interface consists of a centered text display that shows the current greeting fetched from your smart contract's storage.

Testing your application

Finally, let's start our application and perform some basic user acceptance testing!

npm run start
  1. Open your web browser and navigate to http://localhost:3000
  2. Here, you should see a greeting that says "Hello, World!" This is the message that was set in your smart contract.
  3. If you're able to see this greeting, your dApp is functioning correctly.

🎉 Congratulations on building and testing your first dApp!

Remember, Rome wasn't built in a day, and neither are amazing dApps! Keep learning!

Next steps

Congratulations on writing and testing your first dApp using the Massa blockchain! You've taken a crucial step in your blockchain development journey.

There's always more to learn. To continue exploring and expanding your knowledge, you can:

- +We retrieve the current greeting from the smart contract's storage and decode it using the bytesToStr function. Finally, we set the greeting to the greeting state variable using the setGreeting function.

info

As you can see, we cannot directly use the datastore entry returned by the smart contract. Indeed, the storage of the smart contract is a key value store that stores data in bytes. Thus, we need to decode the bytes returned by the smart contract to get the actual greeting message. That is why we have to use massa-web3 bytesToStr function. You can check massa-web3 utils here.

  • User Interface

The user interface consists of a centered text display that shows the current greeting fetched from your smart contract's storage.

Testing your application

Finally, let's start our application and perform some basic user acceptance testing!

npm run start
  1. Open your web browser and navigate to http://localhost:3000
  2. Here, you should see a greeting that says "Hello, World!" This is the message that was set in your smart contract.
  3. If you're able to see this greeting, your dApp is functioning correctly.

🎉 Congratulations on building and testing your first dApp!

Remember, Rome wasn't built in a day, and neither are amazing dApps! Keep learning!

Next steps

Congratulations on writing and testing your first dApp using the Massa blockchain! You've taken a crucial step in your blockchain development journey.

There's always more to learn. To continue exploring and expanding your knowledge, you can:

+ \ No newline at end of file diff --git a/docs/build/home.html b/docs/build/home.html index 123cf16c6..9ed7fcd19 100644 --- a/docs/build/home.html +++ b/docs/build/home.html @@ -10,13 +10,13 @@ - +
-
- +
+ \ No newline at end of file diff --git a/docs/build/massa-web3.html b/docs/build/massa-web3.html index d3618c0a4..dced4dc2a 100644 --- a/docs/build/massa-web3.html +++ b/docs/build/massa-web3.html @@ -10,22 +10,17 @@ - +

Leveraging Javascript API for Massa interaction

What is Massa-Web3?

Massa-web3 is an exhaustive library enabling interaction with the Massa blockchain. It can be used in a browser environment and Node.js runtime.

note

Massa-web3 operates by utilizing JsonRPC API in the background to facilitate blockchain communication. The API is divided into a Private and a Public segment, used for node management and blockchain interactions, respectively. For more information on the API, please refer to the JsonRPC API documentation.

Massa-web3 will allow you to interact with the Massa blockchain in a variety of ways:

  • Send transactions
  • Deploy smart contracts
  • Create, manage and inspect addresses
  • Manage your node
  • Fetch events from the blockchain
  • And much more!

In addition, the library includes a collection of handy utility functions (e.g conversion between different units, etc).

tip

For a quick integration of Massa within a web browser, consider reading our Web Frontend Integration Guide.

Installation

Massa-web3 can be used as a library for frameworks or as a stand-alone bundled js file which can be easily loaded into the browser.

Requirements

  • NodeJS 14+
  • npm / yarn (see package.json)

As a library (Node.js/React/Vue.js)

Just install the library using npm:

npm install @massalabs/massa-web3

In a browser

If you want to use the library in a vanilla javascript project, please add the following script tag to your html file:

<script
type="text/javascript"
src="https://cdn.jsdelivr.net/npm/@massalabs/massa-web3@x.x.x/bundle.js"
></script>

whereby the x.x.x is one of the available released versions under Massa-web3's releases page:

In your code, once the script is fully loaded, just use window.massa to access all massa-web3 exports.

<script>console.log("Massa Web3 ", window.massa);</script>

Initialization

Some usage of massa-web3 require an account. This account can be either provided using Wallet-provider or directly in the code

With Wallet-provider

The Wallet-provider allows you to easily connect your dApp to a user's wallet, without having to worry about -secret keys and other sensitive information. The Wallet-provider will automatically detect if a wallet is installed and connect to it.

Full code can be found here

useEffect(() => {
const registerAndSetProvider = async () => {
try {
let provider = (await providers(true, 10000))[0];
let accounts = await provider.accounts();
if (accounts.length === 0) {
setErrorMessage("No accounts found");
return;
}
setAccount(accounts[0]);
if (!account || !provider) {
return;
}
setClient(await ClientFactory.fromWalletProvider(provider, account));
} catch (e) {
console.log(e);
setErrorMessage(
"Please install massa station and the wallet plugin and refresh."
);
}
};
registerAndSetProvider();
}, [account]);

Without Wallet-provider

You can easily initialize a client instance using the ClientFactory class:

```typescript const baseAccount: IAccount = await WalletClient.getAccountFromSecretKey( privateKey ); const chainId = CHAIN_ID.MainNet;

const testnetClient: Client = await ClientFactory.createDefaultClient( -DefaultProviderUrls.MAINNET, -chainId, -true, // retry failed requests -baseAccount // optional parameter -);

</TabItem>

<TabItem value="buildnet-client" label="Buildnet" default>
```typescript
const baseAccount: IAccount = await WalletClient.getAccountFromSecretKey(
privateKey
);
const chainId = CHAIN_ID.BuildNet;

const testnetClient: Client = await ClientFactory.createDefaultClient(
DefaultProviderUrls.BUILDNET,
chainId,
true, // retry failed requests
baseAccount // optional parameter
);
info

When initializing the client, you have the option to specify a baseAccount. If provided, this account +secret keys and other sensitive information. The Wallet-provider will automatically detect if a wallet is installed and connect to it.

Full code can be found here

useEffect(() => {
const registerAndSetProvider = async () => {
try {
let provider = (await providers(true, 10000))[0];
let accounts = await provider.accounts();
if (accounts.length === 0) {
setErrorMessage("No accounts found");
return;
}
setAccount(accounts[0]);
if (!account || !provider) {
return;
}
setClient(await ClientFactory.fromWalletProvider(provider, account));
} catch (e) {
console.log(e);
setErrorMessage(
"Please install massa station and the wallet plugin and refresh."
);
}
};
registerAndSetProvider();
}, [account]);

Without Wallet-provider

You can easily initialize a client instance using the ClientFactory class:

  const baseAccount: IAccount = await WalletClient.getAccountFromSecretKey(
privateKey
);
const chainId = CHAIN_ID.MainNet;

const testnetClient: Client = await ClientFactory.createDefaultClient(
DefaultProviderUrls.MAINNET,
chainId,
true, // retry failed requests
baseAccount // optional parameter
);
info

When initializing the client, you have the option to specify a baseAccount. If provided, this account will be used as the default executor for upcoming calls. If you choose to initialize the client without a baseAccount, it becomes mandatory to specify the executor for each call that requires a signature. -You can learn more about how to manage the base account in the Wallet Operations section.

Client exposed APIs

Once there is an initialized client instance, it is straightforward to call methods on it:

const balance = await web3Client
.wallet()
.getAccountBalance("address")

You can find details for each of the exposed APIs with all the available methods in the following sections:

- +You can learn more about how to manage the base account in the Wallet Operations section.

Client exposed APIs

Once there is an initialized client instance, it is straightforward to call methods on it:

const balance = await web3Client.wallet().getAccountBalance("address");

You can find details for each of the exposed APIs with all the available methods in the following sections:

+ \ No newline at end of file diff --git a/docs/build/massa-web3/backend-usage-massa-web3.html b/docs/build/massa-web3/backend-usage-massa-web3.html index 5305df499..b63f985f9 100644 --- a/docs/build/massa-web3/backend-usage-massa-web3.html +++ b/docs/build/massa-web3/backend-usage-massa-web3.html @@ -10,7 +10,7 @@ - + @@ -20,8 +20,8 @@ of the Massa Web3.

Wallet & Account Management

The Wallet API provides a range of methods for creating or importing an account, getting account information, sending transactions, signing messages, etc.

A complete example of how to use the Wallet API is also available.

You can also find the full typescript documentation here.

Private and Public API

All the operations needed to manage a node are available through the private API. The corresponding Typescript documentation can be found here.

Reading the state of the blockchain can be done through the public API. The corresponding Typescript documentation can be found -here.

- +here.

+ \ No newline at end of file diff --git a/docs/build/massa-web3/dapp-usage-massa-web3.html b/docs/build/massa-web3/dapp-usage-massa-web3.html index 64c3c0e4e..1d292c958 100644 --- a/docs/build/massa-web3/dapp-usage-massa-web3.html +++ b/docs/build/massa-web3/dapp-usage-massa-web3.html @@ -10,18 +10,18 @@ - +

dApp Usage

Here are some examples of how to use the Massa Web3 API for dApp development.

Calling a smart contract

Full code of the Age dApp is available here.

The age smart contract stores the name and age of persons. This snippets shows how to call the smart contract and change the age value of Alice.

After creating a react app and setting up the Massa Web3 API as described in the -installation section, we can call the smart contract method changeAge like this:

let args = new Args().addString(inputName).addU32(newAge);
let opId = await client.smartContracts().callSmartContract({
targetAddress: CONTRACT_ADDRESS,
functionName: "changeAge",
parameter: args.serialize(),
maxGas: BigInt(1000000),
coins: BigInt(0),
fee: BigInt(0),
});

Github redirection

Since that method requires a string and an integer as parameters, we need to serialize them first. The Args class -provides a convenient way to do that. You can learn more about Args via the source code -and its usage with the examples.

If the call is successful, we get an operation id back, you can then use it to check the status of the operation with the explorer

Reading a smart contract value

You can directly read smart contract datastore values -with the readSmartContractData method, which does not require any gas or fee:

      const res = await client.smartContracts().readSmartContract({
maxGas: BigInt(1000000),
targetAddress: CONTRACT_ADDRESS,
targetFunction: "getAge",
parameter: new Args().addString(inputName).serialize(),
});

const age = res.returnValue;
info

Since the getAge method doesn't change the state of the smart contract, we don't need to use a client with an account linked to it.

- +installation section, we can call the smart contract method changeAge like this:

let args = new Args().addString(inputName).addU32(newAge);
let opId = await client.smartContracts().callSmartContract({
targetAddress: CONTRACT_ADDRESS,
functionName: "changeAge",
parameter: args.serialize(),
maxGas: BigInt(1000000),
coins: BigInt(0),
fee: BigInt(0),
});

Github redirection

Since that method requires a string and an integer as parameters, we need to serialize them first. The Args class +provides a convenient way to do that. You can learn more about Args via the source code +and its usage with the examples.

Reading a smart contract value

You can directly read smart contract datastore values +with the readSmartContractData method, which does not require any gas or fee:

const res = await client.smartContracts().readSmartContract({
maxGas: BigInt(1000000),
targetAddress: CONTRACT_ADDRESS,
targetFunction: "getAge",
parameter: new Args().addString(inputName).serialize(),
});

const age = res.returnValue;
info

Since the getAge method doesn't change the state of the smart contract, we don't need to use a client with an account linked to it.

+ \ No newline at end of file diff --git a/docs/build/massa-web3/massa-web3-utils.html b/docs/build/massa-web3/massa-web3-utils.html index cfb93c525..8b49dad6f 100644 --- a/docs/build/massa-web3/massa-web3-utils.html +++ b/docs/build/massa-web3/massa-web3-utils.html @@ -10,13 +10,13 @@ - +
-

Utils

Massa Units

All Massa values that are being used or returned by web3 (gas, fees, coins and rolls) are expressed via BigInt's. Massa-web3 has however a few convenience methods and converters that might come handy. Below is a summary of available methods:

  • Rolls: expressed in BigInt's. For Rolls there is no metric system as rolls are unit-less. 10 rolls is to be represented by a BigInt containing 10. Example:
const rolls = BigInt(10);
// or. ...
const rolls = 10n;
  • Gas/MaxGas: expressed in BigInt's. For Gas/MaxGas there is no metric system as gas is unit-less. The gas represents the computational units required for a given operation to be executed by the network. Example:
const gas = BigInt(2000000);
// or. ...
const gas = 2000000n;
  • Coins/Fees: expressed in BigInt's. Coins/fees do however have a metric system behind them. The smallest unit is 10-9 Massa. All coins/fees are to be expressed as integers scaled by 109 and this way consumed by the network json-rpc protocol. Since gas/fees are to be used as BigInt's web3 adds in a few convenience utils allowing smaller units (e.g. 0.5 Massa) to be expressed.

The util function fromMAS and toMAS are used exactly for the latter purpose. fromMAS receives any amount of type number | string | BigNumber | bigint and returns a scaled bigint for ready use. toMAS on the contrary converts any amount from nanoMassa to Massa and returns a BigNumber representing the amount as a decimal.

Examples:

const coinsToTransfer = fromMAS("0.5"); // half a massa
// or. ...
const coinsToTransfer = 500n * MassaUnits.mMassa; // half a massa
const coinsToTransfer = fromMAS("1"); // one massa
// or. ...
const coinsToTransfer = 1n * MassaUnits.oneMassa; // one massa

Web3 exposes a collection MassaUnits which has three convenience BigInt constants that could be used for amount scaling:

  • MassaUnits.oneMassa = 10910^{9}
  • MassaUnits.mMassa = 10610^{6}
  • MassaUnits.uMassa = 10310^{3}
- +

Utils

Massa Units

All Massa values that are being used or returned by web3 (gas, fees, coins and rolls) are expressed via BigInt's. Massa-web3 has however a few convenience methods and converters that might come handy. Below is a summary of available methods:

  • Rolls: expressed in BigInt's. For Rolls there is no metric system as rolls are unit-less. 10 rolls is to be represented by a BigInt containing 10. Example:
const rolls = BigInt(10);
// or. ...
const rolls = 10n;
  • Gas/MaxGas: expressed in BigInt's. For Gas/MaxGas there is no metric system as gas is unit-less. The gas represents the computational units required for a given operation to be executed by the network. Example:
const gas = BigInt(2000000);
// or. ...
const gas = 2000000n;
  • Coins/Fees: expressed in BigInt's. Coins/fees do however have a metric system behind them. The smallest unit is 10-9 Massa. All coins/fees are to be expressed as integers scaled by 109 and this way consumed by the network json-rpc protocol. Since gas/fees are to be used as BigInt's web3 adds in a few convenience utils allowing smaller units (e.g. 0.5 Massa) to be expressed.

The util function fromMAS and toMAS are used exactly for the latter purpose. fromMAS receives any amount of type number | string | BigNumber | bigint and returns a scaled bigint for ready use. toMAS on the contrary converts any amount from nanoMassa to Massa and returns a BigNumber representing the amount as a decimal.

Examples:

const coinsToTransfer = fromMAS("0.5"); // half a massa
// or. ...
const coinsToTransfer = 500n * MassaUnits.mMassa; // half a massa
const coinsToTransfer = fromMAS("1"); // one massa
// or. ...
const coinsToTransfer = 1n * MassaUnits.oneMassa; // one massa

Web3 exposes a collection MassaUnits which has three convenience BigInt constants that could be used for amount scaling:

  • MassaUnits.oneMassa = 10910^{9}
  • MassaUnits.mMassa = 10610^{6}
  • MassaUnits.uMassa = 10310^{3}
+ \ No newline at end of file diff --git a/docs/build/networks-faucets/local-network.html b/docs/build/networks-faucets/local-network.html index 005564451..c69b63654 100644 --- a/docs/build/networks-faucets/local-network.html +++ b/docs/build/networks-faucets/local-network.html @@ -10,14 +10,14 @@ - +

Local network generation

Here, you will learn how to launch a local network with custom settings, initial coins and rolls distribution.

This may be useful for instance if you want to build and test your integration on the latest version of the nodes.

Clone massa:

git clone git@github.com:massalabs/massa.git

Compile it with the sandbox feature enabled:

cd massa && cargo build --release --features sandbox

Create a keypair in massa-client:

cd massa-client && cargo run
wallet_generate_secret_key

For the rest of the tutorial we will use theses abbreviations:

  • SECRETK: The secret you just generated
  • PUBK: The public key corresponding to SECRETK
  • ADDR: The address corresponding to PUBK

Setup your node to use the secret you just generated as its public key and staking key:

  • modify or create the file massa-node/config/node_privkey.key:

    {"secret_key":"SECRETK","public_key":"PUBK"}
  • modify the file massa-node/base_config/initial_ledger.json:

    {
    "ADDR": {
    "balance": "80000000",
    "datastore": {},
    "bytecode": []
    }
    }
  • CLEAR and modify the file massa-node/base_config/initial_rolls.json:

    {
    "ADDR": 100
    }
  • CLEAR content of massa-node/base_config/initial_vesting.json:

    {}
  • You also have to modify the file massa-node/base_config/config.toml to match the same ChainID as a Sandbox node, as it defaults to the Mainnet ChainID of 77658377.

    {
    chain_id = 77
    }

You can now launch your node:

cd massa-node && cargo run --features sandbox

On your client run the following command to add your secret key as staking key:

cd massa-client && cargo run node_start_staking ADDR

The local network and your node will start after 10 seconds. Once it is started, you can interact with it using the CLI -client as you would with a node on a public network.

- +client as you would with a node on a public network.

+ \ No newline at end of file diff --git a/docs/build/networks-faucets/public-networks.html b/docs/build/networks-faucets/public-networks.html index 8160b19ef..2b417780a 100644 --- a/docs/build/networks-faucets/public-networks.html +++ b/docs/build/networks-faucets/public-networks.html @@ -10,15 +10,15 @@ - +

Networks & Faucets

Here's a handy table containing all you need to know about the different Massa networks and their faucets.

note

Each faucet allows for only one request per day.

What's a Network, Anyway?

In the realm of blockchain technology, a network is a decentralized system of interconnected nodes. These nodes work in harmony to ensure the blockchain runs smoothly, validating transactions, adding them to the blockchain, and maintaining the integrity of the ledger.

What about Faucets?

A faucet, in the context of blockchain, is a mechanism that provides small amounts of cryptocurrency to users for free. -Think of it as a digital tap that drips a small portion of a specific cryptocurrency.

Faucets play a crucial role in the blockchain ecosystem:

  • they offer a friendly introduction to new users by giving them a starting amount of cryptocurrency, and
  • they also aid developers in testing and building blockchain applications by providing the necessary tokens for experimentation.

What's Special About These Networks?

Mainnet

The Massa Mainnet is the main network. It is the only Massa network for which MAS has a monetary value. As a result, no faucet is available for the Mainnet.

Buildnet

The Massa Buildnet serves as your reliable playground for crafting and deploying smart contracts on the Massa blockchain. Buildnet follows a gradual upgrade cycle. This careful pace ensures its constant availability and stability - key factors that you, as a developer, rely on.

At MassaLabs, we put significant effort into the careful maintenance of Buildnet. Our goal is to provide you with a platform where you can build robust, innovative applications.

Leveraging Buildnet's unique features and capabilities, you can navigate the forefront of blockchain technology with confidence and peace of mind, knowing you have a stable and dependable environment for your projects.

Are There Any Requirements for Using Faucets?

Sure! You'll need:

Library Compatibility with Massa Networks

The following table outlines library compatibility across the Massa networks. Use this as a guide to select the appropriate library based on the network you're working with and your project needs.

ProjectInstallNPM versions
sc-project-initializer
npm install @massalabs/project-initializer@mainnet
sc-project-initializer versions
massa-as-sdk
npm install @massalabs/massa-as-sdk@mainnet
massa-as-sdk versions
massa-web3
npm install @massalabs/massa-web3@mainnet
massa-web3 versions
wallet-provider
npm install @massalabs/wallet-provider@mainnet
wallet-provider versions
as-types
npm install @massalabs/as-types@mainnet
as-types versions
as-proba
npm install @massalabs/as-proba@mainnet
as-proba versions
as-transformer
npm install @massalabs/as-transformer@mainnet
as-transformer versions
sc-deployer
npm install @massalabs/massa-sc-deployer@mainnet
sc-deployer versions
- +Think of it as a digital tap that drips a small portion of a specific cryptocurrency.

Faucets play a crucial role in the blockchain ecosystem:

  • they offer a friendly introduction to new users by giving them a starting amount of cryptocurrency, and
  • they also aid developers in testing and building blockchain applications by providing the necessary tokens for experimentation.

What's Special About These Networks?

Mainnet

The Massa Mainnet is the main network. It is the only Massa network for which MAS has a monetary value. As a result, no faucet is available for the Mainnet.

Buildnet

The Massa Buildnet serves as your reliable playground for crafting and deploying smart contracts on the Massa blockchain. Buildnet follows a gradual upgrade cycle. This careful pace ensures its constant availability and stability - key factors that you, as a developer, rely on.

At MassaLabs, we put significant effort into the careful maintenance of Buildnet. Our goal is to provide you with a platform where you can build robust, innovative applications.

Leveraging Buildnet's unique features and capabilities, you can navigate the forefront of blockchain technology with confidence and peace of mind, knowing you have a stable and dependable environment for your projects.

Are There Any Requirements for Using Faucets?

Sure! You'll need:

Library Compatibility with Massa Networks

The following table outlines library compatibility across the Massa networks. Use this as a guide to select the appropriate library based on the network you're working with and your project needs.

ProjectInstallNPM versions
sc-project-initializer
npm install @massalabs/project-initializer@mainnet
sc-project-initializer versions
massa-as-sdk
npm install @massalabs/massa-as-sdk@mainnet
massa-as-sdk versions
massa-web3
npm install @massalabs/massa-web3@mainnet
massa-web3 versions
wallet-provider
npm install @massalabs/wallet-provider@mainnet
wallet-provider versions
as-types
npm install @massalabs/as-types@mainnet
as-types versions
as-proba
npm install @massalabs/as-proba@mainnet
as-proba versions
as-transformer
npm install @massalabs/as-transformer@mainnet
as-transformer versions
sc-deployer
npm install @massalabs/massa-sc-deployer@mainnet
sc-deployer versions
+ \ No newline at end of file diff --git a/docs/build/smart-contract/intro.html b/docs/build/smart-contract/intro.html index 0cd2c660d..69bc8fa87 100644 --- a/docs/build/smart-contract/intro.html +++ b/docs/build/smart-contract/intro.html @@ -10,13 +10,13 @@ - +
-

Introduction

Smart contracts are programs that can interact with the blockchain, which can be viewed as a decentralized database. They allow developers to build decentralized applications (dApps) with controlled execution of contractual terms, where code is law.

But Technically, What is a Smart Contract?

Smart contracts are human-readable code that can be compiled and deployed on a blockchain. In this context, a smart contract can be seen as a stored procedure that can modify the data, interact with other smart contracts, and can be called by end users.

Thanks to the asynchronous execution of smart contracts, they can even automatically wake up at a specific time or when the ledger reaches a specific condition, such as the data of a smart contract having a specific value.

Limitations of Smart Contracts

While smart contracts have many benefits, they also have limitations.

For example, smart contracts:

  • Are small, and storage has a cost.
  • Have short execution times, and execution has a cost, often called gas, and there is a gas limit for a given slot.
  • Must be deterministic, which implies that all their parameters are public and they can only access information on the blockchain.
- +

Introduction

Smart contracts are programs that can interact with the blockchain, which can be viewed as a decentralized database. They allow developers to build decentralized applications (dApps) with controlled execution of contractual terms, where code is law.

But Technically, What is a Smart Contract?

Smart contracts are human-readable code that can be compiled and deployed on a blockchain. In this context, a smart contract can be seen as a stored procedure that can modify the data, interact with other smart contracts, and can be called by end users.

Thanks to the asynchronous execution of smart contracts, they can even automatically wake up at a specific time or when the ledger reaches a specific condition, such as the data of a smart contract having a specific value.

Limitations of Smart Contracts

While smart contracts have many benefits, they also have limitations.

For example, smart contracts:

  • Are small, and storage has a cost.
  • Have short execution times, and execution has a cost, often called gas, and there is a gas limit for a given slot.
  • Must be deterministic, which implies that all their parameters are public and they can only access information on the blockchain.
+ \ No newline at end of file diff --git a/docs/build/smart-contract/prerequisites.html b/docs/build/smart-contract/prerequisites.html index b465d0509..1b39bcb7a 100644 --- a/docs/build/smart-contract/prerequisites.html +++ b/docs/build/smart-contract/prerequisites.html @@ -10,14 +10,14 @@ - +

Prerequisites

Before you can begin developing smart contracts on the Massa blockchain, you'll need to ensure that your development environment meets the following requirements:

tip

We recommend updating Node.js and npm to the latest version for best performance and security.

To update npm, run the following commands:

npm install -g npm

To update Node.js, the recommended way is to use n, the Node.js version manager. -If you do not already have n installed, you can install it with the following command:

npm install -g n

Once n is installed, you can update to the latest version of Node.js with the following command:

n latest

Once you have an up-to-date Node.js, you're ready to start developing smart contracts on the Massa blockchain.

- +If you do not already have n installed, you can install it with the following command:

npm install -g n

Once n is installed, you can update to the latest version of Node.js with the following command:

n latest

Once you have an up-to-date Node.js, you're ready to start developing smart contracts on the Massa blockchain.

+ \ No newline at end of file diff --git a/docs/build/smart-contract/sdk.html b/docs/build/smart-contract/sdk.html index 3f87c05fa..ae24916a2 100644 --- a/docs/build/smart-contract/sdk.html +++ b/docs/build/smart-contract/sdk.html @@ -10,13 +10,13 @@ - +
-

AS-SDK

AS-SDK is a software development kit designed specifically for Massa smart contracts written in AssemblyScript. It provides a set of functions and objects that wrap the ABIs exposed by the node.

It includes several namespaces, each containing functions and objects that provide specific functionalities:

Coins

The Coins namespace includes functions for interacting with wallet balances and transfers. For more information on this namespace, see the AS-SDK Coins documentation.

Context

The Context namespace includes functions to interact with the execution context of a smart contract on the Massa blockchain. This namespace is particularly useful to retrieve information about the current state of a smart contract, such as the caller and callee of the current contract, the call stack, the amount of transferred coins, the remaining gas, and the timestamp. For more information on this namespace, see the AS-SDK Context documentation.

Contract

The Contract namespace includes functions to interact with other smart contract functions and manipulate their bytecode. This namespace is particularly useful to create new smart contracts and send messages to existing ones. For more information on this namespace, see the AS-SDK Contract documentation.

OpDatastore

The OpDatastore namespace includes functions to interact with the operation datastore. This key/value storage can be filled by the operation creator and then used by the smart contract being executed. This namespace is particularly useful to read the data that is passed with the bytecode in an execute smart contract operation. For more information on this namespace, see the AS-SDK OpDatastore documentation.

Storage

The Storage namespace includes functions to interact with the key-value datastore. This namespace is particularly useful to read and write data that is expected to persist between contract executions, such as contract state or user information. For more information on this namespace, see the AS-SDK Storage documentation.

Utilities

The Utilities namespace includes various utility functions, such as event generation, base58 encoding and decoding, and public key to address conversion. For more information on this namespace, see the AS-SDK Utilities documentation.

- +

AS-SDK

AS-SDK is a software development kit designed specifically for Massa smart contracts written in AssemblyScript. It provides a set of functions and objects that wrap the ABIs exposed by the node.

It includes several namespaces, each containing functions and objects that provide specific functionalities:

Coins

The Coins namespace includes functions for interacting with wallet balances and transfers. For more information on this namespace, see the AS-SDK Coins documentation.

Context

The Context namespace includes functions to interact with the execution context of a smart contract on the Massa blockchain. This namespace is particularly useful to retrieve information about the current state of a smart contract, such as the caller and callee of the current contract, the call stack, the amount of transferred coins, the remaining gas, and the timestamp. For more information on this namespace, see the AS-SDK Context documentation.

Contract

The Contract namespace includes functions to interact with other smart contract functions and manipulate their bytecode. This namespace is particularly useful to create new smart contracts and send messages to existing ones. For more information on this namespace, see the AS-SDK Contract documentation.

OpDatastore

The OpDatastore namespace includes functions to interact with the operation datastore. This key/value storage can be filled by the operation creator and then used by the smart contract being executed. This namespace is particularly useful to read the data that is passed with the bytecode in an execute smart contract operation. For more information on this namespace, see the AS-SDK OpDatastore documentation.

Storage

The Storage namespace includes functions to interact with the key-value datastore. This namespace is particularly useful to read and write data that is expected to persist between contract executions, such as contract state or user information. For more information on this namespace, see the AS-SDK Storage documentation.

Utilities

The Utilities namespace includes various utility functions, such as event generation, base58 encoding and decoding, and public key to address conversion. For more information on this namespace, see the AS-SDK Utilities documentation.

+ \ No newline at end of file diff --git a/docs/build/smart-contract/webassembly-module.html b/docs/build/smart-contract/webassembly-module.html index e8b2e7539..42f9a62f6 100644 --- a/docs/build/smart-contract/webassembly-module.html +++ b/docs/build/smart-contract/webassembly-module.html @@ -10,7 +10,7 @@ - + @@ -18,8 +18,8 @@

WebAssembly Module

Each smart contract is a WebAssembly module with exported functions, and has access to specific node ABIs. We will see these ABIs in the next chapter.

WebAssembly code is compiled from AssemblyScript, a language created specifically for WebAssembly.

AssemblyScript is very similar to TypeScript, but there are some important differences to keep in mind. For example, the basic types in AssemblyScript directly expose all integer and floating-point types available in WebAssembly. Union types and optional arguments/properties are not supported in AssemblyScript, and all objects are statically typed and do not allow for dynamically changing properties. -Additionally, AssemblyScript does not support exceptions catching or closures yet.

To learn more about AssemblyScript, WebAssembly modules, and ABIs, we invite you to check out the following resources:

caution

Do not initialize a smart contract project following AssemblyScript documentation. It will be unnecessarily painful. Go back to the the "Hello, World" dApp tutorial or use the following command:

npx clear-npx-cache && npx @massalabs/sc-project-initializer@buildnet init my-first-sc && cd my-first-sc
- +Additionally, AssemblyScript does not support exceptions catching or closures yet.

To learn more about AssemblyScript, WebAssembly modules, and ABIs, we invite you to check out the following resources:

caution

Do not initialize a smart contract project following AssemblyScript documentation. It will be unnecessarily painful. Go back to the the "Hello, World" dApp tutorial or use the following command:

npx clear-npx-cache && npx @massalabs/sc-project-initializer@buildnet init my-first-sc && cd my-first-sc
+ \ No newline at end of file diff --git a/docs/build/standards.html b/docs/build/standards.html index 12eab1420..225fa7589 100644 --- a/docs/build/standards.html +++ b/docs/build/standards.html @@ -10,13 +10,13 @@ - +
-

Massa Standard

The Massa Standard is your comprehensive starting point for blockchain projects on the Massa network. Offering reference implementations of the most common smart contracts, it's the toolkit you need for tokens, NFTs, or wallet creation.

Adhering to a standard like this in the blockchain world is important. Standards ensure all participants in a blockchain network can interact seamlessly because they follow a unified structure and protocol. This compatibility fosters a more robust and inclusive blockchain ecosystem, encouraging mass adoption and facilitating growth.

Fungible Tokens (FT)

FT is a standard for creating fungible, tradable tokens on the Massa blockchain. It includes a set of functions that allow for seamless interaction with tokens within smart contracts and wallets.

View on GitHub

Non-Fungible Tokens (NFT)

NFT is a standard for creating unique, non-fungible tokens on the Massa blockchain. This allows the creation and management of tokens where each instance has a unique value or properties.

View on GitHub

Massa Domain Name Service (DNS)

The DNS standard provides a foundational framework for managing Domain Name System (DNS) records within the Massa blockchain ecosystem. It streamlines the creation of a link between the hostname (website name), resolver address (where the smart contract and chunks of the website are located), and the DNS record owner.

Massa Units Standard

The Massa Units standard defines common units of measurement for the Massa blockchain, including:

  • Massa coin

  • Gas

  • Rolls

Learn more about Massa Units Standard

- +

Massa Standard

The Massa Standard is your comprehensive starting point for blockchain projects on the Massa network. Offering reference implementations of the most common smart contracts, it's the toolkit you need for tokens, NFTs, or wallet creation.

Adhering to a standard like this in the blockchain world is important. Standards ensure all participants in a blockchain network can interact seamlessly because they follow a unified structure and protocol. This compatibility fosters a more robust and inclusive blockchain ecosystem, encouraging mass adoption and facilitating growth.

Fungible Tokens (FT)

FT is a standard for creating fungible, tradable tokens on the Massa blockchain. It includes a set of functions that allow for seamless interaction with tokens within smart contracts and wallets.

View on GitHub

Non-Fungible Tokens (NFT)

NFT is a standard for creating unique, non-fungible tokens on the Massa blockchain. This allows the creation and management of tokens where each instance has a unique value or properties.

View on GitHub

Massa Domain Name Service (DNS)

The DNS standard provides a foundational framework for managing Domain Name System (DNS) records within the Massa blockchain ecosystem. It streamlines the creation of a link between the hostname (website name), resolver address (where the smart contract and chunks of the website are located), and the DNS record owner.

Massa Units Standard

The Massa Units standard defines common units of measurement for the Massa blockchain, including:

  • Massa coin

  • Gas

  • Rolls

Learn more about Massa Units Standard

+ \ No newline at end of file diff --git a/docs/build/tooling-versions.html b/docs/build/tooling-versions.html index 8ae99c848..41f1fa484 100644 --- a/docs/build/tooling-versions.html +++ b/docs/build/tooling-versions.html @@ -10,13 +10,13 @@ - +
-

Tooling Versions

This table provides a concise overview of the different versions of our projects that are compatible with the different Networks.

Take a look at the table below to identify the right version for your desired network.

ProjectInstallNPM versions
sc-project-initializer
npm install @massalabs/project-initializer@mainnet
sc-project-initializer versions
massa-as-sdk
npm install @massalabs/massa-as-sdk@mainnet
massa-as-sdk versions
massa-web3
npm install @massalabs/massa-web3@mainnet
massa-web3 versions
wallet-provider
npm install @massalabs/wallet-provider@mainnet
wallet-provider versions
as-types
npm install @massalabs/as-types@mainnet
as-types versions
as-proba
npm install @massalabs/as-proba@mainnet
as-proba versions
as-transformer
npm install @massalabs/as-transformer@mainnet
as-transformer versions
sc-deployer
npm install @massalabs/massa-sc-deployer@mainnet
sc-deployer versions
- +

Tooling Versions

This table provides a concise overview of the different versions of our projects that are compatible with the different Networks.

Take a look at the table below to identify the right version for your desired network.

ProjectInstallNPM versions
sc-project-initializer
npm install @massalabs/project-initializer@mainnet
sc-project-initializer versions
massa-as-sdk
npm install @massalabs/massa-as-sdk@mainnet
massa-as-sdk versions
massa-web3
npm install @massalabs/massa-web3@mainnet
massa-web3 versions
wallet-provider
npm install @massalabs/wallet-provider@mainnet
wallet-provider versions
as-types
npm install @massalabs/as-types@mainnet
as-types versions
as-proba
npm install @massalabs/as-proba@mainnet
as-proba versions
as-transformer
npm install @massalabs/as-transformer@mainnet
as-transformer versions
sc-deployer
npm install @massalabs/massa-sc-deployer@mainnet
sc-deployer versions
+ \ No newline at end of file diff --git a/docs/build/wallet/community-wallets.html b/docs/build/wallet/community-wallets.html index d2442bfec..d6ae17665 100644 --- a/docs/build/wallet/community-wallets.html +++ b/docs/build/wallet/community-wallets.html @@ -10,13 +10,13 @@ - +
-

Community Wallets

NameDescription
BearbyBearby provides a simple way to Connect any website to the Massa ecosystem.
- +

Community Wallets

NameDescription
BearbyBearby provides a simple way to Connect any website to the Massa ecosystem.
+ \ No newline at end of file diff --git a/docs/build/wallet/intro.html b/docs/build/wallet/intro.html index b2b7c51b0..0ddc42ed8 100644 --- a/docs/build/wallet/intro.html +++ b/docs/build/wallet/intro.html @@ -10,15 +10,15 @@ - +

Introduction

A wallet is a fundamental tool for interacting with the blockchain. Consider it your digital identity, enabling you to send, receive, and manage assets on a blockchain.

There are several wallets available that are compatible with the Massa blockchain. -These wallets allow you to securely interact with the blockchain, including sending, receiving, and managing assets

Wallet Providers

Here is a list of available wallet providers for the Massa blockchain:

  • Massa Wallet: Massa Station is an official wallet developed by the Massa team. It provides a user-friendly interface and robust security features.

  • Community Wallets: Community wallets are developed and maintained by the Massa community. These wallets can vary in features and interfaces.

  • Wallet Provider: Wallet Provider offers a secure, reliable, and versatile wallet that supports the Massa blockchain.

- +These wallets allow you to securely interact with the blockchain, including sending, receiving, and managing assets

Wallet Providers

Here is a list of available wallet providers for the Massa blockchain:

  • Massa Wallet: Massa Station is an official wallet developed by the Massa team. It provides a user-friendly interface and robust security features.

  • Community Wallets: Community wallets are developed and maintained by the Massa community. These wallets can vary in features and interfaces.

  • Wallet Provider: Wallet Provider offers a secure, reliable, and versatile wallet that supports the Massa blockchain.

+ \ No newline at end of file diff --git a/docs/build/wallet/massa-wallet.html b/docs/build/wallet/massa-wallet.html index 4bc71b0e3..9ab224034 100644 --- a/docs/build/wallet/massa-wallet.html +++ b/docs/build/wallet/massa-wallet.html @@ -10,14 +10,14 @@ - +

Massa Wallet

Massa Wallet is a plugin for Massa Station that allows you to -store your assets and interact with decentralized applications. It is the recommended way to interact with the Massa blockchain.

Follow the link to get started with Massa Wallet !

- +store your assets and interact with decentralized applications. It is the recommended way to interact with the Massa blockchain.

Follow the link to get started with Massa Wallet !

+ \ No newline at end of file diff --git a/docs/build/wallet/wallet-provider.html b/docs/build/wallet/wallet-provider.html index 078283f4a..08a6674f1 100644 --- a/docs/build/wallet/wallet-provider.html +++ b/docs/build/wallet/wallet-provider.html @@ -10,13 +10,13 @@ - +
-

Wallet Provider Integration Guide

Overview of wallet-provider

wallet-provider is a versatile library designed to connect dApps with user wallets, adhering to the Massa wallet standards. It supports seamless integration with the Massa blockchain, either as a standalone utility or in conjunction with massa-web3, facilitating a secure and efficient dApp-to-wallet communication channel.

Key Features

  • Wallet Discovery: Automatically identifies and connects to compatible wallets present on the user's device.
  • Account Management: Offers functionalities to import, retrieve, and handle wallet accounts with ease.
  • Transaction Signing: Enables the signing of transactions and messages directly from the dApp interface.
  • Balance Inquiry: Allows for real-time balance checks of connected wallet accounts.

Getting Started

Installation

Ensure you have wallet-provider installed in your project. If not, you can add it using npm or yarn:

npm install @massalabs/wallet-provider
# or
yarn add @massalabs/wallet-provider

Basic Usage Examples

Listing Available Providers

Retrieve a list of all wallet providers that adhere to the Massa wallet standard:

import { providers } from "@massalabs/wallet-provider";
const providerList = providers();

Selecting a Wallet Provider

Choose a specific wallet provider from the available list, for example, MASSASTATION:

import { providers } from "@massalabs/wallet-provider";

const providerList = providers();
const massaStationProvider = providerList.find(
(provider) => provider.name() === "MASSASTATION"
);

Accessing Wallet Accounts

After selecting a provider, you can retrieve the accounts associated with it:

import { providers } from "@massalabs/wallet-provider";

const providerList = providers();
const massaStationProvider = providerList.find(
(provider) => provider.name() === "MASSASTATION"
);

const accounts = await massaStationProvider.accounts();

Account Functions

For a comprehensive list of account-related functionalities, such as sending transactions, signing messages, and querying account balances, refer to the IAccount interface documentation available here.


This guide serves as an introductory resource for integrating the wallet-provider with your dApp. For detailed documentation, including advanced features and integration scenarios, visit the Massa standards repository and the wallet-provider GitHub page.

- +

Wallet Provider Integration Guide

Overview of wallet-provider

wallet-provider is a versatile library designed to connect dApps with user wallets, adhering to the Massa wallet standards. It supports seamless integration with the Massa blockchain, either as a standalone utility or in conjunction with massa-web3, facilitating a secure and efficient dApp-to-wallet communication channel.

Key Features

  • Wallet Discovery: Automatically identifies and connects to compatible wallets present on the user's device.
  • Account Management: Offers functionalities to import, retrieve, and handle wallet accounts with ease.
  • Transaction Signing: Enables the signing of transactions and messages directly from the dApp interface.
  • Balance Inquiry: Allows for real-time balance checks of connected wallet accounts.

Getting Started

Installation

Ensure you have wallet-provider installed in your project. If not, you can add it using npm or yarn:

npm install @massalabs/wallet-provider
# or
yarn add @massalabs/wallet-provider

Basic Usage Examples

Listing Available Providers

Retrieve a list of all wallet providers that adhere to the Massa wallet standard:

import { providers } from "@massalabs/wallet-provider";
const providerList = providers();

Selecting a Wallet Provider

Choose a specific wallet provider from the available list, for example, MASSASTATION:

import { providers } from "@massalabs/wallet-provider";

const providerList = providers();
const massaStationProvider = providerList.find(
(provider) => provider.name() === "MASSASTATION"
);

Accessing Wallet Accounts

After selecting a provider, you can retrieve the accounts associated with it:

import { providers } from "@massalabs/wallet-provider";

const providerList = providers();
const massaStationProvider = providerList.find(
(provider) => provider.name() === "MASSASTATION"
);

const accounts = await massaStationProvider.accounts();

Account Functions

For a comprehensive list of account-related functionalities, such as sending transactions, signing messages, and querying account balances, refer to the IAccount interface documentation available here.


This guide serves as an introductory resource for integrating the wallet-provider with your dApp. For detailed documentation, including advanced features and integration scenarios, visit the Massa standards repository and the wallet-provider GitHub page.

+ \ No newline at end of file diff --git a/docs/learn/architecture/basic-concepts.html b/docs/learn/architecture/basic-concepts.html index 1869d822b..6a52c108d 100644 --- a/docs/learn/architecture/basic-concepts.html +++ b/docs/learn/architecture/basic-concepts.html @@ -10,7 +10,7 @@ - + @@ -108,8 +108,8 @@ validations of the fact that the parent block on the thread of the block is the best parent that could have been chosen, done by other nodes that have also been deterministically selected via the proof of stake probability distribution. A comprehensive description of endorsements can be found here, so we will -not go further into details in the context of this introduction.

- +not go further into details in the context of this introduction.

+ \ No newline at end of file diff --git a/docs/learn/architecture/consensus-quality.html b/docs/learn/architecture/consensus-quality.html index a0279526f..b6748d9dd 100644 --- a/docs/learn/architecture/consensus-quality.html +++ b/docs/learn/architecture/consensus-quality.html @@ -10,7 +10,7 @@ - + @@ -31,8 +31,8 @@ to the Endorsement Pool if they are not already known. The Endorsement Pool stores a limited number of endorsements that can potentially be included in future blocks. Consensus notifies the Endorsement Pool of newly finalized blocks, allowing it to remove endorsements that can only be included in already-finalized slots.

When the Block Factory produces a block and needs to include endorsements in its header, it requests the Endorsement Pool -for the endorsements that endorse the block's parent in its thread and can be included in the block's slot.

Incentives and penalties

To incentivize the creation and endorsement of blocks, as well as the inclusion of endorsements in blocks, a revenue split is implemented. The total revenue generated by a block, denoted as RR, is divided into 1+E1+E equal parts, where EE is the number of endorsements.

Each part, denoted as rr, is distributed as follows:

  • The block creator receives rr to motivate block creation, even without endorsements.
  • For each successfully included endorsement:
    • The block creator receives r/3r/3 to incentivize endorsement inclusion.
    • The endorsement creator receives r/3r/3 to motivate endorsement creation.
    • The creator of the endorsed block receives r/3r/3 to encourage timely block emission for endorsement.

This revenue split increases the frequency at which stakers receive coins, reducing the need for staking pools.

- +for the endorsements that endorse the block's parent in its thread and can be included in the block's slot.

Incentives and penalties

To incentivize the creation and endorsement of blocks, as well as the inclusion of endorsements in blocks, a revenue split is implemented. The total revenue generated by a block, denoted as RR, is divided into 1+E1+E equal parts, where EE is the number of endorsements.

Each part, denoted as rr, is distributed as follows:

  • The block creator receives rr to motivate block creation, even without endorsements.
  • For each successfully included endorsement:
    • The block creator receives r/3r/3 to incentivize endorsement inclusion.
    • The endorsement creator receives r/3r/3 to motivate endorsement creation.
    • The creator of the endorsed block receives r/3r/3 to encourage timely block emission for endorsement.

This revenue split increases the frequency at which stakers receive coins, reducing the need for staking pools.

+ \ No newline at end of file diff --git a/docs/learn/architecture/node-architecture.html b/docs/learn/architecture/node-architecture.html index d66d5a0fb..08423795f 100644 --- a/docs/learn/architecture/node-architecture.html +++ b/docs/learn/architecture/node-architecture.html @@ -10,7 +10,7 @@ - + @@ -100,8 +100,8 @@ query the Execution Module about finalized and executed operations, and internally cleanup operations that have been handled.

Finally, the Block Factory will query the Pool Module and pick pending endorsements corresponding to the best parents that are selected for the block.

With this information, it is able to forge a new block that will then be propagated to the Graph/Consensus Module via the API Module, as well as to other nodes via gossip, to maintain a global synchronized state.

The Endorsement Factory Module works in a similar manner, requesting the Selector Module to find out when it has been -designated to be an endorsement producer, then feeding new endorsements to the Pool Module and the API Module for global synchronization.

- +designated to be an endorsement producer, then feeding new endorsements to the Pool Module and the API Module for global synchronization.

+ \ No newline at end of file diff --git a/docs/learn/architecture/operation-lifecycle.html b/docs/learn/architecture/operation-lifecycle.html index 5c4fc484b..9ad17c430 100644 --- a/docs/learn/architecture/operation-lifecycle.html +++ b/docs/learn/architecture/operation-lifecycle.html @@ -10,7 +10,7 @@ - + @@ -33,8 +33,8 @@ will eventually be executed. Within the block is the original operation that was originally sent and that will then be applied to the ledger for potential modifications. At this stage, the modifications are not permanent and simply stored in a diff compared to the finalized ledger

  • Eventually, the block will be marked as final and the ledger modification, including the operation changes, -will become final in the finalized ledger.

  • - +will become final in the finalized ledger.

    + \ No newline at end of file diff --git a/docs/learn/asc/intro.html b/docs/learn/asc/intro.html index 3b38699f2..9008fe1fa 100644 --- a/docs/learn/asc/intro.html +++ b/docs/learn/asc/intro.html @@ -10,7 +10,7 @@ - + @@ -29,8 +29,8 @@ Consequently, significant time and effort have been invested in developing more dependable networks of bots to ensure the timely execution of transactions. However, since these solutions operate off-chain, there is no guarantee that the execution will be triggered effectively. -In cases where bots fail to execute transactions, decentralized protocols face risks, as do the applications built on top of them.

    - +In cases where bots fail to execute transactions, decentralized protocols face risks, as do the applications built on top of them.

    + \ No newline at end of file diff --git a/docs/learn/asc/massa-asc.html b/docs/learn/asc/massa-asc.html index 8f69c3007..deed6f861 100644 --- a/docs/learn/asc/massa-asc.html +++ b/docs/learn/asc/massa-asc.html @@ -10,7 +10,7 @@ - + @@ -26,8 +26,8 @@ are removed based on the fees and after a certain number of slots if they were not executed.

    As for normal operations, the number of autonomous operations that can be executed is limited, through a maximum amount of gas. In practice, it’s possible that your message isn’t executed at the slot that you want, but in a later slot, when there is enough space to include your message. If you want your message to be included as soon as possible, the -fees needs to be higher than other messages (just like standard operations).

    Messages are ordered using the following formula:

    (Reverse(Ratio(msg.fee,max(msg.maxgas,1))),emission_slot,emission_index),(Reverse(Ratio(msg.fee, max(msg.max_gas,1))), emission\_slot, emission\_index),

    where emission_indexemission\_index is an index that differentiate multiple messages created in the same slot.

    - +fees needs to be higher than other messages (just like standard operations).

    Messages are ordered using the following formula:

    (Reverse(Ratio(msg.fee,max(msg.maxgas,1))),emission_slot,emission_index),(Reverse(Ratio(msg.fee, max(msg.max_gas,1))), emission\_slot, emission\_index),

    where emission_indexemission\_index is an index that differentiate multiple messages created in the same slot.

    + \ No newline at end of file diff --git a/docs/learn/asc/use-cases.html b/docs/learn/asc/use-cases.html index 68b355f23..0189eb090 100644 --- a/docs/learn/asc/use-cases.html +++ b/docs/learn/asc/use-cases.html @@ -10,15 +10,15 @@ - +

    Use-cases & Applications

    Autonomous smart contracts offers a wide range of compelling use-cases that were either impossible, too costly, or risky to do with benchmark are met.

    Here are some of the best use cases for autonomous smart contracts:

    1. Decentralized Finance (DeFi): Autonomous smart contracts can revolutionize DeFi applications by enabling automated and self-executing actions. Some notable use cases include:

      • Automated liquidations: Smart contracts can automatically trigger the liquidation of under-collateralized positions in lending protocols when predetermined thresholds are breached.
      • Yield farming strategies: Contracts can autonomously perform yield farming strategies, automatically swapping and reinvesting tokens based on predefined conditions.
      • Dynamic portfolio rebalancing: Smart contracts can automatically adjust portfolio allocations based on market conditions, ensuring desired asset ratios are maintained.
    2. Supply Chain Management: Autonomous smart contracts have the potential to streamline supply chain processes by automating specific actions triggered by predefined conditions. Key use cases include:

      • Automatic inventory management: Contracts can initiate purchase orders or trigger production when inventory levels reach predefined thresholds, ensuring optimal stock levels.
      • Quality control and compliance: Smart contracts can autonomously perform quality checks and audits based on predefined criteria, ensuring compliance with standards and regulations.
    3. Insurance Claims: Autonomous smart contracts can revolutionize the insurance industry by automating claims processes. Notable use cases include:

      • Instant claims settlement: Contracts can automatically trigger claim payments when specific conditions, such as verified damage or loss, are met, accelerating the claims settlement process.
      • Parametric insurance: Smart contracts can leverage external data feeds, such as weather or seismic information, to autonomously determine and process claims without human intervention.
    4. Gaming and NFTs: Autonomous smart contracts can bring enhanced functionality and interactivity, and cost-reduction in on-chain execution, to gaming and non-fungible token (NFT) platforms. Key use cases include:

      • Dynamic NFTs: Contracts can imbue NFTs with evolving characteristics or abilities based on predefined conditions, creating captivating and unique gaming experiences.
      • Automated auctions: Contracts can autonomously initiate and manage auctions for rare items, with bidding and settlement executed automatically when predetermined criteria are met.
    5. Decentralized Autonomous Organizations (DAOs): Autonomous smart contracts are instrumental in enabling self-governance and decision-making within DAOs. Notable use cases include:

      • Voting and governance: Contracts can autonomously trigger voting processes based on predefined conditions, empowering token holders to participate in important decision-making. There are various applications for this: from voting in local communities to democratic processes in corporate governance.
      • Automated fund management: Smart contracts can autonomously allocate funds, distribute dividends, or trigger investments based on predefined rules and performance metrics.
    6. Real Estate Transactions: Smart contracts can streamline various aspects of real estate transactions, increasing efficiency and reducing the need for intermediaries. Key use cases include:

      • Escrow and payment automation: Contracts can securely hold funds in escrow and automatically release them when specific conditions, such as successful property transfer or completion of milestones, are met.
      • Streamlined rental agreements: Contracts can automate rental payments, manage security deposits, and enforce the terms and conditions stipulated in the agreement.

    These examples illustrate just a few of the many compelling use cases for autonomous smart contracts. The self wake-up functionality empowers automated processes, reduces reliance on intermediaries, and enhances efficiency and -transparency across diverse industries.

    Going further

    If you want to go further and start coding your own autonomous smart contract, head to the Build section.

    - +transparency across diverse industries.

    Going further

    If you want to go further and start coding your own autonomous smart contract, head to the Build section.

    + \ No newline at end of file diff --git a/docs/learn/bootstrap.html b/docs/learn/bootstrap.html index 56b9cba11..d45db6b29 100644 --- a/docs/learn/bootstrap.html +++ b/docs/learn/bootstrap.html @@ -10,13 +10,13 @@ - +
    -

    Bootstrapping in Massa

    Introduction

    Nodes that are already part of the network are able to follow the State by observing the blocks passing through the network, verifying them, and applying the state changes they cause.

    However, new nodes joining the network need to get an absolute "current" version of the state, which is called "bootstrapping". In some blockchains like Bitcoin, full nodes joining the network are recommended to download all blocks from the beginning (genesis) of the blockchain in order to re-verify the whole state change history.

    However, Massa has a triple decentralization/security/performance goal:

    • maximal decentralization requires that node hardware requirements stay consistent with a typical consumer desktop computer to lower the entry barrier of becoming a node runner
    • maximal security requires that all nodes verify all blocks and operations
    • maximal performance requires using the node hardware to its fullest (CPU, network, memory, storage)

    This means that the State in Massa evolves almost as fast as typical consumer desktop computers can run blocks, which implies that catching up blocks since genesis goes only slightly faster than new blocks appear in the meantime, and would take a very long time. Moreover, Massa aims at processing thousands of operations per second, which means that it produces a lot of block data every second, thus preventing nodes with the target hardware from storing the full block history and making bootstrapping from genesis impossible since old blocks are forgotten.

    Massa nodes joining the network must therefore bootstrap by downloading the absolute current State.

    Note that nodes can recover from short-term disconnects by asking for missing data from nodes around them once they come back in the network. However, since Massa nodes only store a short history of blocks and forget older ones, it is impossible to recover from long disconnects since the surrounding nodes have forgotten the blocks needed by the recovering node. In that case, a new State bootstrap is required.

    Security model

    The example of Bitcoin

    To understand the security model of node bootstrap, Bitcoin is a good starting example.

    When Bitcoin node runners decide to join the network, they first download the node software from a central source (eg. bitcoin.org). If that source is compromised, the node might end up on a different network, and/or private key theft might happen. Bitcoin therefore requires trust in the entity sourcing the node software.

    Note that optionally, if the nodes don't wish to download the full block history they resort to trusting a more recent "checkpoint" state encoded in the node software. If that state is compromised, the node's knowledge of the whole ledger might be skewed.

    Assuming the node software is not corrupted, new nodes joining the network need an initial list of peer nodes to which they need to connect first in order to discover the network. This list is hardcoded in the node software (see the bitcoin docs). If all peers pointed by this initial list are compromised, the node can end on a different (non-bitcoin) network, even if the node software itself is not compromised. Bitcoin therefore also requires trust in at least one of the initial peers.

    Note that ending up on the wrong network can be detected by checking block hashes with an external source. But this requires trusting yet another source of data.

    The case of Massa

    The Massa case is very similar to Bitcoin's. Node runners also need to trust the source of the node software they download, as well as the initial list of peers.

    Similarly to Bitcoin checkpoints, bootstrapping Massa nodes must obtain the current State from a trusted source, ideally the same source as the one they downloaded the node software from, in order to avoid having to trust multiple entities.

    Downloading the state from an untrusted source can result in major issues such as coin theft. As such, bootstrapping from untrusted sources should be discouraged, and bootstrapping other nodes should be opt-in for node runners to avoid "bootstrap lists" circulating as the default way of bootstrapping from unaware node runners.

    Implementation details

    Procedure from the point of view of the node being bootstrapped

    Massa nodes that bootstrap start by connecting to a randomly chosen node among the ones listed in massa-node/base_config/config.toml.

    The bootstrap process uses a separate port and protocol than the normal Massa peer communication.

    All communications with the chosen bootstrap node are authenticated using the public key (node ID) of the bootstrap node in the config.toml file to prevent man-in-the-middle attacks.

    The node being bootstrapped then attempts to download the current State, as well as an initial list of peers from the bootstrap node.

    Once successfully bootstrapped, the node can then connect to peers, discover the rest of the network, and process live incoming blocks to keep its state up to date.

    In Massa, the hash of the state is used as part of the proof-of-stake seed, which is a safety mechanism against malicious bootstrap nodes sending a compromised State. It ensures that nodes with an altered State eventually end up isolated from the real network because their proof-of-stake draws differ which causes them to discard incoming honest blocks. Note however that a PoS seed mismatch can take up to 2 cycles to be detected.

    In case of bootstrap failure, the bootstrapping node retries with another randomly chosen bootstrap node after a delay.

    Procedure from the point of view of the bootstrap node

    Massa nodes can bootstrap other nodes, with certain limitations because the procedure is heavy for the bootstrap node.

    The bootstrap system listens on the address/port defined in massa-node/base_config/config.toml. The node's bootstrap server can be disabled by removing the bind entry from the config file.

    The Massa State is large (terabytes in the worst case), and takes time to upload to bootstrapping nodes. During that time, new changes to the state continue to appear, so new changes affecting already-uploaded parts need to be sent on-the-fly.

    By default, Massa nodes only allow a whitelist of IP addresses to bootstrap from them. This list is present in the massa-node/base_config/bootstrap_whitelist.json file. This list is intended to prevent flooding attacks by attackers pretending to be bootstrapping, and also makes it more difficult for node runners to bootstrap from untrusted sources. If you wish to disable whitelisting and allow anyone to bootstrap from your node, simply delete the bootstrap_whitelist.json file and restart your node.

    A complementary bootstrap_blacklist.json (absent by default) can also be created alongside bootstrap_whitelist.json (and following the same syntax) in order to explicitly prevent certain IP addresses from bootstrapping from the node.

    Once a node has accepted to bootstrap an incoming node, it adds the incoming node's IP address to a local cache preventing that IP from bootstrapping again for a time defined in massa-node/base_config/config.toml (section bootstrap/per_ip_min_interval) by refusing subsequent connections from that IP during the config-defined delay. The exclusion delay is not extended if the remote IP attempts new connections during the exclusion delay. The exclusion delay is however applied if the bootstrap was accepted but failed for any reason. This aims at limiting the load on individual bootstrap nodes, and spreading the load among bootstrap nodes.

    The number of nodes simultaneously bootstrapping from the local node is limited (massa-node/base_config/config.toml section bootstrap/max_simultaneous_bootstraps). Excess attempts are refused but do not trigger the exclusion delay mechanism.

    Future optimizations

    We plan to add the possibility to download bootstrap data from untrusted sources for load-balancing, but then check the hash of the obtained state from trusted sources, and only fallback to downloading everything from trusted sources if multiple bootstrap attempts from this hybrid approach fail.

    - +

    Bootstrapping in Massa

    Introduction

    Nodes that are already part of the network are able to follow the State by observing the blocks passing through the network, verifying them, and applying the state changes they cause.

    However, new nodes joining the network need to get an absolute "current" version of the state, which is called "bootstrapping". In some blockchains like Bitcoin, full nodes joining the network are recommended to download all blocks from the beginning (genesis) of the blockchain in order to re-verify the whole state change history.

    However, Massa has a triple decentralization/security/performance goal:

    • maximal decentralization requires that node hardware requirements stay consistent with a typical consumer desktop computer to lower the entry barrier of becoming a node runner
    • maximal security requires that all nodes verify all blocks and operations
    • maximal performance requires using the node hardware to its fullest (CPU, network, memory, storage)

    This means that the State in Massa evolves almost as fast as typical consumer desktop computers can run blocks, which implies that catching up blocks since genesis goes only slightly faster than new blocks appear in the meantime, and would take a very long time. Moreover, Massa aims at processing thousands of operations per second, which means that it produces a lot of block data every second, thus preventing nodes with the target hardware from storing the full block history and making bootstrapping from genesis impossible since old blocks are forgotten.

    Massa nodes joining the network must therefore bootstrap by downloading the absolute current State.

    Note that nodes can recover from short-term disconnects by asking for missing data from nodes around them once they come back in the network. However, since Massa nodes only store a short history of blocks and forget older ones, it is impossible to recover from long disconnects since the surrounding nodes have forgotten the blocks needed by the recovering node. In that case, a new State bootstrap is required.

    Security model

    The example of Bitcoin

    To understand the security model of node bootstrap, Bitcoin is a good starting example.

    When Bitcoin node runners decide to join the network, they first download the node software from a central source (eg. bitcoin.org). If that source is compromised, the node might end up on a different network, and/or private key theft might happen. Bitcoin therefore requires trust in the entity sourcing the node software.

    Note that optionally, if the nodes don't wish to download the full block history they resort to trusting a more recent "checkpoint" state encoded in the node software. If that state is compromised, the node's knowledge of the whole ledger might be skewed.

    Assuming the node software is not corrupted, new nodes joining the network need an initial list of peer nodes to which they need to connect first in order to discover the network. This list is hardcoded in the node software (see the bitcoin docs). If all peers pointed by this initial list are compromised, the node can end on a different (non-bitcoin) network, even if the node software itself is not compromised. Bitcoin therefore also requires trust in at least one of the initial peers.

    Note that ending up on the wrong network can be detected by checking block hashes with an external source. But this requires trusting yet another source of data.

    The case of Massa

    The Massa case is very similar to Bitcoin's. Node runners also need to trust the source of the node software they download, as well as the initial list of peers.

    Similarly to Bitcoin checkpoints, bootstrapping Massa nodes must obtain the current State from a trusted source, ideally the same source as the one they downloaded the node software from, in order to avoid having to trust multiple entities.

    Downloading the state from an untrusted source can result in major issues such as coin theft. As such, bootstrapping from untrusted sources should be discouraged, and bootstrapping other nodes should be opt-in for node runners to avoid "bootstrap lists" circulating as the default way of bootstrapping from unaware node runners.

    Implementation details

    Procedure from the point of view of the node being bootstrapped

    Massa nodes that bootstrap start by connecting to a randomly chosen node among the ones listed in massa-node/base_config/config.toml.

    The bootstrap process uses a separate port and protocol than the normal Massa peer communication.

    All communications with the chosen bootstrap node are authenticated using the public key (node ID) of the bootstrap node in the config.toml file to prevent man-in-the-middle attacks.

    The node being bootstrapped then attempts to download the current State, as well as an initial list of peers from the bootstrap node.

    Once successfully bootstrapped, the node can then connect to peers, discover the rest of the network, and process live incoming blocks to keep its state up to date.

    In Massa, the hash of the state is used as part of the proof-of-stake seed, which is a safety mechanism against malicious bootstrap nodes sending a compromised State. It ensures that nodes with an altered State eventually end up isolated from the real network because their proof-of-stake draws differ which causes them to discard incoming honest blocks. Note however that a PoS seed mismatch can take up to 2 cycles to be detected.

    In case of bootstrap failure, the bootstrapping node retries with another randomly chosen bootstrap node after a delay.

    Procedure from the point of view of the bootstrap node

    Massa nodes can bootstrap other nodes, with certain limitations because the procedure is heavy for the bootstrap node.

    The bootstrap system listens on the address/port defined in massa-node/base_config/config.toml. The node's bootstrap server can be disabled by removing the bind entry from the config file.

    The Massa State is large (terabytes in the worst case), and takes time to upload to bootstrapping nodes. During that time, new changes to the state continue to appear, so new changes affecting already-uploaded parts need to be sent on-the-fly.

    By default, Massa nodes only allow a whitelist of IP addresses to bootstrap from them. This list is present in the massa-node/base_config/bootstrap_whitelist.json file. This list is intended to prevent flooding attacks by attackers pretending to be bootstrapping, and also makes it more difficult for node runners to bootstrap from untrusted sources. If you wish to disable whitelisting and allow anyone to bootstrap from your node, simply delete the bootstrap_whitelist.json file and restart your node.

    A complementary bootstrap_blacklist.json (absent by default) can also be created alongside bootstrap_whitelist.json (and following the same syntax) in order to explicitly prevent certain IP addresses from bootstrapping from the node.

    Once a node has accepted to bootstrap an incoming node, it adds the incoming node's IP address to a local cache preventing that IP from bootstrapping again for a time defined in massa-node/base_config/config.toml (section bootstrap/per_ip_min_interval) by refusing subsequent connections from that IP during the config-defined delay. The exclusion delay is not extended if the remote IP attempts new connections during the exclusion delay. The exclusion delay is however applied if the bootstrap was accepted but failed for any reason. This aims at limiting the load on individual bootstrap nodes, and spreading the load among bootstrap nodes.

    The number of nodes simultaneously bootstrapping from the local node is limited (massa-node/base_config/config.toml section bootstrap/max_simultaneous_bootstraps). Excess attempts are refused but do not trigger the exclusion delay mechanism.

    Future optimizations

    We plan to add the possibility to download bootstrap data from untrusted sources for load-balancing, but then check the hash of the obtained state from trusted sources, and only fallback to downloading everything from trusted sources if multiple bootstrap attempts from this hybrid approach fail.

    + \ No newline at end of file diff --git a/docs/learn/decentralized-web.html b/docs/learn/decentralized-web.html index 3e8ac555e..0e2cf5715 100644 --- a/docs/learn/decentralized-web.html +++ b/docs/learn/decentralized-web.html @@ -10,7 +10,7 @@ - + @@ -33,8 +33,8 @@ That way, Massa allows deploying fully decentralized code-is-law apps, as it was meant to be!

    Start your decentralized web3 journey now, and install Massa Station. Massa Station allows you to navigate Massa web3 content and to store your own website.

    note

    Note that you would typically not host all assets, images and other non-essential data on-chain, but only the critical functioning parts that need auditing and the subsequent security guarantees. The rest can typically be hosted -on IPFS or some other decentralized storage solution.

    - +on IPFS or some other decentralized storage solution.

    + \ No newline at end of file diff --git a/docs/learn/gas.html b/docs/learn/gas.html index cf3e68951..d34767bd7 100644 --- a/docs/learn/gas.html +++ b/docs/learn/gas.html @@ -10,7 +10,7 @@ - + @@ -46,8 +46,8 @@ When a message is dropped, its coins are reimbursed to the sender but not its fee.

    At each slot S, the autonomous smart contract messages that can be executed at S are picked from the most profitable to the least profitable and executed in that order until their cumulated max_gas reaches MAX_ASYNC_GAS. -Autonomous smart contract messages are removed from the pool once they are executed.

    - +Autonomous smart contract messages are removed from the pool once they are executed.

    + \ No newline at end of file diff --git a/docs/learn/home.html b/docs/learn/home.html index b64665290..c64eca7ad 100644 --- a/docs/learn/home.html +++ b/docs/learn/home.html @@ -10,13 +10,13 @@ - + - + + \ No newline at end of file diff --git a/docs/learn/introduction.html b/docs/learn/introduction.html index 85aa5866b..915e9b92a 100644 --- a/docs/learn/introduction.html +++ b/docs/learn/introduction.html @@ -10,13 +10,13 @@ - +
    -

    What is Massa?

    Massa is a public blockchain built to be scalable, efficient and secure. Massa uses a novel Proof-of-Stake consensus mechanism that massively increases throughput by parallelizing block creation, allowing up to 10'000 transactions per second.

    Massa provides the following key innovations:

    1. Autonomous Smart Contracts: Massa's smart contracts can be programmed to execute autonomously, without the need for any external triggers or oracles.
    2. Decentralized Web: decentralized applications can be hosted entirely on the Massa blockchain, reducing the exposure of dApps to centralized services.
    3. Developer Friendly: Massa's smart contracts are written in TypeScript, a popular programming language that is familiar to many developers.
    - +

    What is Massa?

    Massa is a public blockchain built to be scalable, efficient and secure. Massa uses a novel Proof-of-Stake consensus mechanism that massively increases throughput by parallelizing block creation, allowing up to 10'000 transactions per second.

    Massa provides the following key innovations:

    1. Autonomous Smart Contracts: Massa's smart contracts can be programmed to execute autonomously, without the need for any external triggers or oracles.
    2. Decentralized Web: decentralized applications can be hosted entirely on the Massa blockchain, reducing the exposure of dApps to centralized services.
    3. Developer Friendly: Massa's smart contracts are written in TypeScript, a popular programming language that is familiar to many developers.
    + \ No newline at end of file diff --git a/docs/learn/operation-format-execution.html b/docs/learn/operation-format-execution.html index 1e364012b..abc592d5c 100644 --- a/docs/learn/operation-format-execution.html +++ b/docs/learn/operation-format-execution.html @@ -10,7 +10,7 @@ - + @@ -116,8 +116,8 @@ tracking the state of execution of an operation requires understanding certain principles.

    At the output of an executed slot S, an operation can be in one of the following observable states:

    • EXECUTABLE_OR_EXPIRED: the operation is not in the list of previously executed operations at the output of S:
      • If the operation's expiry date is earlier or equal to the period of S, then the operation can not be executed anymore:
        • The operation might never have been executed previously
        • The operation might have been executed in a slot that finalized more than 10 periods ago. This is because the list of executed operations is pruned to limit its memory usage (see operation execution section).
      • Otherwise, it means that the operation was never executed and can be executed in the future.
    • EXECUTED_WITH_SUCCESS: the operation was executed at or before S and its payload run was successful (see operation execution section). The operation can not be executed anymore.
    • EXECUTED_WITH_FAILURE: the operation was executed at or before S and its payload run generated errors (see operation execution section). The operation can not be executed anymore.

    If the slot S is the latest candidate slot, then the observed status of a given operation at the output of S is considered candidate. As candidate slots are executed, candidate operation states can transition from any state into any other because blockclique changes might happen and rewrite the slot history.

    If the slot S is the latest executed final slot, then the observed status of a given operation at the output of S is considered final. As final slots are executed, the following final operation state transitions can be observed:

    • EXECUTABLE_OR_EXPIRED -> EXECUTED_WITH_SUCCESS: the operation was executed as final with success
    • EXECUTABLE_OR_EXPIRED -> EXECUTED_WITH_FAILURE: the operation was executed as final with failure
    • EXECUTED_WITH_SUCCESS -> EXECUTABLE_OR_EXPIRED: the operation was executed as final with success and then it expired and was pruned away
    • EXECUTED_WITH_FAILURE -> EXECUTABLE_OR_EXPIRED: the operation was executed as final with failure and then it expired and was pruned away

    Operations are guaranteed to be kept in the EXECUTED_WITH_SUCCESS or EXECUTED_WITH_FAILURE state for at least 10 periods (2 minutes and 40 seconds) -to give enough time for operators to register those states before they are pruned.

    - +to give enough time for operators to register those states before they are pruned.

    + \ No newline at end of file diff --git a/docs/learn/storage-costs.html b/docs/learn/storage-costs.html index 51d301aa9..080c4b570 100644 --- a/docs/learn/storage-costs.html +++ b/docs/learn/storage-costs.html @@ -10,7 +10,7 @@ - + @@ -41,8 +41,8 @@ 0.0001 * (4 + 8 + 6) = 0.0018 coins are refunded.

    info

    In the case of a refund for storage costs, the address that receives the refund is the one that initiates the ABI call (setBytecode or setBycodeOf for example), which may differ from the address that initially paid for the storage.

    If you are a Smart Contract developer and want your users to cover the storage costs for your contract, you can utilize the coins passed via the "coins" parameter of the "CallSC" operation. -Additionally, you can save their addresses in your datastore to facilitate future refunds.

    - +Additionally, you can save their addresses in your datastore to facilitate future refunds.

    + \ No newline at end of file diff --git a/docs/learn/tokenomics.html b/docs/learn/tokenomics.html index c99338f23..18fda5dff 100644 --- a/docs/learn/tokenomics.html +++ b/docs/learn/tokenomics.html @@ -10,15 +10,15 @@ - +

    Massa Tokenomics

    Introduction

    note

    This page reproduces most of the whitepaper's Tokenomics section, with additional details and updates.

    Massa, true to its values, has implemented a unique tokenomics model that emphasizes fairness and decentralization. This model ensures that the Massa token is distributed widely among the community, reducing the risk of centralization that can result in unfair voting practices, price manipulation, and security issues:

    • Unfairly-distributed voting: When a small number of entities control a significant portion of a blockchain's tokens, they can disproportionately influence governance decisions, undermining the democratic principles that underpin decentralized systems.
    • Price manipulation: Token centralization can also lead to price manipulation, as large holders can exert undue influence on the market, creating artificial fluctuations that distort the true value of the token.
    • Security issues: A centralized token distribution can lead to security vulnerabilities, as malicious actors can target the limited number of entities controlling a large portion of the token supply. It also generates centralization in block production, leading to protocol-level risks.

    Massa is committed to maintaining the highest standards of decentralization, with the goal to achieve a Nakamoto coefficient of over 1,000, ensuring that control and decision-making power are widely distributed across the community. Achieving this not only requires efforts on the technical and legal design, but also on the coin distribution. On this aspect, we crafted three main particularities compared to other L1 blockchain coin distributions:

    • Less tokens for the company/founders: Massa Labs and founders are allocated 12% of the total supply.
    • Less tokens for insiders: The maximum number of tokens bought per entity in all ourtoken sales is relatively small. For instance, the cap was 1% of the total supply in the seed sale, allowing a record number of 100 backers in such a sale. Also, the supply allocated to these private sales is only 16% in total.
    • More tokens for future builders and stakers: the Decentralization Program sets aside 30% of the supply to grow the future builders and stakers community, with the aim to achieve full decentralization in a transparent way.

    These steps together improve the token decentralization, limit the influence of early insiders and VCs, and limit the formation of whales whose only remaining option is to buy on the market.

    Initial Coin Distribution

    The total initial token supply is 1,000,000,000 Massa tokens. These initial tokens are created in the genesis ledger. They are distributed as follows.

    • Massa Labs & Founders: 12%, 120,000,000 tokens. This allocation goes to the team, the founders and a reserve for Massa Labs, to ensure that the main development team is invested in the project's long-term success. These coins are vested linearly for 60 months, with a 5% initial unlock.
    • Private Sales: Up to 16%, 160,000,000 tokens. These coins are vested linearly for 24 months, with a 30% initial unlock.
    • Community and Ecosystem: 31%, 310,000,000 tokens. This allocation is managed by the Massa Foundation. Its purpose is to foster the growth of the Massa community and ecosystem in the long term through grants, marketing actions, partnerships and other programs. These coins are vested linearly for 60 months, with a 5% initial unlock.
    • Testnet Incentive Program: up to 8%, 80,000,000 tokens. The Testnet Incentive Program rewards the thousands of node runners who successfully participated in the testnet. These coins are vested linearly for 24 months, with a 30% initial unlock.
    • Public Sale: 3%, 30,000,000 tokens. These coins are going to be vested for some time, cf future updates.
    • Decentralization Program: 30%, 300,000,000 tokens. In the initial ledger, these coins are vested for 60 months with a 24-month cliff and then 36 months linear. Tokens not distributed after 96 months will be burnt. They are composed of:
    • 100k-nodes Program: 20%, 200,000,000 tokens. The goal of this pool is to grow the number of individual stakers participating in the security of the network and in the core governance. Compared to the coin distribution of other L1s biased towards insiders who later sell large chunks in opaque deals or on the market, this alternative mechanism provides more transparency and decentralization. This pool, managed by the Foundation, is dedicated to be bought by new node runners with a low cap per person and at a slow pace between 2 and 8 years post-mainnet, with vesting.
    • 2k-builders Program: 10%, 100,000,000 tokens. The goal of this program is to grow a larger builder community with many grants, involving the Massa holders in the decisions to give grants. These grants have a smaller size than with the main grant program: they are capped at 50k tokens per project.

    Nakamoto Coefficient

    With this data, we can compute the Nakamoto coefficient of the coin after full distribution. The Nakamoto coefficient is computed as the minimum number of independent entities/persons required to reach 50% of the total supply. We take the most concentrated categories and count the expected number of entities/people until we reach 50%:

    • Massa Labs: 12%, at least 100 people
    • Private sales: 16%, at least 100 people
    • Community and Ecosystem: expecting 1,000+ people in the first 22%.

    Thanks to the fair distribution with smaller pools for insiders and larger pools dedicated to the community, the Nakamoto coefficient of Massa aims to be well over 1,000 on the long-term when all the categories are distributed. On the short-term, only parts of these categories will be effectively distributed. The next section describes the distribution right on mainnet launch.

    Genesis Ledger

    The genesis ledger is the initial distribution of coins when the network starts. Some of these coins appear as initial rolls instead of tokens (1 roll = 100 tokens) giving the ability to stake right from launch.

    The genesis ledger files have been set up in this GitHub folder.

    The total number of tokens in initial_ledger.json, initial_rolls.json (x100 tokens per roll), and deferred_credits.json is exactly 1,000,000,000. These files have been generated with a script, from this data, where you can find the following:

    • backers.json: backers of Massa Labs who gave their addresses in time. Backers who did not provide their addresses have their coins kept in address AU1PGvG4x1rmFaYBgSNVmgpPDkWvGtNqS2Jc7BjupmVjkce8dBai for now.
    • dashboard_data.json: here you can find participants of the dashboard campaign, ambassadors, and testnet node runners who were eligible for a reward, with corresponding coins and if they want to be initial stakers. These tokens are vested for 24 months, with a 30% initial unlock, and the release is approximately once per month, with some random noise to smooth the unlockings (e.g. on month 3, a user might get tokens released on day 3 while another gets tokens on day 10).
    • foundation.json: here are the three main addresses of the Massa Foundation. The first corresponds to the 310,000,000 tokens from category "Community and Ecosystem", from which above rewards were deducted. These tokens are vested for 60 months. The second is reserved for a public sale. These tokens are unlocked for now, but they are going to move to a vested smart contract for users to claim their tokens. The third address is the decentralization program address, with 2 years cliff and then 3 years linear vesting.
    • founders.json is an allocation reserved for founders. These tokens are unlocked at genesis and will be moved just after launch to a vested smart contract where tokens will be claimable, with 5% initially unlocked and 95% vested for 60 months.
    • labs.json. These are Massa Labs' tokens, with 5% as initial rolls to start staking right from launch, together with the community, and the other 95% vested for 60 months. Massa Labs will thus start staking with 35,000 rolls. This is a large proportion of the total stake at launch, but it is expected to decrease significantly in the next days and weeks after launch when all other categories will ramp up with setting up their nodes.

    Expected Unlocked Supply

    Taking into account the vesting schedules of all categories, we can estimate the evolution of the unlocked supply. Note that many of these unlocked tokens will not be effectively circulating, because they will be held as reserves by Massa Labs and Massa Foundation. -This figure does not account for staking rewards (see next section).

    Staking Rewards

    Staking is the process of running a validator node verifying the blockchain and creating blocks. In Massa as in other Proof-of-Stake blockchains, nodes are selected to create blocks based on their deposited coins –their stake in the blockchain.

    As staking improves the decentralization and security of the network, this behavior is incentivized by staking rewards: the higher the number of staked coins, the higher the number of created blocks and received rewards.

    To improve decentralization and dedicate rewards to independent node runners, there is no delegation mechanism in Massa, and custodial staking is limited by the community charter.

    A minimum number of coins must be deposited to be able to stake, corresponding to one roll. The number of coins in a roll is set to 100. Users deposit coins to get a number of rolls and stake with these rolls. When they want to stop staking, they can get back their coins after a small locking period and lose the corresponding rolls. When the staking address is selected to produce a block, the node is expected to produce exactly one block.

    If the node is offline for some reason, it misses the opportunity to produce the block and to get the reward. If the node is missing these opportunities too often, it is automatically deactivated and its rolls are sold and fully given back as coins. If the node produces more than one block in a selected slot, this is considered as bad behavior and is punished with slashing: one roll is slashed, completely lost and no coins are given back.

    At each slot, one staking address is selected to produce a block, and in order to improve consensus speed, 16 other addresses are selected to create endorsements —votes about the best blocks. A maximum minted reward of 1.02 tokens is distributed per slot. If there was a block in this slot, the reward is distributed as follows:

    • 0.06 tokens are given to the block creator
    • For each endorsement included in the block (up to 16)
      • 0.02 tokens are given to the block creator
      • 0.02 tokens are given to the endorsement creator
      • 0.02 tokens are given to the creator of the endorsed block

    Block and endorsement creators also share the gas fees of all transactions included in the block, and half of the slashed coins, the other half being burnt. However, all the fees of autonomous smart contracts are burnt as they run outside blocks.

    There are 2 slots per second in Massa architecture, so these rewards add up to a maximum of 64,377,504 newly-minted Massa tokens per year, distributed to active staking nodes. The inflation rate is therefore approximately 6.4% during the first year, and decreases each year as the total supply increases.

    As less than the total supply is expected to be staking at any point in time, the actual return per year for active stakers will be higher than this percentage. The next figure shows the maximum inflation rate and an estimation of the annual percentage return (APR) for staking nodes over time.

    Example: How to compute my expected staking rewards ?

    Let's assume I currently have 20 initial rolls from genesis, and after launch I buy 3 other rolls, that's 23 rolls in total, equivalent to 2,300 tokens, that I currently use to stake with my node.

    I can monitor the total number of rolls currently staked on the network on the Massa explorer. Let's assume I see that 500,000 rolls are staked (low number, maybe only in the first weeks after mainnet). I thus produce 0,0046% of blocks and endorsements.

    There are 172,800 blocks per day, so I expect to produce 8 blocks per day on average, but also approximately 127 endorsements per day. The maximum rewards given per block is 1.02 tokens (for block and endorsement producers), which is 176,256 tokens per day. Thus I can expect 176,256 * 0,0046% = 8.1 tokens per day for my 23 rolls, assuming 500,000 rolls are staked in total, and assuming I am always online and I don't miss a block!

    These rewards do not take into account potential gas fees that will be set by users if the network becomes congested one day.

    The staking rewards are unlocked, so after 13 days, I should have 105 tokens and I will be able to buy a 24th roll!

    - +This figure does not account for staking rewards (see next section).

    Staking Rewards

    Staking is the process of running a validator node verifying the blockchain and creating blocks. In Massa as in other Proof-of-Stake blockchains, nodes are selected to create blocks based on their deposited coins –their stake in the blockchain.

    As staking improves the decentralization and security of the network, this behavior is incentivized by staking rewards: the higher the number of staked coins, the higher the number of created blocks and received rewards.

    To improve decentralization and dedicate rewards to independent node runners, there is no delegation mechanism in Massa, and custodial staking is limited by the community charter.

    A minimum number of coins must be deposited to be able to stake, corresponding to one roll. The number of coins in a roll is set to 100. Users deposit coins to get a number of rolls and stake with these rolls. When they want to stop staking, they can get back their coins after a small locking period and lose the corresponding rolls. When the staking address is selected to produce a block, the node is expected to produce exactly one block.

    If the node is offline for some reason, it misses the opportunity to produce the block and to get the reward. If the node is missing these opportunities too often, it is automatically deactivated and its rolls are sold and fully given back as coins. If the node produces more than one block in a selected slot, this is considered as bad behavior and is punished with slashing: one roll is slashed, completely lost and no coins are given back.

    At each slot, one staking address is selected to produce a block, and in order to improve consensus speed, 16 other addresses are selected to create endorsements —votes about the best blocks. A maximum minted reward of 1.02 tokens is distributed per slot. If there was a block in this slot, the reward is distributed as follows:

    • 0.06 tokens are given to the block creator
    • For each endorsement included in the block (up to 16)
      • 0.02 tokens are given to the block creator
      • 0.02 tokens are given to the endorsement creator
      • 0.02 tokens are given to the creator of the endorsed block

    Block and endorsement creators also share the gas fees of all transactions included in the block, and half of the slashed coins, the other half being burnt. However, all the fees of autonomous smart contracts are burnt as they run outside blocks.

    There are 2 slots per second in Massa architecture, so these rewards add up to a maximum of 64,377,504 newly-minted Massa tokens per year, distributed to active staking nodes. The inflation rate is therefore approximately 6.4% during the first year, and decreases each year as the total supply increases.

    As less than the total supply is expected to be staking at any point in time, the actual return per year for active stakers will be higher than this percentage. The next figure shows the maximum inflation rate and an estimation of the annual percentage return (APR) for staking nodes over time.

    Example: How to compute my expected staking rewards ?

    Let's assume I currently have 20 initial rolls from genesis, and after launch I buy 3 other rolls, that's 23 rolls in total, equivalent to 2,300 tokens, that I currently use to stake with my node.

    I can monitor the total number of rolls currently staked on the network on the Massa explorer. Let's assume I see that 500,000 rolls are staked (low number, maybe only in the first weeks after mainnet). I thus produce 0,0046% of blocks and endorsements.

    There are 172,800 blocks per day, so I expect to produce 8 blocks per day on average, but also approximately 127 endorsements per day. The maximum rewards given per block is 1.02 tokens (for block and endorsement producers), which is 176,256 tokens per day. Thus I can expect 176,256 * 0,0046% = 8.1 tokens per day for my 23 rolls, assuming 500,000 rolls are staked in total, and assuming I am always online and I don't miss a block!

    These rewards do not take into account potential gas fees that will be set by users if the network becomes congested one day.

    The staking rewards are unlocked, so after 13 days, I should have 105 tokens and I will be able to buy a 24th roll!

    + \ No newline at end of file diff --git a/docs/massaStation/browse-decentralized-application.html b/docs/massaStation/browse-decentralized-application.html index 36ec264f7..0aae14285 100644 --- a/docs/massaStation/browse-decentralized-application.html +++ b/docs/massaStation/browse-decentralized-application.html @@ -10,13 +10,13 @@ - +
    -

    Browse Decentralized Application

    Browse Decentralized Application

    Massa Station enables you to browse decentralized applications (dApps) hosted on the blockchain and interact with them.

    Browsing Steps

    1. Open Massa Station.
    2. Click on the Search Massa ecosystem button.

    Search Massa ecosystem

    1. Search for the website you want to browse.

    Scroll websites

    1. Click on it to open it in your web browser.
    - +

    Browse Decentralized Application

    Browse Decentralized Application

    Massa Station enables you to browse decentralized applications (dApps) hosted on the blockchain and interact with them.

    Browsing Steps

    1. Open Massa Station.
    2. Click on the Search Massa ecosystem button.

    Search Massa ecosystem

    1. Search for the website you want to browse.

    Scroll websites

    1. Click on it to open it in your web browser.
    + \ No newline at end of file diff --git a/docs/massaStation/faq.html b/docs/massaStation/faq.html index 5eef14dc7..66d433751 100644 --- a/docs/massaStation/faq.html +++ b/docs/massaStation/faq.html @@ -10,7 +10,7 @@ - + @@ -24,8 +24,8 @@ In that case, you can make it the default node by changing the Default field to true, and change the default field for the mainnet node to false.

    After these lines are added, close and reopen Massa Station. Your newly named node will now be a part of the network selection dropdown menu. Selecting it will connect Massa Station and its plugins, such as Massa Wallet, to your specified node.

    For those whose nodes are on the MainNet, it's essential that the ChainID accurately reflects the MainNet's chain ID, -By ensuring the correct ChainID is set, your Massa Station will be in sync with the intended network.

    Why can't I access Massa Station from my browser?

    Massa Station must be installed and running on your computer to be able to access it from your browser. If you have installed Massa Station, please make sure it is running.

    If Massa Station is running, please check that you are using the correct URL. The URL should be https://station.massa/.

    If you are still having trouble accessing Massa Station, please check the troubleshooting page for help.

    "Install" module button doesn't work. What to do?

    This is a known issue that happens when a module is stored on GitHub. We are investigating the issue.

    In the meantime, you can install the module manually by following the instructions on the right panel of the module store.

    For example with the Massa Wallet module:

    1. Go to the latest Massa Wallet release page.
    2. Copy the URL of the .zip file corresponding to your operating system.
    3. Paste the URL in the right panel of the module store and click on "Install".

    Why isn't Massa Station working on Safari?

    Massa Station is only available in HTTP on Safari. Supporting HTTPS on Safari is on our roadmap but we don't have an ETA yet.

    To use Massa Station in HTTP on Safari, simply modify the URL to http://station.massa/ (or click on the link).

    How to enable HTTPS on unsupported browsers?

    To enable HTTPS on unsupported browsers, you need to install the Massa Station certificate authority.

    1. Locate the certificate authority file at the following path:
      • On Windows, follow those steps:
        1. Copy this path: C:\Program Files (x86)\MassaStation\certs\
          caution

          The path might be different if you changed Massa Station location

        2. Open the File Explorer
        3. Paste the path you copied previously in the address bar
        4. Press enter
      • On Macos, follow those steps:
        1. Copy this path: /etc/massastation/certs/
        2. Open finder
        3. Click on the "Go" button at the top left of your screen
        4. Click on the "Go to folder..." button at the bottom of the menu
        5. Paste the path you copied previously
        6. Press enter
      • On Linux, the file is located in /etc/massastation/certs/
    2. In this folder, you will find a file named rootCA.pem. Keep this folder open, you will need it in the next steps.
    3. Open your browser's settings or preferences.
    4. Search for the "Security" or "Privacy" section, and look for an option related to certificates.
    5. Find the option to import or add a certificate authority.
    6. Choose the rootCA.pem file from the specified path.

    Massa Wallet installation

    How to solve a Wallet can't be opened issue?

    It depends on your OS and its configuration, please check the troubleshooting page

    - +By ensuring the correct ChainID is set, your Massa Station will be in sync with the intended network.

    Why can't I access Massa Station from my browser?

    Massa Station must be installed and running on your computer to be able to access it from your browser. If you have installed Massa Station, please make sure it is running.

    If Massa Station is running, please check that you are using the correct URL. The URL should be https://station.massa/.

    If you are still having trouble accessing Massa Station, please check the troubleshooting page for help.

    "Install" module button doesn't work. What to do?

    This is a known issue that happens when a module is stored on GitHub. We are investigating the issue.

    In the meantime, you can install the module manually by following the instructions on the right panel of the module store.

    For example with the Massa Wallet module:

    1. Go to the latest Massa Wallet release page.
    2. Copy the URL of the .zip file corresponding to your operating system.
    3. Paste the URL in the right panel of the module store and click on "Install".

    Why isn't Massa Station working on Safari?

    Massa Station is only available in HTTP on Safari. Supporting HTTPS on Safari is on our roadmap but we don't have an ETA yet.

    To use Massa Station in HTTP on Safari, simply modify the URL to http://station.massa/ (or click on the link).

    How to enable HTTPS on unsupported browsers?

    To enable HTTPS on unsupported browsers, you need to install the Massa Station certificate authority.

    1. Locate the certificate authority file at the following path:
      • On Windows, follow those steps:
        1. Copy this path: C:\Program Files (x86)\MassaStation\certs\
          caution

          The path might be different if you changed Massa Station location

        2. Open the File Explorer
        3. Paste the path you copied previously in the address bar
        4. Press enter
      • On Macos, follow those steps:
        1. Copy this path: /etc/massastation/certs/
        2. Open finder
        3. Click on the "Go" button at the top left of your screen
        4. Click on the "Go to folder..." button at the bottom of the menu
        5. Paste the path you copied previously
        6. Press enter
      • On Linux, the file is located in /etc/massastation/certs/
    2. In this folder, you will find a file named rootCA.pem. Keep this folder open, you will need it in the next steps.
    3. Open your browser's settings or preferences.
    4. Search for the "Security" or "Privacy" section, and look for an option related to certificates.
    5. Find the option to import or add a certificate authority.
    6. Choose the rootCA.pem file from the specified path.

    Massa Wallet installation

    How to solve a Wallet can't be opened issue?

    It depends on your OS and its configuration, please check the troubleshooting page

    + \ No newline at end of file diff --git a/docs/massaStation/guidelines.html b/docs/massaStation/guidelines.html index a5a30db4f..68a4aee42 100644 --- a/docs/massaStation/guidelines.html +++ b/docs/massaStation/guidelines.html @@ -10,14 +10,14 @@ - +

    Plugin Creation Guidelines

    One of the advantages of Massa Station is its flexibility in allowing plugins to be developed in any programming language. In order for modules to work with Massa Station, they must adhere to specific guidelines and specifications.

    Plugin Overview

    Massa Station plugins are essentially binaries with a few specific requirements, as defined in this document.

    Since Massa Station plugins are binaries, developers have the freedom to use their preferred programming language to create plugins that work seamlessly with Massa Station. Most of our Massa Station products and documentation are using Go because it's the language we use internally. However, we encourage developers to use any language they prefer.

    For detailed steps on creating a plugin, please refer to the create plugin guide.

    Plugin binary specifications

    When Massa Station starts a plugin, it generates a unique ID for the plugin and passes it as a parameter to the plugin binary. Once the plugin has started, it must register itself to Massa Station to confirm that it is running properly.

    Plugins are started as follows:

    ./plugin-binary <PLUGIN-ID>

    At startup, the plugin must retrieve the plugin ID from the command line arguments. -Following the startup, the plugin must register itself by calling the /plugin-manager/register endpoint of Massa Station, providing the assigned ID.

    info

    Massa Station will respond with a 204 status code if the registration is successful. In case of failure, the plugin must exit with a non-zero exit code.

    Plugin Packaging

    To be installed in Massa Station, a plugin must be packaged as a Zip Archive, tailored for each targeted operating system.

    Supported OS Configurations

    Currently, Massa Station supports the following OS configurations:

    • Windows 10/11, AMD64
    • Linux, AMD64
    • macOS, AMD64
    • macOS, ARM64

    Archive Structure

    A plugin Zip Archive must contain the following files and adhere to the specified structure:

    1. Plugin Binary: The plugin's binary, withch should follow the statdards

    2. Logo: The archive must include a valid image file that serves as the plugin's logo. Refer to the Mozilla Developer Network for valid image formats.

      tip

      This logo will be displayed in the Massa Station interface. To ensure a good user experience, we recommend using a square image with a minimum size of 128x128 pixels.

    3. Manifest: The plugin must have a manifest.json file at the root of the Zip Archive. This manifest provides essential information to Massa Station for displaying the plugin in the user interface. The manifest.json file must include the following properties:

      FieldDescriptionFormatSpecifications
      AuthorModule author's nametextMaximum 30 characters
      NameModule nametextMaximum 30 characters
      DescriptionModule short description texttextMaximum 80 characters
      LogoModule logo file nametextExample: logo.png
      HomeURL to module home pageURLFormat: http(s)://example.com
      VersionModule versiontextFollow Semantic Versioning 2.0
      APIspecAPI specificationstextSwagger file
      info

      See the example manifest of the Hello-World plugin: Hello-World Manifest

    4. Optional: Additional Resources: Any additional resources for the plugin such as configuration files, images, etc.

    - +Following the startup, the plugin must register itself by calling the /plugin-manager/register endpoint of Massa Station, providing the assigned ID.

    info

    Massa Station will respond with a 204 status code if the registration is successful. In case of failure, the plugin must exit with a non-zero exit code.

    Plugin Packaging

    To be installed in Massa Station, a plugin must be packaged as a Zip Archive, tailored for each targeted operating system.

    Supported OS Configurations

    Currently, Massa Station supports the following OS configurations:

    • Windows 10/11, AMD64
    • Linux, AMD64
    • macOS, AMD64
    • macOS, ARM64

    Archive Structure

    A plugin Zip Archive must contain the following files and adhere to the specified structure:

    1. Plugin Binary: The plugin's binary, withch should follow the statdards

    2. Logo: The archive must include a valid image file that serves as the plugin's logo. Refer to the Mozilla Developer Network for valid image formats.

      tip

      This logo will be displayed in the Massa Station interface. To ensure a good user experience, we recommend using a square image with a minimum size of 128x128 pixels.

    3. Manifest: The plugin must have a manifest.json file at the root of the Zip Archive. This manifest provides essential information to Massa Station for displaying the plugin in the user interface. The manifest.json file must include the following properties:

      FieldDescriptionFormatSpecifications
      AuthorModule author's nametextMaximum 30 characters
      NameModule nametextMaximum 30 characters
      DescriptionModule short description texttextMaximum 80 characters
      LogoModule logo file nametextExample: logo.png
      HomeURL to module home pageURLFormat: http(s)://example.com
      VersionModule versiontextFollow Semantic Versioning 2.0
      APIspecAPI specificationstextSwagger file
      info

      See the example manifest of the Hello-World plugin: Hello-World Manifest

    4. Optional: Additional Resources: Any additional resources for the plugin such as configuration files, images, etc.

    + \ No newline at end of file diff --git a/docs/massaStation/hello-world-plugin.html b/docs/massaStation/hello-world-plugin.html index 5833202ad..10e45488e 100644 --- a/docs/massaStation/hello-world-plugin.html +++ b/docs/massaStation/hello-world-plugin.html @@ -10,7 +10,7 @@ - + @@ -34,8 +34,8 @@ So go ahead and create the file endpoints.go in the my-plugin/web folder and add the following code:

    package web

    import (
    "mime"
    "net/http"
    "path/filepath"

    "github.com/go-openapi/runtime/middleware"
    "my-plugin/api/server/restapi/operations"
    "github.com/massalabs/station-massa-wallet/pkg/openapi"
    )

    // webHandle handles a Web request.
    func Handle(params operations.WebParams) middleware.Responder {
    resourceName := params.Resource

    resourceContent, err := Content(resourceName) // reads the content of the html file
    if err != nil {
    return operations.NewWebNotFound()
    }

    fileExtension := filepath.Ext(resourceName)

    mimeType := mime.TypeByExtension(fileExtension) // gets the mime type of the file

    header := map[string]string{"Content-Type": mimeType}

    return openapi.NewCustomResponder(resourceContent, header, http.StatusOK) // returns the content of the html file
    }

    // defaultRedirectHandler redirects request to "/" URL to "web/index.html".
    func DefaultRedirectHandler(_ operations.DefaultPageParams) middleware.Responder {
    return openapi.NewCustomResponder(nil, map[string]string{"Location": "web/index.html"}, http.StatusPermanentRedirect) // redirects to the html file
    }

    As you can see, we imported the github.com/massalabs/station-massa-wallet/pkg/openapi package. This package contains the NewCustomResponder function that allows us to return a custom response. Go ahead and install the package with the following command:

    go get github.com/massalabs/station-massa-wallet/pkg/openapi

    Register the handler

    Then, we need to add the handler to the initializeAPI function:

        ...
    pluginAPI.WebHandler = operations.WebHandlerFunc(web.Handle)
    pluginAPI.DefaultPageHandler = operations.DefaultPageHandlerFunc(web.DefaultRedirectHandler)
    ...

    So open the my-plugin.go file and replace the current content of the initializeAPI function with the following code snippet:

    func initializeAPI() *restapi.Server {
    swaggerSpec, err := loads.Analyzed(restapi.SwaggerJSON, "")
    if err != nil {
    panic(err)
    }

    pluginAPI := operations.NewHelloWorldAPI(swaggerSpec)
    server := restapi.NewServer(pluginAPI)

    pluginAPI.WebHandler = operations.WebHandlerFunc(web.Handle)
    pluginAPI.DefaultPageHandler = operations.DefaultPageHandlerFunc(web.DefaultRedirectHandler)
    pluginAPI.HelloHandler = operations.HelloHandlerFunc(api.Hello)

    server.ConfigureAPI()

    return server
    }

    As you can see, we are using the web package we created in the previous step. So make sure you import it in the my-plugin.go file. Your import section should look like this:

    import (
    "fmt"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"

    "my-plugin/api"
    "my-plugin/api/server/restapi"
    "my-plugin/api/server/restapi/operations"
    "my-plugin/web"

    "github.com/go-openapi/loads"
    "github.com/rs/cors"

    "github.com/massalabs/station-massa-hello-world/pkg/plugin"
    )

    Re-build and re-deploy the plugin

    As we already did in the previous sections, we are going to re-build and re-deploy the plugin. Start by building the binary with the following command:

    go build -o build/my-plugin

    Then, move the binary, to the Massa Station plugin folder. The location of the Massa Station plugin folder depends on your operating system.

    note

    To copy the files, you should make sure that Massa Station is not running.

    On linux or macOS:

    cp build/my-plugin /usr/local/share/massastation/plugins/my-plugin
    cp web/content/index.html /usr/local/share/massastation/plugins/my-plugin

    On Windows, you can use the following commands in the PowerShell:

    # Copy the files
    $sourceDir = "build\my-plugin"
    Copy-Item $sourceDir\my-plugin $destinationDir -Force

    $sourceDir = "web\content"
    Copy-Item $sourceDir\index.html $destinationDir -Force

    Restart Massa Station and access the module page

    Restart Massa Station and access the module page. You should see the plugin in the list of available plugins. -Click on the plugin to launch it. You should see the "Hello, World!" page.

    Hello world page

    Congratulations! You have successfully created your first Massa Station plugin!

    - +Click on the plugin to launch it. You should see the "Hello, World!" page.

    Hello world page

    Congratulations! You have successfully created your first Massa Station plugin!

    + \ No newline at end of file diff --git a/docs/massaStation/home.html b/docs/massaStation/home.html index 6c4aff4eb..845448907 100644 --- a/docs/massaStation/home.html +++ b/docs/massaStation/home.html @@ -10,7 +10,7 @@ - + @@ -28,8 +28,8 @@ mind; indeed, it allows anyone to develop and install their own modules. The most looked upon modules in terms of community adoption, and upon audit, will be made publicly available through the Massa Plugin Store. We greatly encourage our community to develop their own modules, as we believe that the Massa Station ecosystem will be the key to the -adoption of the Massa Blockchain.

    Get Started

    Build on Massa Station

    Other Resources

    - +adoption of the Massa Blockchain.

    Get Started

    Build on Massa Station

    Other Resources

    + \ No newline at end of file diff --git a/docs/massaStation/install.html b/docs/massaStation/install.html index 06b36aa4f..c60660da0 100644 --- a/docs/massaStation/install.html +++ b/docs/massaStation/install.html @@ -10,15 +10,15 @@ - +

    Install

    System Requirements

    • Operating System:
      • Windows 10 and 11
      • MacOS 13 and above
      • Debian-based Linux distributions: Ubuntu 22.04 and later, Debian 11 and later...
    • Disk Space: At least 200 MB
    • RAM: At least 2 GB
    • Web Browser: Firefox or Chromium-based browsers (Chrome, Brave, etc.)

    To install Massa Station, follow these steps:

    1. Visit the Massa Station website.
    2. Click the Download button and select the version compatible with your operating system.
    3. Once the download is complete, run the installer and follow the instructions.
    info

    During the installation process, you will be prompted to grant permissions to Massa Station. These permissions are necessary for Massa Station to function correctly.

    note

    If you prefer to install Massa Station manually, you can follow the instructions provided in the Manual Install section.

    Windows

    1. Locate the downloaded .msi installer file and double-click on it to start the installation process.
    2. Follow the on-screen instructions to proceed with the installation.
    3. You will be prompted to choose the kind of installation you want. We recommend choosing the "Complete" installation as it will install all the necessary dependencies to access web on-chain. If you select the "Typical" option, Massa Station will be installed without DNS configuration. In that case, access to .massa domains may be restricted.
    4. Once the installation is complete, you can launch Massa Station from the Start menu.
    5. If prompted, click on "Yes" to allow the installer to make changes on certificates. These certificates allow Massa Station to use the HTTPS protocol, which improves your security when browsing dApp.
    info

    If you experience any issues during the installation process or while using Massa Station, please refer to the FAQ.

    caution

    If you are using a version of Massa Station older than 0.3.6, Windows will warn you about untrusted software. -You can safely ignore this warning and proceed with the installation by clicking on "more info" and "run anyway".

    MacOS

    1. Locate the downloaded .pkg installer file. Hold "Option" key on the keyboard and right-click on the package, at the same time.
    2. From the context menu, select "Open" and then click "Open" again in the security pop-up window. This step is necessary because the installer is not signed by the App Store, and MacOS may block the installation by default.
    3. If prompted, enter your administrator password to authorize the installation.
    4. Follow the on-screen instructions to proceed with the installation.
    info

    If you experience any issues during the installation process or while using Massa Station, please refer to the FAQ.

    Debian Linux

    Terminal Installation using apt

    1. Locate the downloaded .deb installer file.
    2. Open a terminal on your Debian Linux system.
    3. Navigate to the directory where the downloaded .deb package is located.
    4. Run the following command to install the package:
      sudo apt install ./massastation-${{ VERSION }}_amd64.deb
    5. Enter your administrator password when prompted and press Enter to confirm.
    6. The installation will begin, and you will see progress information in the terminal.
    7. Once the installation is complete, you can close the terminal.
    info

    If you experience any issues during the installation process or while using Massa Station, please refer to the FAQ.

    GUI Installation

    caution

    Terminal installation method is preferred over linux GUI detailed below.

    1. Open your file manager and navigate to the location where the .deb package is saved.
    2. Right-click on the .deb package and choose "Open with Software Install" or a similar option.
    3. The package manager will launch and display Massa Station installation page.
    4. Review the package information and dependencies, if any, and click on the "Install" button.
    5. If prompted, enter your administrator password to authorize the installation.
    6. The installation will commence, and you will see a progress bar indicating the status.
    7. Once the installation is complete, you will receive a notification confirming the successful installation.
    info

    If you experience any issues during the installation process or while using Massa Station, please refer to the FAQ.

    Updating on Linux

    There is a known issue involving version checks while updating Massa Station via Software Installer, follow these instructions for best results.

    1. Download the latest version of Massa Station installer for Debian Linux (.deb) from here.
    2. Open your file manager and navigate to the location where the .deb package is saved.
    3. The package manager will launch and display Massa Station installation page.
    4. Review the package information and dependencies, if any, and click on the red "Delete" button.
    5. Proceed to GUI installation starting at step 2.
    - +You can safely ignore this warning and proceed with the installation by clicking on "more info" and "run anyway".

    MacOS

    1. Locate the downloaded .pkg installer file. Hold "Option" key on the keyboard and right-click on the package, at the same time.
    2. From the context menu, select "Open" and then click "Open" again in the security pop-up window. This step is necessary because the installer is not signed by the App Store, and MacOS may block the installation by default.
    3. If prompted, enter your administrator password to authorize the installation.
    4. Follow the on-screen instructions to proceed with the installation.
    info

    If you experience any issues during the installation process or while using Massa Station, please refer to the FAQ.

    Debian Linux

    Terminal Installation using apt

    1. Locate the downloaded .deb installer file.
    2. Open a terminal on your Debian Linux system.
    3. Navigate to the directory where the downloaded .deb package is located.
    4. Run the following command to install the package:
      sudo apt install ./massastation-${{ VERSION }}_amd64.deb
    5. Enter your administrator password when prompted and press Enter to confirm.
    6. The installation will begin, and you will see progress information in the terminal.
    7. Once the installation is complete, you can close the terminal.
    info

    If you experience any issues during the installation process or while using Massa Station, please refer to the FAQ.

    GUI Installation

    caution

    Terminal installation method is preferred over linux GUI detailed below.

    1. Open your file manager and navigate to the location where the .deb package is saved.
    2. Right-click on the .deb package and choose "Open with Software Install" or a similar option.
    3. The package manager will launch and display Massa Station installation page.
    4. Review the package information and dependencies, if any, and click on the "Install" button.
    5. If prompted, enter your administrator password to authorize the installation.
    6. The installation will commence, and you will see a progress bar indicating the status.
    7. Once the installation is complete, you will receive a notification confirming the successful installation.
    info

    If you experience any issues during the installation process or while using Massa Station, please refer to the FAQ.

    Updating on Linux

    There is a known issue involving version checks while updating Massa Station via Software Installer, follow these instructions for best results.

    1. Download the latest version of Massa Station installer for Debian Linux (.deb) from here.
    2. Open your file manager and navigate to the location where the .deb package is saved.
    3. The package manager will launch and display Massa Station installation page.
    4. Review the package information and dependencies, if any, and click on the red "Delete" button.
    5. Proceed to GUI installation starting at step 2.
    + \ No newline at end of file diff --git a/docs/massaStation/manual-install.html b/docs/massaStation/manual-install.html index cd999e05b..371a25a61 100644 --- a/docs/massaStation/manual-install.html +++ b/docs/massaStation/manual-install.html @@ -10,7 +10,7 @@ - + @@ -23,8 +23,8 @@ features such as HTTPS support and accessing .massa domains will not work.

    Handle station.massa redirection

    If you want to access Massa Station by typing station.massa in your browser's address bar, you will need to configure your system to redirect requests to station.massa to localhost. You can make this change by editing the 'hosts' file on your computer, regardless of whether you're using Windows, MacOS, or Linux:

    1. Open the 'hosts' file, which is located at:
      • Windows: C:\Windows\System32\drivers\etc\hosts
      • MacOS and Linux: /etc/hosts
    2. Add 127.0.0.1 station.massa at the end of the file.
    3. Save and close the file.

    Add HTTPS support

    Massa Station will automatically generate a self-signed certificate for HTTPS support when it is first run, but to do it, -it requires some dependencies to be installed on your system.

    Windows

    1. Download a Windows version of the Mar Tools
    2. Extract the contents of the archive to a directory named mar-tools in the same directory as the massastation.exe binary.
    3. Run the massastation.exe binary to start Massa Station.

    MacOS

    1. Install Homebrew.
    2. Install the nss package using Homebrew: brew install nss
    3. Create the certificate directory:
      mkdir -m 777 -p /etc/massastation/certs
    4. Run the massastation binary in repair mode with sudo:
      sudo ./massastation --repair
    5. Run the massastation binary to start Massa Station.

    Linux

    1. Install the nss package using your package manager.
    2. Create the certificate directory:
      mkdir -m 777 -p /etc/massastation/certs
    3. Run the massastation binary to start Massa Station.
    - +it requires some dependencies to be installed on your system.

    Windows

    1. Download a Windows version of the Mar Tools
    2. Extract the contents of the archive to a directory named mar-tools in the same directory as the massastation.exe binary.
    3. Run the massastation.exe binary to start Massa Station.

    MacOS

    1. Install Homebrew.
    2. Install the nss package using Homebrew: brew install nss
    3. Create the certificate directory:
      mkdir -m 777 -p /etc/massastation/certs
    4. Run the massastation binary in repair mode with sudo:
      sudo ./massastation --repair
    5. Run the massastation binary to start Massa Station.

    Linux

    1. Install the nss package using your package manager.
    2. Create the certificate directory:
      mkdir -m 777 -p /etc/massastation/certs
    3. Run the massastation binary to start Massa Station.
    + \ No newline at end of file diff --git a/docs/massaStation/massa-wallet/account-backup.html b/docs/massaStation/massa-wallet/account-backup.html index 43ac77856..14c7e0588 100644 --- a/docs/massaStation/massa-wallet/account-backup.html +++ b/docs/massaStation/massa-wallet/account-backup.html @@ -10,13 +10,13 @@ - +
    -

    Account Backup

    danger

    For your peace of mind, we recommend backing up your account. This ensures you can easily restore it if needed.

    The backup file contains your account private key encrypted with a password. You can restore your account by importing it using the backup file and the password.

    1. Open the Massa Wallet module.

    2. Access your wallet.

    3. Click on the Settings button in the left bar.

      Settings

    4. Click on Back up Account.

    5. Choose how you want to backup your account:

      • Using a ‘.yaml’ file: Click on Download .yaml file and select a location to save the file.
      • Using the secret key: Click on Show key pair, type your password and copy the secret key by clicking on the Copy Secret Key button.
    6. Save the file or the secret key in a safe place and do not share it with anyone.

    tip

    As a best practice, consider importing your account on another device to verify that your backup is fully functional.

    - +

    Account Backup

    danger

    For your peace of mind, we recommend backing up your account. This ensures you can easily restore it if needed.

    The backup file contains your account private key encrypted with a password. You can restore your account by importing it using the backup file and the password.

    1. Open the Massa Wallet module.

    2. Access your wallet.

    3. Click on the Settings button in the left bar.

      Settings

    4. Click on Back up Account.

    5. Choose how you want to backup your account:

      • Using a ‘.yaml’ file: Click on Download .yaml file and select a location to save the file.
      • Using the secret key: Click on Show key pair, type your password and copy the secret key by clicking on the Copy Secret Key button.
    6. Save the file or the secret key in a safe place and do not share it with anyone.

    tip

    As a best practice, consider importing your account on another device to verify that your backup is fully functional.

    + \ No newline at end of file diff --git a/docs/massaStation/massa-wallet/account-creation.html b/docs/massaStation/massa-wallet/account-creation.html index 52a6bda1d..f920189c1 100644 --- a/docs/massaStation/massa-wallet/account-creation.html +++ b/docs/massaStation/massa-wallet/account-creation.html @@ -10,14 +10,14 @@ - +

    Account Creation

    Creating a new account in Massa Wallet is straightforward:

    1. Open Massa Station.
    2. Open the Massa Wallet module by clicking on the ‘Launch’ button.
    3. Click on Create an Account.
    4. Follow the prompts to set a strong password and backup your recovery phrase.
    danger

    We strongly recommend you to backup your account to ensure that you will be able to restore it in case of a problem. -You can find more information about how to backup your account in the Account Backup section of this document.

    - +You can find more information about how to backup your account in the Account Backup section of this document.

    + \ No newline at end of file diff --git a/docs/massaStation/massa-wallet/account-restore.html b/docs/massaStation/massa-wallet/account-restore.html index 7b8040762..5391133df 100644 --- a/docs/massaStation/massa-wallet/account-restore.html +++ b/docs/massaStation/massa-wallet/account-restore.html @@ -10,13 +10,13 @@ - +
    -

    Account Restore

    You can import an account using either a backup file or a private key.

    If you choose to import an account using a backup file, you will need to enter the password used to encrypt the backup file.

    If you opt to import an account using a private key, you will need to create a new password to encrypt the private key.

    1. Open the Massa Wallet module.
    2. Click on Add an account.
    3. Click on Import an existing account.
    4. Choose the method you want to use to import your account (either backup file or private key).
    5. Follow the instructions.
    - +

    Account Restore

    You can import an account using either a backup file or a private key.

    If you choose to import an account using a backup file, you will need to enter the password used to encrypt the backup file.

    If you opt to import an account using a private key, you will need to create a new password to encrypt the private key.

    1. Open the Massa Wallet module.
    2. Click on Add an account.
    3. Click on Import an existing account.
    4. Choose the method you want to use to import your account (either backup file or private key).
    5. Follow the instructions.
    + \ No newline at end of file diff --git a/docs/massaStation/massa-wallet/asset-monitoring-and-history.html b/docs/massaStation/massa-wallet/asset-monitoring-and-history.html index 0934c23c3..7c19fa95c 100644 --- a/docs/massaStation/massa-wallet/asset-monitoring-and-history.html +++ b/docs/massaStation/massa-wallet/asset-monitoring-and-history.html @@ -10,14 +10,14 @@ - +

    Asset Monitoring and History

    info

    Massa Wallet will soon support transaction history, which will allow users to see the transactions they have sent and received.

    Massa Wallet allows you to monitor Fungible Tokens (FT) balances. -You can add as many FTs as you want and monitor them in a single place.

    To add a FT, follow these steps:

    1. Open Massa Wallet.

    2. Access your wallet.

    3. Click on the Assets button in the left bar.

      Assets

    4. Click on the Import token button.

      Import Token

    5. Enter the FT address and click on the Add token button

      Add Token

    - +You can add as many FTs as you want and monitor them in a single place.

    To add a FT, follow these steps:

    1. Open Massa Wallet.

    2. Access your wallet.

    3. Click on the Assets button in the left bar.

      Assets

    4. Click on the Import token button.

      Import Token

    5. Enter the FT address and click on the Add token button

      Add Token

    + \ No newline at end of file diff --git a/docs/massaStation/massa-wallet/getting-started.html b/docs/massaStation/massa-wallet/getting-started.html index 5f1f084f2..0a3d4d817 100644 --- a/docs/massaStation/massa-wallet/getting-started.html +++ b/docs/massaStation/massa-wallet/getting-started.html @@ -10,15 +10,15 @@ - +

    Getting Started with Massa Wallet

    Massa Wallet

    The Massa Wallet module enhances Massa Station by adding wallet-related functionalities, such as account management (creation, transfer, balance checking), and private key management (signing transactions, generating random messages).

    Installation

    To install the Massa Wallet module, follow these steps:

    1. If Massa Station is not running, start it:
    • On Windows, you can find Massa Station in your Start Menu and on your Desktop.
    • On MacOS, you can find Massa Station in LaunchPad or in the ‘Applications’ directory in Finder.
    • On Linux, you can find Massa Station in your Applications menu.
    1. Open Massa Station in your web browser. You can do it either by:
    • Clicking on the Massa Station icon in the system tray and then clicking on Open Massa Station.
    • Opening https://station.massa/ in your web browser.
    1. In the Massa Wallet section, click on the ‘Install’ button.

      Install Massa Wallet

    2. Once the installation is complete, click on the ‘Launch’ button to access the Massa Wallet module.

      Launch Massa Wallet

    tip

    If you are unable or do not wish to install a thick client, you can always use one of our community browser extensions. -However, by doing so, you will limit your access to the full potential of this super app.

    - +However, by doing so, you will limit your access to the full potential of this super app.

    + \ No newline at end of file diff --git a/docs/massaStation/massa-wallet/transaction-management.html b/docs/massaStation/massa-wallet/transaction-management.html index 142ade861..31a58f00a 100644 --- a/docs/massaStation/massa-wallet/transaction-management.html +++ b/docs/massaStation/massa-wallet/transaction-management.html @@ -10,13 +10,13 @@ - +
    -

    Transaction Management

    Sending Funds

    1. Open the Massa Wallet module.

    2. Access to your wallet.

    3. Click on the Send button.

    4. Enter the recipient's address and the amount to send.

      Send

    5. Confirm the transaction.

      Confirm

    6. A popup will appear asking you to sign the transaction.

    Receiving Funds

    1. From your wallet dashboard, click on the ‘Receive’ button.
    2. Copy the address or generate a link:
      1. To copy the address, click on the button at the right of your account address.

        Receive

      2. To generate a link, click on the ‘Generate link’ button and select the amount you want to receive. Once done, click on the ‘Generate link’ button and copy the link using the button on the right of the link.

        Generate Link

    3. Share the address or the link with the person who wants to send you funds.
    info

    The generated link only works if Massa Station is installed and running on the computer of the person who wants to send you funds.

    - +

    Transaction Management

    Sending Funds

    1. Open the Massa Wallet module.

    2. Access to your wallet.

    3. Click on the Send button.

    4. Enter the recipient's address and the amount to send.

      Send

    5. Confirm the transaction.

      Confirm

    6. A popup will appear asking you to sign the transaction.

    Receiving Funds

    1. From your wallet dashboard, click on the ‘Receive’ button.
    2. Copy the address or generate a link:
      1. To copy the address, click on the button at the right of your account address.

        Receive

      2. To generate a link, click on the ‘Generate link’ button and select the amount you want to receive. Once done, click on the ‘Generate link’ button and copy the link using the button on the right of the link.

        Generate Link

    3. Share the address or the link with the person who wants to send you funds.
    info

    The generated link only works if Massa Station is installed and running on the computer of the person who wants to send you funds.

    + \ No newline at end of file diff --git a/docs/massaStation/modules.html b/docs/massaStation/modules.html index 59fa2cb58..ced624c86 100644 --- a/docs/massaStation/modules.html +++ b/docs/massaStation/modules.html @@ -10,7 +10,7 @@ - + @@ -20,8 +20,8 @@ here.

    To achieve evolvability and decentralization, Massa Station is designed to be extendable using modules, which are also known as plugins.

    tip

    If you are unable or do not wish to install a thick client, you can always use one of our community browser extensions. -However, by doing so, you will limit your access to the full potential of this super app.

    - +However, by doing so, you will limit your access to the full potential of this super app.

    + \ No newline at end of file diff --git a/docs/massaStation/troubleshooting.html b/docs/massaStation/troubleshooting.html index 21d9bc892..5b72fc232 100644 --- a/docs/massaStation/troubleshooting.html +++ b/docs/massaStation/troubleshooting.html @@ -10,7 +10,7 @@ - + @@ -39,8 +39,8 @@ This section will explain you how to get them.

    Please make sure to follow the instructions for your operating system.

    Once you have the logs, please open a new issue on the Massa Wallet repository and attach the logs to your issue so we can help you.

    Windows

    1. Copy %APPDATA%\massa-station-wallet\
    2. Press Win + R, a small window with a text box should open.
    3. In this window, paste what you just copied and press Enter.
    4. A File Explorer window should appear in an APPDATA directory
    5. In this directory, search for the file named station-massa-wallet.log

    MacOS

    1. Open Finder
    2. On the top right you should see an application bar with different options such as File, Edit and View
    3. Click on the Go and in the dropdown select Library
    4. Look for a directory named Application Support and open it
    5. Open the folder named massa-station-wallet
    6. In this directory, search for the file named station-massa-wallet.log

    Linux

    The log file is located in ~/.config/massa-station-wallet/. You can access it using the Files app or with a terminal using cd. -Once in the directory, search for the file named station-massa-wallet.log.

    Massa Wallet can't be opened error

    Wallet plugin error

    So far, this issue happens only on Linux because some dependencies aren't installed correctly.

    Linux

    1. Open your terminal
    2. Verify witch version of this packet you have libwebkit2gtk with apt list --installed libwebkit2gtk
    3. The required version is 0.4-37, so you need to install it with this cmd sudo apt install libwebkit2gtk-4.0-37. If the version installed is already the 0.4-37, please open an issue here.
    4. Once the library installed, restart Massa Wallet module by turning it off and on again.
    - +Once in the directory, search for the file named station-massa-wallet.log.

    Massa Wallet can't be opened error

    Wallet plugin error

    So far, this issue happens only on Linux because some dependencies aren't installed correctly.

    Linux

    1. Open your terminal
    2. Verify witch version of this packet you have libwebkit2gtk with apt list --installed libwebkit2gtk
    3. The required version is 0.4-37, so you need to install it with this cmd sudo apt install libwebkit2gtk-4.0-37. If the version installed is already the 0.4-37, please open an issue here.
    4. Once the library installed, restart Massa Wallet module by turning it off and on again.
    + \ No newline at end of file diff --git a/docs/massaStation/uninstall.html b/docs/massaStation/uninstall.html index 5a2807f3e..03a09ae3a 100644 --- a/docs/massaStation/uninstall.html +++ b/docs/massaStation/uninstall.html @@ -10,14 +10,14 @@ - +

    Uninstall

    Windows

    To uninstall Massa Station from your Windows system, follow the steps below:

    1. Stop MassaStation by right-clicking on the icon in the system tray and selecting "Quit".
    2. Open your "Start" panel.
    3. Type "Settings" and open the settings.
    4. On the left panel, click on "Apps".
    5. Click on "Installed Apps".
    6. Search for "MassaStation" in the list of installed applications.
    7. On the "..." menu, click on "Uninstall".
    8. Confirm uninstallation by clicking on "Uninstall" in the confirmation dialog.
    9. Follow the instructions provided by the uninstaller.

    The application and all modules installed will be deleted from your desktop.

    MacOS

    To uninstall Massa Station from your MacOS system, follow the steps below:

    1. Stop MassaStation by right-clicking on the icon in the system tray and selecting "Quit".
    2. Open the Terminal application on your MacOS system.
    3. Execute the following command in the terminal to download and run the Massa Station uninstaller script:
      /usr/local/share/massastation/uninstall.sh
      info

      This command will remove MassaStation and its associated files from your system.

    4. Follow any prompts or instructions provided by the uninstaller script. This may involve confirming the removal and providing your password for administrative privileges.
    5. Once the uninstallation process is complete, you will receive a confirmation message indicating that Massa Station has been successfully uninstalled.
    info

    DNSMasq and Homebrew might have been installed on your system as dependencies for Massa Station. -We do not remove these packages automatically as they may be used by other applications on your system.

    Linux

    To uninstall Massa Station from your Linux system, follow the steps below:

    1. Stop MassaStation by right-clicking on the icon in the system tray and selecting "Quit".
    2. Open the Terminal application on your Linux system.
    3. Execute the following command in the terminal to download and run the Massa Station uninstaller script:
      sudo dpkg -r massastation
      info

      This command will remove MassaStation and its associated files from your system.

    4. Once the uninstallation process is complete, you will receive a confirmation message indicating that Massa Station has been successfully uninstalled.
    - +We do not remove these packages automatically as they may be used by other applications on your system.

    Linux

    To uninstall Massa Station from your Linux system, follow the steps below:

    1. Stop MassaStation by right-clicking on the icon in the system tray and selecting "Quit".
    2. Open the Terminal application on your Linux system.
    3. Execute the following command in the terminal to download and run the Massa Station uninstaller script:
      sudo dpkg -r massastation
      info

      This command will remove MassaStation and its associated files from your system.

    4. Once the uninstallation process is complete, you will receive a confirmation message indicating that Massa Station has been successfully uninstalled.
    + \ No newline at end of file diff --git a/docs/node/all-configs.html b/docs/node/all-configs.html index 15424ba34..90e3d4eab 100644 --- a/docs/node/all-configs.html +++ b/docs/node/all-configs.html @@ -10,7 +10,7 @@ - + @@ -18,8 +18,8 @@

    Node and client configuration

    caution

    Use with caution, overriding some configurations could lead to node instability and/or a complete desynchronization from Massa blockchain.

    Node configuration

    You can override the default configuration via the massa-node/config/config.toml file.

    [logging]
    # Logging level. High log levels might impact performance. 0: ERROR, 1: WARN, 2: INFO, 3: DEBUG, 4: TRACE
    level = 2

    [api]
    # max number of future periods considered during requests
    draw_lookahead_period_count = 10
    # port on which the node API listens for admin and node management requests. Dangerous if publicly exposed. Bind to "[::1]:port" for IPv6
    bind_private = "127.0.0.1:33034"
    # port on which the node API listens for public requests. Can be exposed to the Internet. Bind to "[::]:port" for IPv6
    bind_public = "0.0.0.0:33035"
    # port on which the node API(V2) listens for HTTP requests and WebSockets subscriptions. Can be exposed to the Internet. Bind to "[::]:port" for IPv6
    bind_api = "0.0.0.0:33036"
    # max number of arguments per RPC call
    max_arguments = 128
    # path to the openrpc specification file used in `rpc.discover` method
    openrpc_spec_path = "base_config/openrpc.json"
    # maximum size in bytes of a request. Defaults to 50MB
    max_request_body_size = 52428800
    # maximum size in bytes of a response. Defaults to 50MB
    max_response_body_size = 52428800
    # maximum number of incoming connections allowed
    max_connections = 100
    # maximum number of subscriptions per connection
    max_subscriptions_per_connection = 100
    # max length for logging for requests and responses. Logs bigger than this limit will be truncated
    max_log_length = 4096
    # host filtering
    allow_hosts = []
    # batch request limit. 0 means disabled
    batch_request_limit = 16
    # the interval at which `Ping` frames are submitted in milliseconds
    ping_interval = 60000
    # whether to enable HTTP.
    enable_http = true
    # whether to enable WS.
    enable_ws = false
    # whether to broadcast for blocks, endorsements and operations
    enable_broadcast = false
    # deferred credits delta (in milliseconds)
    deferred_credits_delta = 7776000000 # ~ 3 months (90×24×60×60×1000) in milliseconds

    [grpc]
    [grpc.public]
    # whether to enable gRPC
    enabled = true
    # whether to add HTTP 1 layer
    accept_http1 = false
    # whether to enable CORS. works only if `accept_http1` is true
    enable_cors = false
    # whether to enable gRPC health service
    enable_health = true
    # whether to enable gRPC reflection(introspection)
    enable_reflection = true
    # whether to enable TLS
    enable_tls = false
    # whether to enable mTLS (requires `enable_tls` to be true)
    enable_mtls = false
    # whether to generate a self-signed certificate if none is provided(ignored if `enable_tls` is false)
    generate_self_signed_certificates = true
    # list of subject alternative names for the server certificate(requires `generate_self_signed_certificates` to be true)
    subject_alt_names = []
    # bind for the Massa gRPC API
    bind = "0.0.0.0:33037"
    # which compression encodings does the server accept for requests
    accept_compressed = "Gzip"
    # which compression encodings might the server use for responses
    send_compressed = "Gzip"
    # limits the maximum size of a decoded message. Defaults to 50MB
    max_decoding_message_size = 52428800
    # limits the maximum size of an encoded message. Defaults to 50MB
    max_encoding_message_size = 52428800
    # limits the maximum size of streaming channel
    max_channel_size = 128
    # set a timeout on for all request handlers in seconds. Defaults to 60s
    timeout = 60
    # sets the maximum frame size to use for HTTP2(must be within 16384(16KB) and 16777215(16MB)). Defaults to 16KB
    max_frame_size = 16384
    # set the concurrency limit applied to on requests inbound per connection. Defaults to 32
    concurrency_limit_per_connection = 100
    # sets the SETTINGS_MAX_CONCURRENT_STREAMS spec option for HTTP2 connections
    max_concurrent_streams = 100
    # max number of arguments per gRPC request
    max_arguments = 128
    # set the value of `TCP_NODELAY` option for accepted connections. Enabled by default
    tcp_nodelay = true
    # max number of future periods considered during requests
    draw_lookahead_period_count = 10
    # max number of addresses that can be included in a single request
    max_addresses_per_request = 50
    # max number of slot ranges that can be included in a single request
    max_slot_ranges_per_request = 50
    # max number of block ids that can be included in a single request
    max_block_ids_per_request = 50
    # max number of endorsement ids that can be included in a single request
    max_endorsement_ids_per_request = 100
    # max number of operation ids that can be included in a single request
    max_operation_ids_per_request = 250
    # max op datastore entries per request
    max_datastore_entries_per_request = 128
    # max number of filters that can be included in a single request
    max_filters_per_request = 32
    # max number of query items that can be included in a single request
    max_query_items_per_request = 128
    # certificate authority root path
    certificate_authority_root_path = "config/tls_public_ca.pem"
    # server certificate path
    server_certificate_path = "config/tls_public_server.pem"
    # server private key path
    server_private_key_path = "config/tls_public_server.key"
    # client certificate authority root path
    client_certificate_authority_root_path = "config/tls_public_client_ca.pem"
    # client certificate path
    client_certificate_path = "../massa-client/config/tls_public_client.pem"
    # client private key path
    client_private_key_path = "../massa-client/config/tls_public_client.key"
    [grpc.private]
    # whether to enable gRPC
    enabled = true
    # whether to add HTTP 1 layer
    accept_http1 = false
    # whether to enable CORS. works only if `accept_http1` is true
    enable_cors = false
    # whether to enable gRPC health service
    enable_health = true
    # whether to enable gRPC reflection(introspection)
    enable_reflection = true
    # whether to enable TLS
    enable_tls = false
    # whether to enable mTLS (requires `enable_tls` to be true)
    enable_mtls = true
    # whether to generate a self-signed certificate if none is provided(ignored if `enable_tls` is false)
    generate_self_signed_certificates = true
    # list of subject alternative names for the server certificate(requires `generate_self_signed_certificates` to be true)
    subject_alt_names = []
    # bind for the Massa gRPC API
    bind = "127.0.0.1:33038"
    # which compression encodings does the server accept for requests
    accept_compressed = "Gzip"
    # which compression encodings might the server use for responses
    send_compressed = "Gzip"
    # limits the maximum size of a decoded message. Defaults to 50MB
    max_decoding_message_size = 52428800
    # limits the maximum size of an encoded message. Defaults to 50MB
    max_encoding_message_size = 52428800
    # limits the maximum size of streaming channel
    max_channel_size = 128
    # set a timeout on for all request handlers in seconds. Defaults to 60s
    timeout = 60
    # sets the maximum frame size to use for HTTP2(must be within 16384(16KB) and 16777215(16MB)). Defaults to 16KB
    max_frame_size = 16384
    # set the concurrency limit applied to on requests inbound per connection. Defaults to 32
    concurrency_limit_per_connection = 100
    # sets the SETTINGS_MAX_CONCURRENT_STREAMS spec option for HTTP2 connections
    max_concurrent_streams = 100
    # max number of arguments per gRPC request
    max_arguments = 128
    # set the value of `TCP_NODELAY` option for accepted connections. Enabled by default
    tcp_nodelay = true
    # max number of future periods considered during requests
    draw_lookahead_period_count = 10
    # max number of addresses that can be included in a single request
    max_addresses_per_request = 50
    # max number of slot ranges that can be included in a single request
    max_slot_ranges_per_request = 50
    # max number of block ids that can be included in a single request
    max_block_ids_per_request = 50
    # max number of endorsement ids that can be included in a single request
    max_endorsement_ids_per_request = 100
    # max number of operation ids that can be included in a single request
    max_operation_ids_per_request = 250
    # max op datastore entries per request
    max_datastore_entries_per_request = 128
    # max number of filters that can be included in a single request
    max_filters_per_request = 32
    # max number of query items that can be included in a single request
    max_query_items_per_request = 128
    # certificate authority root path
    certificate_authority_root_path = "config/tls_private_ca.pem"
    # server certificate path
    server_certificate_path = "config/tls_private_server.pem"
    # server private key path
    server_private_key_path = "config/tls_private_server.key"
    # client certificate authority root path
    client_certificate_authority_root_path = "config/tls_private_client_ca.pem"
    # client certificate path
    client_certificate_path = "../massa-client/config/tls_private_client.pem"
    # client private key path
    client_private_key_path = "../massa-client/config/tls_private_client.key"
    [execution]
    # max number of generated events kept in RAM
    max_final_events = 10000
    # maximum length of the read-only execution requests queue
    readonly_queue_length = 10
    # by how many milliseconds should the execution lag behind real time
    # higher values increase speculative execution lag but improve performance
    cursor_delay = 2000
    # duration of the statistics time window in milliseconds
    stats_time_window_duration = 60000
    # maximum allowed gas for read only executions
    max_read_only_gas = 4_294_967_295
    # gas cost for ABIs
    abi_gas_costs_file = "base_config/gas_costs/abi_gas_costs.json"
    # gas cost for wasm operator
    wasm_gas_costs_file = "base_config/gas_costs/wasm_gas_costs.json"
    # path to the hard drive cache storage
    hd_cache_path = "storage/cache/rocks_db"
    # maximum number of entries we want to keep in the LRU cache
    # in the worst case scenario this is equivalent to 2Gb
    lru_cache_size = 200
    # maximum number of entries we want to keep in the HD cache
    # in the worst case scenario this is equivalent to 20Gb
    hd_cache_size = 2000
    # amount of entries removed when `hd_cache_size` is reached
    snip_amount = 10
    # slot execution outputs channel capacity
    broadcast_slot_execution_output_channel_capacity = 5000

    [ledger]
    # path to the initial ledger
    initial_ledger_path = "base_config/initial_ledger.json"
    # path to the disk ledger db directory
    disk_ledger_path = "storage/ledger/rocks_db"
    # length of the changes history. Higher values allow bootstrapping nodes with slower connections
    final_history_length = 100
    # path of the initial deferred credits file
    initial_deferred_credits_path = "base_config/deferred_credits.json"

    [consensus]
    # max number of previously discarded blocks kept in RAM
    max_discarded_blocks = 100
    # max number of blocks in the future kept in RAM
    max_future_processing_blocks = 400
    # max number of blocks waiting for dependencies
    max_dependency_blocks = 2048
    # number of final periods that must be kept without operations (increase improve bootstrap process, high values will increase RAM usage.)
    force_keep_final_periods_without_ops = 32
    # number of final periods that must be kept with operations (increase to more resilience to short network disconnections, high values will increase RAM usage.)
    force_keep_final_periods = 5
    # useless blocks are pruned every block_db_prune_interval ms
    block_db_prune_interval = 5000
    # considered timespan for stats info
    stats_timespan = 60000
    # blocks headers channel capacity
    broadcast_blocks_headers_channel_capacity = 128
    # blocks channel capacity
    broadcast_blocks_channel_capacity = 128
    # filled blocks channel capacity
    broadcast_filled_blocks_channel_capacity = 128

    [protocol]
    # port on which to listen for protocol communication. You may need to change this to "0.0.0.0:port" if IPv6 is disabled system-wide.
    bind = "[::]:31244"
    # timeout for connection establishment
    connect_timeout = 3000
    # path to the node key (not the staking key)
    keypair_file = "config/node_privkey.key"
    # path to the initial peers file
    initial_peers_file = "base_config/initial_peers.json"
    # Limit of read/write number of bytes per second with a peer (Should be a 10 multiple)
    read_write_limit_bytes_per_second = 2_000_000_000
    # timeout after which without answer a handshake is ended
    message_timeout = 5000
    # timeout after which a peer tester will consider the peer unreachable
    tester_timeout = 10000
    # timeout after whick we consider a node does not have the block we asked for
    ask_block_timeout = 10000
    # Max known blocks we keep during their propagation
    max_blocks_kept_for_propagation = 300
    # Time during which a block is expected to propagate (in milliseconds)
    max_block_propagation_time = 40000
    # Block propagation tick interval, useful for propagating blocks quickly to newly connected peers (in milliseconds)
    block_propagation_tick = 1000
    # max cache size for which blocks our node knows about
    max_known_blocks_size = 1024
    # max cache size for which blocks a foreign node knows about
    max_node_known_blocks_size = 1024
    # max cache size for which blocks a foreign node asked for
    max_node_wanted_blocks_size = 1024
    # max number of blocks we can ask simultaneously per node
    max_simultaneous_ask_blocks_per_node = 128
    # max milliseconds to wait while sending an event before dropping it
    max_send_wait = 0
    # max cache size for which operations your node knows about
    max_known_ops_size = 1000000
    # max size of the cache of asked operations
    asked_operations_buffer_capacity = 600000
    # max cache size for which operations a foreign node knows about
    max_node_known_ops_size = 200000
    # max cache size for which endorsements our node knows about
    max_known_endorsements_size = 2048
    # max cache size for which endorsements a foreign node knows about
    max_node_known_endorsements_size = 2048
    # maximum number of batches in the memory buffer.
    # dismiss the new batches if overflow
    operation_batch_buffer_capacity = 10024
    # immediately announce ops if overflow
    operation_announcement_buffer_capacity = 2000
    # start processing batches in the buffer each `operation_batch_proc_period` in millisecond
    operation_batch_proc_period = 500
    # interval at which operations are announced in batches.
    operation_announcement_interval = 300
    # max number of operation per message, same as network param but can be smaller
    max_operations_per_message = 5000
    # Number of millis seconds between each try out connections
    try_connection_timer = 250
    # Number of millis seconds between each try out connections for same peer
    try_connection_timer_same_peer = 10000
    # Number of millis seconds between each unban of every peer
    unban_everyone_timer = 86400000
    # Number of millis seconds that create a timeout for out connections
    timeout_connection = 1000
    # max number of operations kept for propagation
    max_ops_kept_for_propagation = 320000
    # time threshold after which operation are not propagated
    max_operations_propagation_time = 32000
    # time threshold after which endorsement are not propagated
    max_endorsements_propagation_time = 32000
    # number of thread tester
    thread_tester_count = 25
    # Nb max in connections that we accept
    max_in_connections = 250
    # Cooldown before testing again old peer
    test_oldest_peer_cooldown = 720000
    # Rate limitation on the data streams (per second)
    rate_limit = 5_242_880 # 5 MiB / secs
    # Peer default category limits
    default_category_info = { target_out_connections = 10, max_in_connections_per_ip = 2, max_in_connections = 15, allow_local_peers = false }
    # Peer categories limits
    [protocol.peers_categories]
    Bootstrap = { target_out_connections = 1, max_in_connections_per_ip = 1, max_in_connections = 1, allow_local_peers = false }

    [network]

    [metrics]
    # enable prometheus metrics
    enabled = true
    # port on which to listen for prometheus metrics
    bind = "[::]:31248"
    # interval at which to update metrics
    tick_delay = 5000

    [bootstrap]
    # list of bootstrap (ip, node id)
    bootstrap_list = [
    ["149.202.86.103:31245", "N16noomm9akwBSTkvhs4KX6kjbhVhYkLqrzneCwBdo2SUE8axHx"],
    ["149.202.89.125:31245", "N12bYghvuhCuQ38iSAGQvKTb1iXtwzPZhNJLhWQPYcmgz8PDPAGo"],
    ["158.69.120.215:31245", "N1jRVjMZK8ZEmUGxDbLgHv3BTeQy8wHnazKCdcpQy4sFxu9d8GW"],
    ["158.69.23.120:31245", "N12B7LqdyVVBXr8TMygU28R7JYxUR2dsLLp63YXtH9XAR1R2NUrY"],
    ["198.27.74.5:31245", "N1FoYxXoSC39ZamAvwi7srz3oRrJ8JC3EvRhcqXPCD7vaQZTHKV"],
    ["51.75.60.228:31245", "N1nRDdGq7DFD7AvSz5pgAsXCvkcqoL5Xf3kHr8Yd3TTUgtBcBun"],
    ["[2001:41d0:1004:67::]:31245", "N16noomm9akwBSTkvhs4KX6kjbhVhYkLqrzneCwBdo2SUE8axHx"],
    ["[2001:41d0:a:7f7d::]:31245", "N12bYghvuhCuQ38iSAGQvKTb1iXtwzPZhNJLhWQPYcmgz8PDPAGo"],
    ["[2001:41d0:602:21e4::]:31245", "N1nRDdGq7DFD7AvSz5pgAsXCvkcqoL5Xf3kHr8Yd3TTUgtBcBun"],
    ]
    # force the bootstrap protocol to use: "IPv4", "IPv6", or "Both". Defaults to using both protocols.
    bootstrap_protocol = "Both"
    # path to the bootstrap whitelist file. This whitelist define IPs that can bootstrap on your node.
    bootstrap_whitelist_path = "base_config/bootstrap_whitelist.json"
    # path to the bootstrap blacklist file. This whitelist define IPs that will not be able to bootstrap on your node. This list is optional.
    bootstrap_blacklist_path = "base_config/bootstrap_blacklist.json"
    # [optional] port on which to listen for incoming bootstrap requests. You may need to change this to "0.0.0.0:port" if IPv6 is disabled system-wide.
    bind = "[::]:31245"
    # timeout to establish a bootstrap connection
    connect_timeout = 15000
    # timeout for providing the bootstrap to a connection
    bootstrap_timeout = 600000 # 10 mins
    # delay in milliseconds to wait between consecutive bootstrap attempts
    retry_delay = 60000
    # if ping is too high bootstrap will be interrupted after max_ping milliseconds
    max_ping = 10000
    # timeout for incoming message readout
    read_timeout = 30000
    # timeout for message sending
    write_timeout = 30000
    # timeout for incoming error message readout
    read_error_timeout = 200
    # timeout for message error sending
    write_error_timeout = 200
    # max allowed difference between client and servers clocks in ms
    max_clock_delta = 5000
    # [server] data is cached for cache duration milliseconds
    cache_duration = 15000
    # max number of simulataneous bootstraps for server
    max_simultaneous_bootstraps = 2
    # max size of recently bootstrapped IP cache
    ip_list_max_size = 10000
    # refuse consecutive bootstrap attempts from a given IP when the interval between them is lower than per_ip_min_interval milliseconds
    per_ip_min_interval = 180000
    # read-write limitation for a connection in bytes per seconds (about the bootstrap specifically)
    rate_limit = 20_971_520 # 20 MiB /sec

    [pool]
    # max number of operations kept in the pool
    max_operation_pool_size = 500000
    # max excess number of operations kept in pool in-between refreshes
    max_operation_pool_excess_items = 100000
    # refresh interval of the operation pool scoring (milliseconds)
    operation_pool_refresh_interval = 5000
    # if an operation is too much in the future it will be ignored (milliseconds)
    operation_max_future_start_delay = 50000
    # max number of endorsements kept per thread
    max_endorsements_pool_size_per_thread = 25000
    # max number of items returned per query
    max_item_return_count = 100
    # endorsements channel capacity
    broadcast_endorsements_channel_capacity = 2000
    # operations channel capacity
    broadcast_operations_channel_capacity = 5000


    [selector]
    # path to the initial roll distribution
    initial_rolls_path = "base_config/initial_rolls.json"

    [factory]
    # initial delay in milliseconds to wait before starting production to avoid double staking on node restart
    initial_delay = 100
    # path to your staking wallets
    staking_wallet_path = "config/staking_wallets"
    # stop or not the production in case we are not connected to anyone
    stop_production_when_zero_connections = true

    [versioning]
    # Warn user to update its node if we reach this percentage for announced network versions
    mip_stats_warn_announced_version = 30

    Client configuration

    You can override the default configuration via -the massa-client/config/config.toml file.

    history = 10
    history_file_path = "config/.massa_history"
    timeout = 1000

    [default_node]
    # The IP of your node. Works both with IPv4 (like 127.0.0.1) and IPv6 (like ::1) addresses, if the node is bound to the correct protocol.
    ip = "127.0.0.1"
    private_port = 33034
    public_port = 33035
    grpc_public_port = 33037
    grpc_private_port = 33038
    # Chain id for MainNet, please update to match the target node chain id
    chain_id = 77658377

    [client]
    # maximum size in bytes of a request. Defaults to 50MB
    max_request_body_size = 52428800
    # request timeout
    request_timeout = 60000
    # maximum number of outcoming connections allowed
    max_concurrent_requests = 100
    # certificate_store, `Native` or `WebPki`
    certificate_store = "Native"
    # JSON-RPC request object id data type, `String` or `Number`
    id_kind = "Number"
    # max length for logging for requests and responses. Logs bigger than this limit will be truncated
    max_log_length = 4096
    # custom headers passed to the server with every request (default is empty).
    headers = []

    [client.http]
    # whether to enable HTTP.
    enabled = true

    - +the massa-client/config/config.toml file.

    history = 10
    history_file_path = "config/.massa_history"
    timeout = 1000

    [default_node]
    # The IP of your node. Works both with IPv4 (like 127.0.0.1) and IPv6 (like ::1) addresses, if the node is bound to the correct protocol.
    ip = "127.0.0.1"
    private_port = 33034
    public_port = 33035
    grpc_public_port = 33037
    grpc_private_port = 33038
    # Chain id for MainNet, please update to match the target node chain id
    chain_id = 77658377

    [client]
    # maximum size in bytes of a request. Defaults to 50MB
    max_request_body_size = 52428800
    # request timeout
    request_timeout = 60000
    # maximum number of outcoming connections allowed
    max_concurrent_requests = 100
    # certificate_store, `Native` or `WebPki`
    certificate_store = "Native"
    # JSON-RPC request object id data type, `String` or `Number`
    id_kind = "Number"
    # max length for logging for requests and responses. Logs bigger than this limit will be truncated
    max_log_length = 4096
    # custom headers passed to the server with every request (default is empty).
    headers = []

    [client.http]
    # whether to enable HTTP.
    enabled = true

    + \ No newline at end of file diff --git a/docs/node/check_status.html b/docs/node/check_status.html index 5f52c27b4..9ca3afae4 100644 --- a/docs/node/check_status.html +++ b/docs/node/check_status.html @@ -10,15 +10,15 @@ - +

    Check your node's status

    Check your routability status

    You can use a service such as https://portchecker.co to check that the ports 31244 and 31245 are both opened for your public IP address.

    Additionally, in your massa-client, you can check that the get_status command shows your Node's IP: <your_public_ip_address>. If it shows No routable IP set instead, please check again your configuration.

    Make sure you are connected to peers

    In order for your node to be running properly, you have to make sure you are connected to other peers on the network.

    The get_status command will show you which nodes you are connected too. -You need to have both IN and OUT connections.

    - +You need to have both IN and OUT connections.

    + \ No newline at end of file diff --git a/docs/node/community-resources.html b/docs/node/community-resources.html index e27643276..6a5b4dcbf 100644 --- a/docs/node/community-resources.html +++ b/docs/node/community-resources.html @@ -10,7 +10,7 @@ - + @@ -19,8 +19,8 @@ useful tutorials and resources and deserve to be credited for it. In this document, we are gathering links of the latest creations.

    caution

    Please note, these are unofficial and not frequently checked by the core members. Some might be outdated or miss important information. For security reasons, we encourage you to go through the official installation process and -tutorials or trusted parties. As always, use your best judgment when visiting third party links.

    About Massa



    Setting up a node





    Tracking the activity of a node

    Miscellaneous


    - +tutorials or trusted parties. As always, use your best judgment when visiting third party links.

    About Massa



    Setting up a node





    Tracking the activity of a node

    Miscellaneous


    + \ No newline at end of file diff --git a/docs/node/faq.html b/docs/node/faq.html index eddce533e..b06b75547 100644 --- a/docs/node/faq.html +++ b/docs/node/faq.html @@ -10,7 +10,7 @@ - + @@ -52,8 +52,8 @@ already in use on your computer. You should change the port in the config files, both in the API and Client:
  • create/edit file massa-node/config/config.toml to change the port used by the API:
  • [api]
    bind_private = "127.0.0.1:33034" # change port here from 33034 to something else
    bind_public = "0.0.0.0:33035" # change port here from 33035 to something else
    • create/edit file massa-client/config/config.toml and put the same port:
    [default_node]
    ip = "127.0.0.1"
    private_port = 33034 # change port here from 33034 to the port chosen in node's bind_private
    public_port = 33035 # change port here from 33035 to the port chosen in node's bind_public

    Raspberry Pi problem "Thread 'main' panicked"

    If you encountered an error message such as: Thread 'main' panicked at 'called Option::unwrap() on a None value', models/src/hasher.rs:35:46, this is a known problem on older Raspberry Pi, especially with Raspbian. Try installing Debian.

    Please note, running a Massa node on a Raspberry Pi is ambitious and will probably not work that well. We don't expect -raspberry to be enough powerful to run on the mainnet.

    Disable IPV6 support

    If your OS, virtual machine or provider does not support IPV6, try disabling IPV6 support on your Massa node.

    To do this, edit (or create if absent) the file massa-node/config/config.toml with the following contents:

    [network]
    bind = "0.0.0.0:31244"

    [bootstrap]
    bind = "0.0.0.0:31245"

    then restart your node.

    - +raspberry to be enough powerful to run on the mainnet.

    Disable IPV6 support

    If your OS, virtual machine or provider does not support IPV6, try disabling IPV6 support on your Massa node.

    To do this, edit (or create if absent) the file massa-node/config/config.toml with the following contents:

    [network]
    bind = "0.0.0.0:31244"

    [bootstrap]
    bind = "0.0.0.0:31245"

    then restart your node.

    + \ No newline at end of file diff --git a/docs/node/home.html b/docs/node/home.html index 71ffeeb2f..ec0da9fbd 100644 --- a/docs/node/home.html +++ b/docs/node/home.html @@ -10,7 +10,7 @@ - + @@ -19,8 +19,8 @@ Massa is carried by individuals called "node runners", who run their personal computers ("nodes") to form a robust and uncensorable mesh of around the world, which supports the network's security and independence. Moreover, node runners are the ones who include pending operations into the blockchain by creating Blocks, which is called "staking".

    If you have access to a mid-range desktop computer, a decent internet connection and own at least 100 Massa coins, you can become a staking node runner. -Staking node runners are rewarded for their participation:

    • first, more than 7000 new Massa coins are created every hour and distributed to stakers as rewards
    • second, stakers receive a share of the operation fees included in the blocks they produce
    • third, by supporting the security of the network, stakers contribute to the value of the Massa coins they own

    How to become a staking node runner ?

    In this section you'll find various resources regarding the Massa network and in particular how to participate as a node runner.

    - +Staking node runners are rewarded for their participation:

    • first, more than 7000 new Massa coins are created every hour and distributed to stakers as rewards
    • second, stakers receive a share of the operation fees included in the blocks they produce
    • third, by supporting the security of the network, stakers contribute to the value of the Massa coins they own

    How to become a staking node runner ?

    In this section you'll find various resources regarding the Massa network and in particular how to participate as a node runner.

    + \ No newline at end of file diff --git a/docs/node/install.html b/docs/node/install.html index e5de1db73..c46387c94 100644 --- a/docs/node/install.html +++ b/docs/node/install.html @@ -10,7 +10,7 @@ - + @@ -20,8 +20,8 @@ go to the next step: Running a node.

    From source code (advanced installation)

    Otherwise, if you wish to run a Massa node from source code, here are the steps to follow:

    On Ubuntu / MacOS

    • on Ubuntu, these libs must be installed: sudo apt install pkg-config curl git build-essential libssl-dev libclang-dev cmake
    • on MacOS: brew install llvm cmake
    • install rustup: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    • configure path: source $HOME/.cargo/env
    • check rust version: rustc --version
    • install rust stable version: rustup toolchain install 1.74.1
    • set it as default: rustup default 1.74.1
    • check rust version: rustc --version
    • clone this repo: git clone https://github.com/massalabs/massa.git
    • go to the cloned repository: cd massa
    • checkout the latest tag: git checkout MAIN.2.1

    On Windows

    Set up your Rust environment:

    • On Windows, you should first follow the indications from Microsoft to be able to run on a Rust environment here.
      • Install Visual Studio (recommended) or the Microsoft C++ Build Tools.
      • Once Visual Studio is installed, click on C++ Build Tool. Select on the right column called "installation details" the following packages:
        • MSCV v142 -- VS 2019
        • Windows 10 SDK
        • C++ CMake tools for Windows
        • Testing Tools Core Feature
      • Click install on the bottom right to download and install those packages
    • Install NASM: https://www.nasm.us/pub/nasm/releasebuilds/2.16.01/ choose win32 or win64 folder depending on your architecture and download then launch the installer.
    • Install Chocolatey and run: choco install llvm cmake
    • Install Rust, to be downloaded here
    • Install Git for windows, to be downloaded here

    Clone the Massa Git Repository:

    • Open Windows Power Shell
      • Clone the latest distributed version: git clone https://github.com/massalabs/massa.git
      • Go to the cloned repository: cd massa
      • Checkout the latest tag: git checkout MAIN.2.1
      • Change default Rust to the following stable version: rustup default 1.74.1

    My node is installed. What next ?

    Once you have installed your node, you want to set it up for running and staking. Before running the node, you should configure it to be routable as indicated here. -Without it, your node will be unstable through lack of connectivity.

    - +Without it, your node will be unstable through lack of connectivity.

    + \ No newline at end of file diff --git a/docs/node/routability.html b/docs/node/routability.html index 7b5eb159e..b2c47286e 100644 --- a/docs/node/routability.html +++ b/docs/node/routability.html @@ -10,7 +10,7 @@ - + @@ -29,8 +29,8 @@ running the node
  • setup the firewall on your computer to allow incoming TCP connections on ports 31244 and 31245 (example: ufw allow 31244 && ufw allow 31245 on Ubuntu, or set up the Windows Firewall on Windows)
  • you can then test if your ports are open by typing your public IP address and port 31244 in https://portchecker.co (then again with port 31245)
  • edit the file massa-node/config/config.toml (or create it if absent) with the following contents:
  • [protocol]
    routable_ip = "AAA.BBB.CCC.DDD"

    where AAA.BBB.CCC.DDD should be replaced with your public IP address (not the local one !). IPV6 is also supported.

    • run the massa node
    • Additionally, in your massa-client, you can check that the get_status command shows your Node's IP: <your_public_ip_address>. -If it shows No routable IP set instead, please check again your configuration.
    - +If it shows No routable IP set instead, please check again your configuration. + \ No newline at end of file diff --git a/docs/node/run.html b/docs/node/run.html index 7142a45fd..c7a6ead78 100644 --- a/docs/node/run.html +++ b/docs/node/run.html @@ -10,7 +10,7 @@ - + @@ -23,8 +23,8 @@ open an issue on the Massa repository instead. We will triage the issues and open them on the Rust side if they are valid. This avoids polluting the main Rust repository with many reports of the same error.

    What next ?

    Congratulations, you are now running a node. To interact with the network, to send transactions and call smart contracts, -you will need a wallet.

    It is time to setup or import a wallet. Follow the tutorial: Creating a wallet.

    - +you will need a wallet.

    It is time to setup or import a wallet. Follow the tutorial: Creating a wallet.

    + \ No newline at end of file diff --git a/docs/node/stake.html b/docs/node/stake.html index df50c3f13..7e26cbbb4 100644 --- a/docs/node/stake.html +++ b/docs/node/stake.html @@ -10,7 +10,7 @@ - + @@ -23,8 +23,8 @@ A12dr48yZaL2NpQkwsrpsNLGDpndFUCVSdYdSiQh4UfkYRMo17km 1 0

    It should take less than one minute for your roll to become final, check with:

    wallet_info

    Telling your node to start staking with your rolls

    Get the address that has rolls in your wallet:

    wallet_info

    Register your address so that your node start to stake with it:

    node_start_staking <your_address>

    Now you should wait some time so that your rolls become active: 3 cycles of 128 periods (one period is 32 blocks - 16 sec), so about 1 hour and 40 minutes.

    You can check if your rolls are active with the same command:

    wallet_info

    When your rolls become active, that's it! You're staking! You should be selected to create blocks in the different threads.

    To check when your address is selected to stake, run this command:

    get_addresses <your_address>

    and look at the "next draws" section.

    Also check that your balance increases, for each block or endorsement that you create you should get a small reward.

    Selling rolls

    If you want to get back some or all of your coins, sell rolls the same way you bought them:

    sell_rolls <address> <roll count> <fee>

    It should take some time again for your coins to be credited, and they will be frozen for 1 cycle before you can spend -them, again check with:

    wallet_info

    What next ?

    Congratulations, you followed all the steps to be part of the Massa adventure!

    You should now check the status of your setup: Check your node's status.

    - +them, again check with:

    wallet_info

    What next ?

    Congratulations, you followed all the steps to be part of the Massa adventure!

    You should now check the status of your setup: Check your node's status.

    + \ No newline at end of file diff --git a/docs/node/update.html b/docs/node/update.html index 406ebcb28..15ed0cc46 100644 --- a/docs/node/update.html +++ b/docs/node/update.html @@ -10,14 +10,14 @@ - +

    Updating a node

    Update process

    The exact update procedure depends on how you previously installed your node.

    The basic process goes as follows:

    • Stop your previous node, as running 2 nodes with the same keys will lead to loss of coins
    • Backup your node wallet folders (massa-node/staking_wallets and massa-client/wallets)
    • If needed, backup you custom config files (massa-node/config/config.toml and massa-client/config/config.toml)
    • Install your new node by following the documentation.
    • Restore your wallet folders to their respective location
    • If needed, restore your custom configuration

    If, during the process, you missed enough block production, your rolls may be automatically sold. -If that is the case, wait for the coins to get reimbursed automatically (taking ~3 hours), and buy your rolls again.

    Updating the git repository (if installed from sources)

    If you installed from sources, you can either re-clone the repo, or you can update your existing repo to the latest release.

    In order to update to the latest release, launch a terminal in your current repository, and then run the following commands:

    git fetch
    git checkout MAIN.2.1
    - +If that is the case, wait for the coins to get reimbursed automatically (taking ~3 hours), and buy your rolls again.

    Updating the git repository (if installed from sources)

    If you installed from sources, you can either re-clone the repo, or you can update your existing repo to the latest release.

    In order to update to the latest release, launch a terminal in your current repository, and then run the following commands:

    git fetch
    git checkout MAIN.2.1
    + \ No newline at end of file diff --git a/docs/node/wallet.html b/docs/node/wallet.html index eebceadc3..479394962 100644 --- a/docs/node/wallet.html +++ b/docs/node/wallet.html @@ -10,7 +10,7 @@ - + @@ -20,8 +20,8 @@ that were sent to your address.

    From the command line interface

    If your client is not running

    Go to the client folder:

    cd massa/massa-client/

    Start the interactive client and load a wallet file:

    cargo run

    It will ask your wallet password in order to load the wallet.dat file. If the file does not exist, you will be asked to set a password and it will be created.

    If your client is running

    Now you can either generate a new keypair (and associated address):

    wallet_generate_secret_key

    The list of addresses of your wallet can be accessed with:

    wallet_info

    Access public key(s) of addresse(s):

    wallet_get_public_key <Address1> <Address2>

    Access secret key(s) of addresse(s):

    wallet_get_secret_key <Address1> <Address2>

    Importing your wallet in the client

    In order to import a wallet into your client, the procedure depends on how you have saved your wallet in the first place.

    If you have saved your secret/private key

    Then you can import it in the client using the following command:

    wallet_add_secret_keys <your_secret_key>

    If you have saved an encrypted wallet file

    Then you can import it in the client by placing the corresponding .yaml file in the massa/massa-client/wallets folder. Make sure it is the only wallet in the folder.

    What next ?

    Congratulations, you are now running a node and have access to a wallet. -But your node is still not staking, so it is not producing blocks nor receiving rewards.

    It is time to activate staking on your node. Follow the tutorial: Staking with a node.

    - +But your node is still not staking, so it is not producing blocks nor receiving rewards.

    It is time to activate staking on your node. Follow the tutorial: Staking with a node.

    + \ No newline at end of file diff --git a/docs/tutorial/home.html b/docs/tutorial/home.html index b51bd9f1b..5b5e0a673 100644 --- a/docs/tutorial/home.html +++ b/docs/tutorial/home.html @@ -10,13 +10,13 @@ - +
    -
    - +
    + \ No newline at end of file diff --git a/docs/tutorial/trading-bot.html b/docs/tutorial/trading-bot.html index aa880b2a9..9cf6c21e3 100644 --- a/docs/tutorial/trading-bot.html +++ b/docs/tutorial/trading-bot.html @@ -10,13 +10,13 @@ - +
    -

    Autonomous Trading Bot

    This video is a great example of how to use Massa's autonomous smart contracts to build a trading bot that will automatically buy and sell tokens on the Dusa decentralized exchange (DEX).

    This tutorial covers all the tooling required to build a decentralized application on the Massa blockchain, from the smart contract to the front-end interface, making it a great way to get started with Massa.

    Or you can have a look at the GitHub repository here.

    - +

    Autonomous Trading Bot

    This video is a great example of how to use Massa's autonomous smart contracts to build a trading bot that will automatically buy and sell tokens on the Dusa decentralized exchange (DEX).

    This tutorial covers all the tooling required to build a decentralized application on the Massa blockchain, from the smart contract to the front-end interface, making it a great way to get started with Massa.

    Or you can have a look at the GitHub repository here.

    + \ No newline at end of file diff --git a/index.html b/index.html index e832eefaa..6c18281a0 100644 --- a/index.html +++ b/index.html @@ -10,13 +10,13 @@ - + - + \ No newline at end of file diff --git a/search.html b/search.html index 3ea60fea1..a677a11d0 100644 --- a/search.html +++ b/search.html @@ -10,13 +10,13 @@ - + - + \ No newline at end of file