# Tanssi Developer Documentation (LLMS Format) This file contains documentation for Tanssi (https://docs.tanssi.network). Tanssi is a decentralized infrastructure protocol designed to enable the rapid deployment of sovereign appchains. It is intended for use with large language models (LLMs) to support developers working with Tanssi. The content includes selected pages from the official docs, organized by section. This file includes documentation related to the product: Appchain ## AI Prompt Template You are an AI developer assistant for Tanssi (https://docs.tanssi.network). Your task is to assist developers in understanding and using the product described in this file. - Provide accurate answers based on the included documentation. - Do not assume undocumented features, behaviors, or APIs. - If unsure, respond with “Not specified in the documentation. ## List of doc pages: Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/account-management/identity.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/account-management/proxy-accounts.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/build/customize/customizing-chain-specs.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/build/templates/overview.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/deploy/dapp.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/manage/dapp/manage-tokens.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/manage/dapp/register-external-assets.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/manage/dapp/services-payment.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/manage/dapp/xcm-channels.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/manage/developer-portal/impersonate.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/manage/developer-portal/maintenance.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/manage/developer-portal/minting.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/manage/developer-portal/pause-transactions.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/manage/developer-portal/smart-contracts-creation-filter.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/manage/developer-portal/sudo.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/manage/developer-portal/upgrade.md [type: builders] Doc-Page: https://raw.githubusercontent.com/moondance-labs/tanssi-docs/refs/heads/main/builders/tanssi-network/testnet/demo-evm-network.md [type: builders] ## Full content for each doc page Doc-Content: https://docs.tanssi.network/builders/account-management/identity/ --- BEGIN CONTENT --- --- title: Set an Account Identity description: Follow these instructions to establish an identity, including a display name so that you can be more easily recognizable on the Tanssi orchestrator chain. icon: octicons-person-24 categories: Basics, Appchain --- # Set Up an On-Chain Identity ## Introduction {: #introduction } The [Substrate](/learn/framework/overview/#substrate-framework){target=\_blank} Identity [module](/learn/framework/modules/){target=\_blank} is an out-of-the-box solution for adding personal information to your on-chain account. Establishing an identity makes it easier for your account to be recognized by others, as your display name will automatically populate when someone pastes your address into a field on the [developer portal](https://polkadot.js.org/apps/?rpc=wss://{{ networks.mainnet.dns_name }}#/accounts){target=\_blank}. The identity you configure goes beyond a simple display name. Personal information can include default fields such as your legal name, display name, website, Twitter handle, Discord, and Riot (now known as Element) name. You can also use custom fields to include any other relevant information. This guide will demonstrate setting up an identity with a display name and additional parameters, enhancing your visibility and recognizability. ## General Definitions {: #general-definitions } To store your information on-chain, you must bond some funds, which will eventually be returned once the identity has been cleared. There are two categories of fields: default and custom. A basic deposit amount is reserved upon identity creation, and a storage deposit is required for each additional byte of data stored on-chain. - **Default fields include** - your legal name, display name, website, Twitter handle, Discord, Riot (now known as Element) name - **Custom fields include** - any other relevant information - **Subaccounts** - You can link subaccounts underneath a primary account. As an example, a sequencer service that's running multiple different sequencer nodes can establish subaccounts to demonstrate an official link between the nodes === "Tanssi MainNet" | Variable | Definition | Value | |:---------------------:|:--------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------:| | Basic deposit | The amount held on deposit for setting an identity | {{ networks.mainnet.identity.basic_deposit }} {{ networks.mainnet.token_symbol }} | | Deposit per byte | The amount held on deposit per byte of on-chain storage used setting an identity | {{ networks.mainnet.identity.per_byte_deposit }} {{ networks.mainnet.token_symbol }} | | Max additional fields | Maximum number of additional fields that may be stored in an ID | {{ networks.mainnet.identity.max_fields }} | | Max subaccounts | Maximum number of subaccounts that can be defined under an account identity | {{ networks.mainnet.identity.max_subaccounts }} | === "Dancelight TestNet" | Variable | Definition | Value | |:---------------------:|:--------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------:| | Basic deposit | The amount held on deposit for setting an identity | {{ networks.dancelight.identity.basic_deposit }} {{ networks.dancelight.token_symbol }} | | Deposit per byte | The amount held on deposit per byte of on-chain storage used setting an identity | {{ networks.dancelight.identity.per_byte_deposit }} {{ networks.dancelight.token_symbol }} | | Max additional fields | Maximum number of additional fields that may be stored in an ID | {{ networks.dancelight.identity.max_fields }} | | Max subaccounts | Maximum number of subaccounts that can be defined under an account identity | {{ networks.dancelight.identity.max_subaccounts }} | ## Checking Prerequisites { : #checking-prerequisites } To follow along with this guide, you will need the following: === "Tanssi MainNet" - The [developer portal](https://polkadot.js.org/apps/?rpc=wss://{{ networks.mainnet.dns_name }}#/accounts){target=\_blank} open and connected to Tanssi MainNet. - At least one account funded with `{{ networks.mainnet.token_symbol }}` tokens. === "Dancelight TestNet" - The [developer portal](https://polkadot.js.org/apps/?rpc=wss://{{ networks.dancelight.dns_name }}#/accounts){target=\_blank} open and connected to [Dancelight](/builders/tanssi-network/testnet/dancelight/){target=\_blank}. - At least one account funded with `{{ networks.dancelight.token_symbol }}` tokens. If you need help importing your accounts into the developer portal, please check out the [Connecting to the developer portal](/builders/toolkit/substrate-api/wallets/talisman/#connecting-to-polkadotjs){target=\_blank} guide. ## Get Started {: #get-started } Depending on the information to be included, there are a couple of different ways to set and clear an identity using the developer portal. If you intend to register your identity using only the default fields, you can follow the instructions for [Managing an Identity via the Accounts](#manage-via-accounts) page. **This is the recommended way to set and manage your identity**. If you want to add custom fields beyond the default fields, follow the instructions for [Managing an Identity via the Extrinsics](#manage-via-extrinsics) page. !!! note Please note that using the **Accounts** page on the developer portal is recommended to manage your identity as it provides an easy-to-use interface that enforces character limits. If you use the **Extrinsics** page, please be aware that your input for each field (i.e., name, email, etc.) must be 32 characters or less; otherwise, your information will be cut off. ## Manage an Identity via Accounts {: #manage-via-accounts } ### Set an Identity {: #set-identity-accounts } To get started with setting an identity using the Accounts page, head to the [**Accounts** tab](https://polkadot.js.org/apps/?rpc=wss://{{ networks.mainnet.dns_name }}#/accounts){target=\_blank} of the developer portal. You should already have an account connected, so you can click on your account name to verify and note your balances. After you send the transaction to set an identity, the deposit(s) you submitted will be moved from your transferable balance to your reserved balance. ![Starting account balances](/images/builders/account-management/identity/identity-1.webp) To set your identity, you'll need to: 1. Click on the three vertical dots next to the account you would like to set an identity for 2. A menu will pop up. Click **Set on-chain identity** ![Set on-chain identity](/images/builders/account-management/identity/identity-2.webp) Next, the menu to register and set your identity will pop up, and you can start filling in your information. You are not required to enter information for every single field; you can choose to fill in just one field or all of them; it's up to you. For this example: 1. Set your display name 2. Click on the **include field** toggle for email and then enter in your email 3. Click on the **include field** toggle for web and then enter in your website URL 4. Click on the **include field** toggle for Twitter and then enter in your Twitter handle 5. Review the prior data fields and click **Set Identity** ![Set your identity](/images/builders/account-management/identity/identity-3.webp) You will then be prompted to sign the transaction. If everything looks good, sign it. You should see status notifications pop up in the top right-hand corner. Once the transaction has been confirmed, you can click on your account name again, and the panel will slide out on the right side of the page. Your balances will have changed, and you'll also see your new identity information. ![Updated account balances](/images/builders/account-management/identity/identity-4.webp) If the identity information matches what you entered, you've successfully set an identity! Once you clear your identity, the deposit in your reserved balance will get transferred back to your transferable balance. If you need to change your identity, you can go through the process of setting your identity again. Please note that you must ensure all fields are re-entered, even if only one field needs to be changed, or they will be overwritten. You will not need to pay another deposit unless custom fields are used, but you will need to pay gas fees. ## Manage an Identity via Extrinsics {: #manage-via-extrinsics } ### Set an Identity {: #set-identity-extrinsics } To register an identity using the extrinsics page, navigate to the [**Extrinsics** page](https://polkadot.js.org/apps/?rpc=wss://{{ networks.mainnet.dns_name }}#/extrinsics){target=\_blank} of the developer portal. Please ensure your input does not exceed 32 characters for each identity field. To complete your identity, take the following steps: 1. Select your account 2. Select identity from the **submit the following extrinsic** dropdown 3. Then select the **setIdentity(info)** function 4. Select **Raw** as the data format to enter your **Display Name** 5. Enter the data for **Display** in the selected format 6. Select **Raw** as the data format to enter your web address 7. Enter your website URL in the selected format 8. Select **Raw** as the data format to enter your email 9. Enter your email address in the selected format 10. Select **Raw** as the data format to enter your Twitter handle 11. Enter your Twitter in the selected format. Enter the username only, starting with the `@` symbol 12. Review the prepared fields and press **Submit Transaction** ![Set on-chain identity](/images/builders/account-management/identity/identity-5.webp) Optionally, if you would like to enter custom fields, take the following steps: 1. Scroll to the top and click on **Add item** 2. Two fields will appear: the first for the field name and the second for the value. Select **Raw** as the data format to enter the field name 3. Enter the field name in the specified format 4. Select **Raw** as the data format to enter the custom value 5. Enter the custom value in the specified format ![Add custom fields](/images/builders/account-management/identity/identity-6.webp) Finally, once all of your identity information has been added, you can scroll to the bottom of the page and click **Submit Transaction**. You will then be prompted to sign the transaction. Remember, an additional deposit is required for each additional custom field. If everything looks good, sign the transaction. You should see status notifications pop up in the top right-hand corner confirming the transaction. If successful, you've set an identity! Congratulations! To ensure everything went through and your identity information looks good, you can verify your identity. ### Confirm an Identity {: #confirm-identity-extrinsics } To verify the addition of your identity information, you can click on the **Developer** tab and then navigate to [**Chain state**](https://polkadot.js.org/apps/?rpc=wss://{{ networks.mainnet.dns_name }}#/chainstate){target=\_blank}. On the **Chain State** page, make sure **Storage** is selected. Then you can start to request your identity information: 1. Set **selected state query** to **identity** 2. Select the **identityOf(AccountId)** function 3. Select your account 4. Click the **+** button to get your identity information ![Request identity information](/images/builders/account-management/identity/identity-7.webp) You can see now that you've successfully set an identity! Once you clear your identity, the deposit in your reserved balance will get transferred back to your transferable balance. If you need to change your identity, you can go through the process of setting your identity again. Please note that you must ensure all fields are re-entered, even if only one field needs to be changed, or they will be overwritten. You will not need to pay another deposit unless custom fields are used, but you will need to pay gas fees. ## Clear an Identity {: #confirm-identity-extrinsics } To clear your identity, take the following steps from **Extrinsics** tab of the developer portal: 1. Select your account from the **using the selected account** dropdown 2. Select **identity** from the **submit the following extrinsic** dropdown 3. Then select the **clearIdentity()** function 4. Click **Submit Transaction** ![Clear an identity](/images/builders/account-management/identity/identity-8.webp) You will then be prompted to sign the transaction. If everything looks good, sign it. You should see status notifications in the top right-hand corner confirming the transaction. To confirm that your identity information has been successfully removed, revisit the steps outlined in the [Confirm an Identity section](#confirm-identity-extrinsics). This time, instead of displaying your identity details, the response should indicate **none**, confirming that no identity information is currently linked to your account. Additionally, when you check your balances, you will find that the deposit initially made for setting your identity has been credited back to your transferable balance. This completes the process of clearing your identity. ![Clear an identity confirmation](/images/builders/account-management/identity/identity-9.webp) --- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/account-management/proxy-accounts/ --- BEGIN CONTENT --- --- title: Set Up and Manage Proxy Accounts description: Follow these step-by-step instructions to learn how proxies work and how to create, view, update, and remove proxy accounts from primary (proxied) accounts. icon: octicons-shield-lock-24 categories: Basics, Appchain --- # Proxy Accounts ## Introduction {: #introduction } Proxy accounts can be set up to perform a limited number of actions on behalf of primary accounts and are helpful for keeping the underlying accounts safe. Your proxy account can act as a "hot wallet" to interact with the network on behalf of your "cold wallet" account. For added safety, you can regularly rotate the proxy account. Proxy accounts can also help you implement the principle of least privilege for access control. For example, if you have multiple team members, you can give them the minimum level of access required to carry out their duties via a specific type of proxy account. This tutorial will walk you through configuring a proxy account on Dancelight, the Tanssi TestNet, specifically for balance transfers. Then, it will demonstrate performing a balance transfer using the newly created proxy. ## Checking Prerequisites {: #checking-prerequisites } To follow along with this tutorial, you will need to have: - [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=wss://{{ networks.dancelight.dns_name }}#/accounts){target=\_blank} open and connected to [Dancelight](/builders/tanssi-network/testnet/dancelight/){target=\_blank}. - Create or have two accounts accessible on the developer portal. - At least one of the accounts will need to be funded with `{{ networks.dancelight.token_symbol }}` tokens. If you need help importing your accounts into Polkadot.js Apps, please check out the [Connecting to Polkadot.js](/builders/toolkit/substrate-api/wallets/talisman/#connecting-to-polkadotjs){target=\_blank} guide. ## General Definitions {: #general-definitions } When setting up a proxy account, a bond for the proxy is taken out of your free balance and moved to your reserved balance. The bond is required as adding a proxy requires on-chain storage space, and it is recalculated for each proxy you add or remove. The bond is returned to your free balance after all proxies are removed from your account. The deposit is calculated based on a deposit base and a deposit factor: - **Deposit base** - the amount to be reserved for an account to have a proxy list. - **Deposit factor** - the additional amount to be reserved for every proxy the primary account has. The equation for calculating the deposit is: ```text deposit base + deposit factor * number of proxies ``` You can find each of the relevant variables below. === "Tanssi MainNet" | Variable | Value | |:--------------:|:--------------------------------------------------------------------------------:| | Deposit base | {{ networks.mainnet.proxy.deposit_base }} {{ networks.mainnet.token_symbol }} | | Deposit factor | {{ networks.mainnet.proxy.deposit_factor }} {{ networks.mainnet.token_symbol }} | | Max proxies | {{ networks.mainnet.proxy.max_proxies }} proxies | === "Dancelight TestNet" | Variable | Value | |:--------------:|:--------------------------------------------------------------------------------------:| | Deposit base | {{ networks.dancelight.proxy.deposit_base }} {{ networks.dancelight.token_symbol }} | | Deposit factor | {{ networks.dancelight.proxy.deposit_factor }} {{ networks.dancelight.token_symbol }} | | Max proxies | {{ networks.dancelight.proxy.max_proxies }} proxies | ## Proxy Types {: #proxy-types } When creating a proxy account, you must choose a type of proxy that will define how the proxy can be used. The available options are: - **`Any`** - allows the proxy account to use any function supported by the proxy pallet. There is no filtering of calls. - **`NonTransfer`** - this type of proxy account is allowed to submit any type of transaction with the exception of balance transfers. - **`Balances`** - allows the proxy account to only make transactions related to sending funds. - **`Governance`** - allows the proxy account to only make transactions related to the governance pallet, such as voting or creating democracy proposals. Note, governance is not yet enabled on Tanssi. You can create governance proxy accounts but they will not be able to take any actions until governance is enabled. - **`Registrar`** - allows the proxy account to only make transactions related to the registrar pallet. - **`SudoRegistrar`** - allows the proxy account to only make transactions related to the registrar pallet that need to be called by Sudo. - **`CancelProxy`** - allows the proxy account to reject and remove any announced proxy calls. - **`Staking`** - allows the proxy account to perform staking-related transactions, such as sequencer and `session()` functions. - **`SessionKeyManagement`** - allows the proxy account to make key management related transactions included in the session pallet. For this guide, you will be setting up a proxy account using the balances proxy type. Since this type enables the proxy to spend funds on behalf of the primary account, you should exercise caution and only provide access to accounts you trust. The proxy will have access to transfer all of the funds within the primary account, and if not trusted, the proxy could drain the primary account. Ensure that you maintain oversight of your proxy accounts and remove any proxies that are no longer needed. ## Creating a Proxy Account {: #creating-a-proxy-account } There are a couple of ways you can create proxy accounts in [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=wss://{{ networks.dancelight.dns_name }}#/accounts){target=\_blank}, either from the **Extrinsics** page or the **Accounts** page. However, to create a time-delayed proxy, you will need to use the **Extrinsics** page. A time delay provides an additional layer of security to proxies by specifying a delay period based on the number of blocks. This will prevent the proxy account from executing a transaction until the delay period ends. The delay allows time for the primary account that controls the proxy to review pending transactions, potentially for malicious actions, and cancel if necessary before execution. The following demo will showcase configuring a Balances proxy, which allows for transferring funds, making it perfect for demonstration purposes. After configuring your Balances proxy you can try transferring funds from the primary account via proxy. To get started creating your proxy account, head to the **Developer** tab and select [**Extrinsics**](https://polkadot.js.org/apps/?rpc=wss://{{ networks.dancelight.dns_name }}#/extrinsics){target=\_blank} from the dropdown. Next, you will need to take the following steps: 1. Select the primary account. 2. From the **submit the following extrinsic** dropdown, select **proxy**. 3. Choose the **addProxy** extrinsic. 4. Choose **Id** from the **AccountIdLookupOf** dropdown. 5. Select the **delegate** account for the proxy. 6. From the **proxyType** dropdown, choose **Balances**. 7. Optionally, you can add a time delay using a specified number of blocks to add an additional layer of security for the primary account to review the pending transaction. 8. Click **Submit Transaction**. ![Add a proxy account from the Extrinsics page of Polkadot.js Apps.](/images/builders/account-management/proxy/proxy-1.webp) You will then be prompted to authorize and sign the transaction. Click **Sign and Submit** to create the proxy relationship. Once the transaction has been successfully submitted, you will receive some notifications confirming the transaction. As previously mentioned, you can also create a proxy from the **Accounts** page. To do so, navigate to the **Accounts** page and take the following steps: 1. Select the three vertical dots next to the primary account. 2. Select **Add proxy**. ![Select the Add proxy menu item from the Accounts page of Polkadot.js Apps.](/images/builders/account-management/proxy/proxy-2.webp) !!! note If the account already has a proxy, **Manage proxies** will be displayed as an option instead of **Add proxy**. A pop-up will appear and you can enter in the required information, such as the proxied/primary account, the proxy account, and type of proxy to create a proxy account. First click **Add Proxy**. ![Add a proxy account from the Accounts page of Polkadot.js Apps](/images/builders/account-management/proxy/proxy-3.webp) Then, take the following steps: 1. Select the account you would like to set as a proxy. 2. Select the proxy type. 3. Click **Submit** and sign the transaction. ![Add the details of the proxy account, including the proxy account and type.](/images/builders/account-management/proxy/proxy-4.webp) In the next section, you will learn how to verify that your proxy account was set up successfully. ## Verifying Your Proxy Account {: #verifying-your-proxy-account } You can verify that your proxy account has been successfully set up in a couple of ways: either through the **Accounts** page or via the **Chain state** page. To check your proxy accounts from the [**Chain state** page](https://polkadot.js.org/apps/?rpc=wss://{{ networks.dancelight.dns_name }}#/chainstate){target=\_blank}, you can take the following steps: 1. From the **selected state query** dropdown, select **proxy**. 2. Choose the **proxies** extrinsic. 3. Select your primary/proxied account. 4. Click on the **+** button to send the query. ![Verify your proxy accounts via the Extrinsics page of Polkadot.js Apps.](/images/builders/account-management/proxy/proxy-5.webp) The result will appear on the page showing you information about all of your proxies, including the delegate/proxy account address, the proxy type, the delay period if one was specified, and the total bond amount for all of your proxies in Planck. You can also check your proxy accounts from the **Accounts** page. To do so, navigate to the **Accounts** page, and there should be a Proxy symbol next to the primary account. Hover over the icon and click on **Manage proxies** to review your proxies. ![Hover over the proxy icon to manage your proxies via the Accounts page of Polkadot.js Apps.](/images/builders/account-management/proxy/proxy-6.webp) A pop-up will appear where you can see an overview of all of your proxy accounts. ![Review your proxy accounts.](/images/builders/account-management/proxy/proxy-7.webp) ## Executing a Proxy Transaction {: #executing-a-proxy-transaction } Now that you have created a proxy account and verified that it was successfully set up, you can execute a transaction using the proxy account on behalf of the primary account. To execute a transaction, you can navigate back to the [**Extrinsics** page](https://polkadot.js.org/apps/?rpc=wss://{{ networks.dancelight.dns_name }}#/extrinsics){target=\_blank} and take the following steps: 1. Select the proxy account to submit the transaction from the **using the select account** dropdown. 2. From the **submit the following extrinsic** menu, select **proxy**. 3. Choose the **proxy** extrinsic. 4. Choose **Id** from the **AccountIdLookupOf** dropdown. 5. Select the primary account from the **real** dropdown. 6. Select the **balances** call. 7. Choose the **transferKeepAlive** extrinsic. 8. Choose **Id** from the **AccountIdLookupOf** dropdown. 9. In the **dest** field, enter the address you would like to send funds to. 10. In the **value** field, enter the amount of {{ networks.dancelight.token_symbol }} tokens to send. For this example, you can send `2` {{ networks.dancelight.token_symbol }} tokens. 11. Click **Submit Transaction**. ![Execute a proxy transaction from the Extrinsics page of Polkadot.js Apps.](/images/builders/account-management/proxy/proxy-8.webp) A pop-up will appear for you to authorize and sign the transaction. Enter your password for the proxy account and click **Sign and Submit**. If the transaction successfully went through, you should see a couple of notification pop-ups. If you head over to the **Accounts** page, you'll see that your primary account balance has decreased. If you check the account balance where you sent the funds, you'll notice the balance there has increased. ![Check balance on the accounts page of Polkadot.js Apps](/images/builders/account-management/proxy/proxy-9.webp) That's it! You've successfully executed a transaction using a proxy account on behalf of your primary account. ## Removing a Proxy Account {: #removing-a-proxy-account } Similarly to adding a proxy account, there are a couple of ways that you can remove a proxy account, either from the **Extrinsics** page or the **Accounts** page. Regardless of which page you use, you can elect to remove a single proxy account or all proxies associated with your primary account. To remove a proxy from the [**Extrinsics** page](https://polkadot.js.org/apps/?rpc=wss://{{ networks.dancelight.dns_name }}#/extrinsics){target=\_blank}, you can take the following steps: 1. From the **using the selected account** dropdown, select your primary account. 2. Then select **proxy**. 3. Choose **removeProxy** to remove a single proxy or **removeProxies** to remove all associated proxies. 4. Choose **Id** from the **AccountIdLookupOf** dropdown. 5. If removing a single proxy, enter the proxy account to remove in the **delegate** field. 6. Select the **proxyType** to remove, in this case choose **Balances**. 7. Optionally, select a delay period in block numbers. 8. Click **Submit Transaction**. ![Remove a proxy account from the Extrinsics page of Polkadot.js Apps](/images/builders/account-management/proxy/proxy-10.webp) A pop-up will appear asking you to authorize and sign the transaction. You can sign and send the transaction from the primary or proxy account, but the call to remove the proxy must be sent from the primary account. Enter your password and click **Sign and Submit**. To check that the proxy or proxy accounts have been removed, follow the steps in the [Verifying your Proxy Account](#verifying-your-proxy-account) section. As previously mentioned, you can also remove a proxy from the **Accounts** page. To do so, on the **Accounts** page, select the three vertical dots next to the primary account and select **Manage Proxies**. ![Click on the Manage Proxies button to review and manage your proxy accounts.](/images/builders/account-management/proxy/proxy-11.webp) A pop-up will appear showing an overview of your proxy accounts. To remove all proxies, you can click on **Clear all**, then you will automatically be prompted to enter your password and submit the transaction. To remove a single proxy, take the following steps: 1. Click the **X** button next to the proxy to remove 2. Press **Submit** ![Remove a proxy account from the Accounts page of Polkadot.js Apps.](/images/builders/account-management/proxy/proxy-12.webp) On the transaction confirmation screen, take the following steps: 1. Ensure that you do not use a proxy for this call (as this example is a balances proxy, the call to remove the proxy needs to come from the primary account rather than the proxy account). 2. Enter your password for the respective account. 3. Press **Sign and Submit**. ![Remove a proxy account from the Accounts page of Polkadot.js Apps, confirmation](/images/builders/account-management/proxy/proxy-13.webp) Once the transaction has successfully been submitted, you can review your current proxies, or if you removed all proxies, you will notice the proxy icon is no longer being displayed next to the primary account. And that's it! You've successfully created a proxy, reviewed all proxy accounts associated with your primary account, executed a proxy transaction, and removed a proxy account!
The information presented herein has been provided by third parties and is made available solely for general information purposes. Tanssi does not endorse any project listed and described on the Tanssi Doc Website (https://docs.tanssi.network/). Tanssi Foundation does not warrant the accuracy, completeness or usefulness of this information. Any reliance you place on such information is strictly at your own risk. Tanssi Foundation disclaims all liability and responsibility arising from any reliance placed on this information by you or by anyone who may be informed of any of its contents. All statements and/or opinions expressed in these materials are solely the responsibility of the person or entity providing those materials and do not necessarily represent the opinion of Tanssi Foundation. The information should not be construed as professional or financial advice of any kind. Advice from a suitably qualified professional should always be sought in relation to any particular matter or circumstance. The information herein may link to or integrate with other websites operated or content provided by third parties, and such other websites may link to this website. Tanssi Foundation has no control over any such other websites or their content and will have no liability arising out of or related to such websites or their content. The existence of any such link does not constitute an endorsement of such websites, the content of the websites, or the operators of the websites. These links are being provided to you only as a convenience and you release and hold Tanssi Foundation harmless from any and all liability arising from your use of this information or the information provided by any third-party website or service.
--- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/build/customize/customizing-chain-specs/ --- BEGIN CONTENT --- --- title: Customizing Chain Specifications description: Review the sections and attributes of a chain specification file and how to obtain it for launching your Tanssi-powered network with a customized specification. icon: octicons-link-24 categories: Appchain --- # Customizing Chain Specifications {: #customizing-chain-specifications } ## Introduction {: #introduction } The chain specification refers to a set of parameters and configurations that define the characteristics and behavior of a new Tanssi-powered network. It defines the initial settings and state that all nodes participating in the network must agree on to reach consensus and produce blocks. Many initial settings cannot be changed after the network is launched without generating a completely different chain. The specification contains two main sections: - **The client specification** - includes the network parameters, for example, the boot nodes the client connects with when joining the network - **The genesis state** - represents the initial state upon which all transactions and state transitions take place. It includes details like the initial registered accounts and their balances, as well as the account with administrator privileges (sudo, if applicable), among other relevant information This information the chain specification contains can be stored in a Rust file (which can be found in the [templates](/builders/build/templates/overview/){target=\_blank} included in the Tanssi repository) or in a JSON file. This article covers the sections and attributes within a chain specification file and explains how to obtain it, in case you want to launch your Tanssi network by uploading a customized specifications file. ## The Client Specification {: #client-specification } The client specification contains the configuration of the network and other settings (excluding those related to the runtime state): - **Name** - name for the specifications - **Id** - a unique simple id for the network used to define the storage path in the node - **Fork Id** - optional parameter for a network fork identifier - **Chain Type** - a parameter that can be set to define the chain type and display additional information or enable additional features (it can be set to Development, Local, Live, or a custom type) - **Boot Nodes** - set of boot nodes that will be used when the new node joins the network and syncs - **Telemetry Endpoints** - an optional list of endpoints to send information and monitor the operation of the network - **Protocol Id** - a unique name defining the network protocol - **Relay Chain** - defines the id of the orchestration chain the Tanssi network interacts with - **Parachain Id** - sets a unique id that identifies the Tanssi network - **Code Substitutes** - an emergency feature to replace the runtime when a Tanssi network is unable to perform a runtime upgrade - **Properties** - key-value properties that can be customized and are useful to improve the user experience In the `properties` attribute, the following settings are used by various front-end libraries, including the [Polkadot.js API](/builders/toolkit/substrate-api/libraries/polkadot-js-api/){target=\_blank}: - **Token Symbol** - a name for your Tanssi network's own token symbol - **SS58 Format** - an integer that uniquely identifies the accounts in your network. [SS58 encoding](https://docs.polkadot.com/polkadot-protocol/parachain-basics/accounts/#address-formats){target=\_blank} transforms the underlying 32-byte account to a network-specific representation. This attribute doesn't apply nor interfere with the ECDSA Ethereum accounts on EVM-compatible networks - **Token Decimals** - represent how divisible a token can be, and what is the smallest representation of the token. It's set to `18` for EVM-compatible networks - **Is Ethereum** - a boolean identifying the network as EVM compatible or not ## The Genesis State {: #genesis-state } All the sequencers assigned to the Tanssi network must agree on the initial state so they can execute the incoming extrinsics, arrive at the same results, and finally reach a consensus on the new valid state. This genesis state will define the starting point of the Tanssi network. It includes an initial value for the elements that the modules included in the runtime need to persist and the initial runtime Wasm code, which is stored on-chain. For example, in the templates included, the chain specification defines the initial accounts and token balances in the `Balances` module. In addition, the template also has a sudo account (which **should be modified**) for the `Sudo` module, which provides unique priviledges to the given account, and that can be offboarded once an on-chain democracy module is plugged in. ## Generating a JSON Chain Specification File {: #generating-json-chain-specs } The following commands will build and generate the chain specification for the EVM-compatible template based on the configuration expressed in the `chain_spec.rs`, located in the `*/container-chains/templates/frontier/node/src/chain_spec.rs`. This example can be adapted to any other template or custom runtime. To build and generate the chain specifications, take the following steps: 1. Clone the Tanssi code hosted on GitHub ```bash git clone https://github.com/moondance-labs/tanssi ``` 2. Step into the project folder ```bash cd tanssi ``` 3. Build the Tanssi EVM-compatible network template ```bash cargo build -p container-chain-frontier-node --release ``` This step is quite verbose and might take a while to complete. The following screenshot shows the terminal after successfully finishing the building process (note that the completion time is above 35 minutes): ![Building the template](/images/builders/build/customize/customizing-chain-specs/customizing-chain-specs-1.webp) 4. Generate the chain specification ```bash ./target/release/container-chain-frontier-node \ build-spec > chain_spec.json ``` After executing the last step, the terminal displays only a log line: ![Generating the chain specification](/images/builders/build/customize/customizing-chain-specs/customizing-chain-specs-2.webp) And now the `chain_spec.json` file containing the client specification and the genesis state is created in the current folder. !!! note The JSON chain specifications can be generated in two different versions: the human readable, which is the one generated following the previous steps, and the raw version, which is the one needed to deploy the network through Tanssi. More about how to generate the raw version [later](#generating-raw-specs-file) in this article. ### Editing the JSON Chain Specification File {: #editing-json-chain-specs } The generated `chain_spec.json` file reflects the parameters set in the Rust chain specifications file. Being a JSON file, it is easy to read and, should any parameter need to be changed, easy to edit. For example, the following code snippet shows some of the attributes of the client specifications: ```json { // Set the name for the specification of this network "name": "Frontier network 1000", // Set an id for the specifications of this network "id": "frontier_network_1000", // Network will be live "chainType": "Live", "bootNodes": [ // boot nodes will be added automatically during deployment ], // Optional attribute, defaults to null "telemetryEndpoints": null, // Set a protocol identifier for this network "protocolId": "network-chain-1000", // Set properties to define the token and the ethereum compatibility "properties": { "isEthereum": true, "ss58Format": 42, "tokenDecimals": 18, "tokenSymbol": "UNIT" }, // Set the stagenet relay chain "relay_chain": "westend_moonbase_relay_stagenet", // Set the parachain id reserved in the relay chain "para_id": 3333, // No need "codeSubstitutes": {}, "genesis": { ... } } ``` The other important section of the file is within the `genesis` attribute, which contains the genesis state. In the following JSON snippet, the default values and configuration for some modules are presented as an example: ```json { ... "genesis": { "runtime": { ... // Sets the account that will bear sudo privileges "sudo": { "key": "0xf24ff3a9cf04c71dbc94d0b566f7a27b94566cac" }, // Sets the initial balances for some accounts "balances": { "balances": [ [ "0x3cd0a705a2dc65e5b1e1205896baa2be8a07c6e0", 1208925819614629174706176 ], [ "0x773539d4ac0e786233d90a233654ccee26a613d9", 1208925819614629174706176 ], [ "0x798d4ba9baf0064ec19eb4f0a1a45785ae9d6dfc", 1208925819614629174706176 ], [ "0xf24ff3a9cf04c71dbc94d0b566f7a27b94566cac", 1208925819614629174706176 ] ] }, // Sets balances for EVM accounts "evm": { "accounts": { "0x1000000000000000000000000000000000000001": { "nonce": "0x1", "balance": "0xd3c21bcecceda1000000", "storage": {}, "code": [ 0 ] }, "0x6be02d1d3665660d22ff9624b7be0551ee1ac91b": { "nonce": "0x0", "balance": "0xffffffffffffffffffffffffffffffff", "storage": {}, "code": [] }, "0xd43593c715fdd31c61141abd04a99fd6822c8558": { "nonce": "0x0", "balance": "0xffffffffffffffffffffffffffffffff", "storage": {}, "code": [] } } }, } } ... } ``` An example of a non-manually editable attribute is the Wasm runtime (in the genesis state section), which is a hexadecimal representation of a binary blob generated by the compiler. Still, apart from this, most of the properties are easy to edit before launching the network. ## Generating a Raw JSON Chain Specification File {: #generating-raw-specs-file } One final step before deploying the Tanssi network is converting the JSON specification file to a raw format, which is a compact, less-readable version of the same file, required to initialize a node. After going through the [steps to generate the JSON chain Specification File](#generating-json-chain-specs) and editing its values, the following command will convert the chain specs file into the required raw format: ```bash ./target/release/container-chain-frontier-node \ build-spec --chain=chain_spec.json --raw > raw_chain_spec.json ``` Now that this file has been configured and customized and is in the correct raw JSON format, it can be uploaded to initialize a new network in Tanssi. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/build/templates/overview/ --- BEGIN CONTENT --- --- title: Requirements and Features of Templates description: Explore the foundational setup and key features included in each Tanssi template, designed to streamline the building and deployment of Tanssi networks. icon: octicons-home-24 categories: Basics, Appchain --- # Templates Overview {: #templates-overview } ## Introduction {: #introduction } Networks deployed through Tanssi are fully customizable blockchains benefiting from a shared set of sequencers and the security of a provider of their choice. The templates presented in this article implement the necessary functionalities and configurations to support the Tanssi protocol, making development easier. ## Base Setup to Support the Tanssi Protocol {: #base-setup-supporting-tanssi } Tanssi networks must implement the following modules to support the protocol and benefit safely from Tanssi's block production as a service: - **Author Noting** - registers the set of sequencers assigned to the network by Tanssi - **Author Inherent** - allows the sequencer authoring the block to include its identity to get validated and rewarded If you don't include these modules in the Tanssi network's runtime, there won't be a method to confirm that the blocks are being generated by trustworthy sequencers designated by the Tanssi orchestrator. This could create a vulnerability for malicious actors to exploit and compromise the network. For more information about Tanssi's block production as a service please refer to the [Block Production Services](/learn/tanssi/network-services/block-production/){target=\_blank} article. Besides block production, there are other essential aspects for any network covered in the templates, such as: - **Consensus** - networks have the necessary functionality to allow the sequencers to produce blocks, gossip and validate them, and coordinate with the security provider to get notified about the block's finality - **Networks Interoperability** - handles the ingestion and dispatch of incoming downward and lateral messages, allowing a Tanssi network to communicate and interoperate with the other chains within the ecosystem - **Runtime Upgrades** - a runtime upgrade in a Tanssi network must be informed to the security provider's operators to allow them to check on the blocks produced by the sequencers of the Tanssi networks ## Included Modules {: #included-modules } Besides the necessary modules to support the operation of a Tanssi network, many other modules provide functional behavior that the users can interact with. These are some of the functional modules exposing a behavior to the users that are included in the templates and ready to use: - **[Balances](https://paritytech.github.io/substrate/master/pallet_balances/index.html){target=\_blank}** - the Balances module provides functions for handling accounts and balances for the Tanssi network native currency - **[Utility](https://paritytech.github.io/polkadot-sdk/master/pallet_utility/index.html){target=\_blank}** - the Utility module provides functions to execute multiple calls in a single dispatch. Besides batching transactions, this module also allows the execution of a call from an alternative signed origin - **[Proxy](https://paritytech.github.io/polkadot-sdk/master/pallet_proxy/index.html){target=\_blank}** - the Proxy module provides functions to delegate to other accounts (proxies) the permission to dispatch calls from a proxied origin - **[Maintenance Mode](https://github.com/moondance-labs/moonkit/blob/tanssi-polkadot-v1.3.0/pallets/maintenance-mode/src/lib.rs){target=\_blank}** - the Maintenance Mode module allows the Tanssi network to be set to a mode where it doesn't execute balance/asset transfers or other transactions. This could be useful when upgrading the runtime in an emergency, when executing large storage migrations, or when a security vulnerability is discovered - **[Tx Pause](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/tx-pause/src/lib.rs){target=\_blank}** - the Tx Pause module allows a valid origin (typically Root) to pause (and unpause) an entire module or a single transaction. A paused transaction (or all the transactions included in a paused module) will fail when called until it is unpaused. This module provides a higher degree of granularity compared to maintenance mode, making it particularly useful when a faulty or vulnerable transaction is identified in the runtime - **[Multisig](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/multisig/src/lib.rs){target=\_blank}** - the Multisig module enables transaction dispatches that require -typically- more than one signature. A multisig transaction defines a set of authorized accounts and a threshold for its approval, requiring consensus among multiple parties ## Start Building {: #getting-started } To start building on top of the provided templates, be it the [baseline Tanssi network template](/builders/build/templates/substrate/){target=\_blank} or the [baseline EVM (Ethereum Virtual Machine) template](/builders/build/templates/evm/){target=\_blank}, the recommended approach is to fork the [Tanssi repository](https://github.com/moondance-labs/tanssi){target=\_blank} and start adding [built-in modules](/builders/build/customize/adding-built-in-module/){target=\_blank} or [custom-made modules](/builders/build/customize/adding-custom-made-module/){target=\_blank} on top of the [latest release](https://github.com/moondance-labs/tanssi/releases/latest){target=\_blank} tag. This approach comes with some advantages, such as: - Building on top of the latest and stable release - Get the Tanssi protocol already configured and included in the template runtime - Keep your fork up-to-date by syncing with the Tanssi upstream repository - Run the included tests, ensuring that block production on your Tanssi network works as intended - Run a complete local environment with the included [Zombienet](https://paritytech.github.io/zombienet){target=\_blank} configuration If the templates already cover your use case needs, or after building and testing your chain, you can continue with the [Deploy Your Network via the Tanssi DApp](/builders/deploy/dapp/){target=\_blank} article to know how to use the Tanssi dApp to register and get your chain up and running. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/deploy/dapp/ --- BEGIN CONTENT --- --- title: Deploy Your Appchain via the DApp description: Learn how to spin up and deploy an appchain on Tanssi using the Tanssi dApp, a no-code solution for onboarding and launching decentralized appchains in minutes. icon: octicons-browser-24 categories: Appchain --- # Deploy Your Appchain via the Tanssi DApp
## Introduction {: #introduction } Tanssi aims to lower the barrier to entry for building decentralized appchains by streamlining the onboarding process and abstracting away the technical details of launching a Tanssi-powered appchain. The [Tanssi dApp](https://apps.tanssi.network){target=\_blank} allows you to spin up an appchain in just minutes. This guide will walk you through the steps required to launch an appchain on Dancelight, the Tanssi TestNet, via the Tanssi dApp. ## Quick Trials vs. Dedicated appchains {: #quick-trial-vs-dedicated-appchains } [The Tanssi dApp](https://apps.tanssi.network){target=\_blank} supports the creation of two different types of appchains, namely: - Quick trial - a temporary appchain that self-destructs after 48 hours - Dedicated - a long-lasting appchain for Tanssi ecosystem builders Both types of Tanssi appchains behave identically, with the only difference being the ephemeral nature of the quick trials. Generally speaking, quick trial appchains are best for most builders who want to test out a Tanssi-powered appchain. However, if you require a long-lasting test environment, the Tanssi team will happily assist you with setting up a dedicated appchain. The screenshots and content in this guide will showcase quick trial appchains, but you can follow the same process to configure a dedicated Tanssi appchain. ![A screenshot showing the initial dashboard of apps.tanssi.network.](/images/builders/deploy/dapp/dapp-1.webp) ## Prerequisites {: #prerequisites } ### Supported Wallets {: #supported-wallets } Since Tanssi is built with Substrate, you'll need to use a Substrate-compatible wallet to deploy and manage your Tanssi appchain. Supported wallets include: - [Talisman](https://talisman.xyz/){target=\_blank} - [SubWallet](https://www.subwallet.app){target=\_blank} - [Enkrypt](https://www.enkrypt.com){target=\_blank} - [Polkadot.js extension](https://polkadot.js.org/extension){target=\_blank} If you deploy a Tanssi-powered EVM appchain, your users won't need a Substrate wallet. They can interact with your Tanssi appchain using Ethereum-compatible wallets like [MetaMask](/builders/toolkit/ethereum-api/wallets/metamask/){target=\_blank}. ![Connection screen for various Substrate wallets](/images/builders/deploy/dapp/dapp-2.webp) ### Connect Your Wallet to the DApp {: #connect-wallet } To connect your wallet to the Tanssi dApp, click **Connect Wallet** in the upper-right corner. Select the desired wallet type. Then, take the following steps: 1. Choose your account from the dropdown 2. You'll be prompted to sign a message to log you into the Tanssi dApp. Go ahead and sign the message ![Click on the Connect Wallet button to connect your wallet to the Tanssi dApp.](/images/builders/deploy/dapp/dapp-3.webp) Once connected, you'll see your address in the top-right corner. If you've connected multiple accounts and want to switch accounts, you can click on your address and choose an account from the dropdown menu. ## Configure Your Appchain {: #configure-your-appchain } On the dApp [Home page](https://apps.tanssi.network/){target=\_blank}, click the **Start Building** button in the **Launch Network** block to start configuring your Tanssi appchain immediately. You have to choose between a **Quick Trial** or a **Dedicated** appchain. You can read more about [the differences between these two available types on the Tanssi Testnet](#quick-trial-vs-dedicated-appchains). ![A screenshot showing the Launch Network section of apps.tanssi.network.](/images/builders/deploy/dapp/dapp-1.webp) Next, select a template that best fits your use case and configure your Tanssi appchain's properties accordingly. You can choose from the EVM or Substrate template or upload a raw specification file. Please refer to the [Templates](/builders/build/templates/overview/){target=\_blank} documentation to learn more about the available templates. ### EVM Template {: #evm-template } The [EVM template](/builders/build/templates/evm/){target=\_blank} provides all the necessary components to add an Ethereum compatibility layer to your Tanssi appchain. As part of the setup process, you'll need a unique EVM chain ID ([EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md){target=\_blank}) that is distinct from all other EVM chains. You can verify that another chain does not already use your EVM chain ID on [Chainlist](https://chainid.network){target=\_blank}. When launching your Tanssi appchain in production, it's critical that you open a PR to reserve your chain ID on the [`ethereum-lists/chains` GitHub repository](https://github.com/ethereum-lists/chains){target=\_blank} immediately after your RPC endpoint spins up. This is part of the validation process and is required for the PR to be accepted and merged. !!! note A registered EVM chain ID is only necessary for Tanssi appchains deployed on the MainNet. When testing or deploying on the TestNet, you can choose any available ID and move forward. To get started, select the **EVM** template from the left-side menu. Then take the following steps: 1. In the **Network Details** section, provide your project's name, your unique EVM chain ID, and select the category that best fits your use case 2. In the **Gas Token** section, enter the symbol of your appchain's native token. Decimal places are fixed to 18 digits, the same as Ether, to preserve compatibility across EVM tooling 3. (Optional) You can adjust the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559){target=\_blank} configurations in the **Advanced** settings. You can choose to change the **Base fee per gas** and **Max base fee change** 4. In the **Accounts** section, provide the Ethereum-style address of the account you want to use as the sudo account and its corresponding initial balance. This account will be able to dispatch privileged functions that require Root permissions. There can only be one sudo account at a time. The sudo account can be changed at any time to a new one by the current sudo account. Once the Tanssi appchain is launched, you can easily migrate to a fully decentralized system using specific democracy-related modules 5. (Optional) In the **Advanced** section, click on **Add** to add genesis accounts and balances. If you choose to skip this step, you can use the sudo account to create accounts and transfer funds at a later time 6. (Optional) In the **Genesis Smart Contracts**, click on **Add** to add genesis smart contracts by providing an address to use and the bytecode for the smart contract. When providing the bytecode, you'll need to remove the `0x` from the beginning of the bytecode 7. Once you have configured the template for your Tanssi appchain, select **Continue** and proceed to the [Check Balances section](#check-balances) ![Create a Tanssi EVM Appchain with the Tanssi dApp.](/images/builders/deploy/dapp/dapp-4.webp) ### Substrate Template {: #substrate-template } The [Substrate template](/builders/build/templates/overview/#baseline-network-template){target=\_blank} includes all the configurations for seamless integration with Tanssi. It can be used as the baseline specification to build a custom Tanssi-powered appchain leveraging the modularity and scalability of the Substrate framework. To get started, select the **Substrate** template from the left-side menu. Then take the following steps: 1. In the **Network Details** section, enter your project's name and select the category that best fits your use case 2. In the **Gas Token** section, enter the token decimals, symbol, and the [SS58 address format](https://github.com/paritytech/ss58-registry/blob/main/ss58-registry.json){target=\_blank} 3. In the **Accounts** section, provide the Substrate-style address of the account you want to use as the sudo account and its initial balance. This account will be able to dispatch privileged functions that require Root permissions. There can only be one sudo account at a time. The sudo account can be changed at any time to a new one by the current sudo account. Once the appchain is launched, you can easily migrate to a fully decentralized system using specific democracy-related modules 4. (Optional) In the **Advanced** section, click on **Add** to add genesis accounts and balances. If you choose to skip this step, you can use the sudo account to create accounts and transfer funds at a later time 5. Once you have configured the template for your Tanssi appchain, you can select **Continue** to proceed to the [Check Balances section](#check-balances) ![Create a baseline Substrate Appchain with the Tanssi dApp.](/images/builders/deploy/dapp/dapp-5.webp) ### Custom {: #custom } If you already have a Substrate runtime built and have chosen to upload your own custom specification file, there are some requirements you should be aware of to ensure the runtime can evolve into a Tanssi-powered appchain and run properly. Your runtime must implement the following: - The Cumulus SDK, as outlined in the [Base Setup to Connect to Polkadot](/builders/build/templates/overview/#base-setup-to-polkadot){target=\_blank} section of the [Templates](/builders/build/templates/overview/){target=\_blank} page - Tanssi modules for block production, as outlined in the [Base Setup to Support the Tanssi Protocol](/builders/build/templates/overview/#base-setup-supporting-tanssi){target=\_blank} section of the [Templates](/builders/build/templates/overview/){target=\_blank} page Other required changes in the runtime include: - To verify the author's eligibility to produce a block, set the following type as shown in the snippet, in the `timestamp` module configuration section of the runtime: ```rust type OnTimestampSet = tp_consensus::OnTimestampSet< ::SlotBeacon, ConstU64<{ SLOT_DURATION }>, >; ``` - Remove all the modules related to block production and consensus (such as `Aura` and `Grandpa`), leaving Tanssi to take over the burden. If the starting point for your project was the parachain template, the following modules are included by default in the runtime and must be removed: ```rust // Collator support. The order of these 4 are important and shall not change. #[runtime::pallet_index(20)] pub type Authorship = pallet_authorship; #[runtime::pallet_index(21)] pub type CollatorSelection = pallet_collator_selection; #[runtime::pallet_index(22)] pub type Session = pallet_session; #[runtime::pallet_index(23)] pub type Aura = pallet_aura; #[runtime::pallet_index(24)] pub type AuraExt = cumulus_pallet_aura_ext; ``` Finally, [generate and edit](/builders/build/customize/customizing-chain-specs/#editing-json-chain-specs){target=\_blank} the chain specification paying special attention to: - `para_id` - within this custom flow, a pre-registered appchain id is required. You can get an appchain ID moving forward with the registration to the **Reserve your Network ID** step. After you reserve the ID, start over the process to get back to this point - `is_ethereum` - to `true` if exposing Ethereum compatible RPC endpoints is needed And, depending on whether you are deploying a quick trial appchain or a dedicated one, also adjust these attributes: === "Quick Trial Appchain" ```json { ... "relay_chain": "rococo_flashbox_relay_testnet", "chainType": "Live", "genesis": { "runtime": { ... "authoritiesNoting": { "orchestratorParaId": 1000 }, ... } } ... } ``` === "Dedicated Appchain" ```json { ... "relay_chain": "rococo-local", "chainType": "Live", "genesis": { "runtime": { ... "authoritiesNoting": { "orchestratorParaId": 0 }, ... } } ... } ``` Now, you can upload your custom raw specification file by selecting the **Custom** template and adding your JSON specification file. ![Upload a custom raw specification file to the Tanssi dApp.](/images/builders/deploy/dapp/dapp-6.webp) !!! note The size of a raw chain specifications file should not exceed 2MB. ## Check Balances {: #check-balances } Next, you'll need to verify that you have sufficient balance. If you don't, you can press **Request Tokens** and complete the following login with GitHub or Google. You'll need to complete a few quick onboarding questions, and then you'll be able to press **Request Tokens** again, and they will be delivered to your connected wallet. ![Request tokens](/images/builders/deploy/dapp/dapp-7.webp) If you're setting up a dedicated Tanssi appchain, you'll need to fill out an [application form](https://www.tanssi.network/dedicated-chain-testnet-form){target=\_blank}. The Tanssi team will review your application and send the necessary tokens within one business day. The required minimum balances to launch a Tanssi appchain are as follows: === "Quick Trial Appchain" | Chain | Balance Required | |:-------------------:|:----------------:| | Orchestration layer | 70 UNIT | | Tanssi TestNet | 100 SNAP | === "Dedicated Appchain" | Chain | Balance Required | |:----------------------------:|:----------------:| | Tanssi TestNet | 100 STAR | !!! note Quick trial appchains use an additional orchestration layer, therefore two different tokens, SNAP and UNIT, will be sent to your account. For dedicated appchains only STAR tokens are required. ## Reserve your Appchain ID {: #reserve-appchain-id } If you haven't already done so, you must to reserve your Tanssi appchain ID, which will identify your chain within the Tanssi ecosystem. To reserve your Tanssi appchain ID, you'll need to submit a transaction. Please make sure to use the account you plan to launch your Tanssi appchain with when submitting the transaction. 1. To initiate the transaction, click on **Reserve Network ID** 2. Your wallet will pop up, and you'll need to submit the transaction ![Reserve your Tanssi-powered Appchain ID via the Tanssi dApp.](/images/builders/deploy/dapp/dapp-8.webp) Once the transaction has successfully gone through, your Tanssi appchain ID will be displayed on the dApp, and you'll be able to click **Continue** to proceed to the next step. You'll notice that some of your UNIT (or STAR if registering a dedicated Appchain) tokens have been removed from your transferrable balance and are now reserved. ![Successfully reserved your Tanssi-powered Appchain ID via the Tanssi dApp.](/images/builders/deploy/dapp/dapp-9.webp) ## Generate Your Appchain Files {: #generate-appchain-files } Before you can deploy your Tanssi appchain, you'll need to generate three configuration files: - [The raw chain specification](/builders/build/customize/customizing-chain-specs/#generating-raw-specs-file){target=\_blank} - a compact version of the JSON specification file, which defines the initial settings and state that all nodes participating in the network must agree on to reach consensus and produce blocks - [The genesis state header](/builders/build/customize/customizing-chain-specs/#genesis-state){target=\_blank} - defines the initial state upon which all transactions and state transitions are executed - [The genesis Wasm](/learn/framework/architecture/#runtime){target=\_blank} - a WebAssembly (Wasm) blob that defines the runtime logic These files will automatically be generated for you based on your Tanssi appchain ID and your customized template configurations. All you need to do is click **Generate**, and the dApp will generate the required files for you. ![Generate your Tanssi-powered appchain files with the click of a button on the Tanssi dApp.](/images/builders/deploy/dapp/dapp-10.webp) Once the files have been generated, please click **Continue** to go on to the final step. ## Deploy Your appchain {: #deploy-your-appchain } You're finally ready to take your last step towards preparing your appchain as it evolves into a Tanssi-powered appchain! For this final step, when registering a quick trial you'll need to submit two transactions: one to register your appchain on the orchestration layer and another to register your appchain on the Tanssi TestNet. To register your appchain on the orchestration layer, take the following steps: 1. Click **Register** under the **Register Network in Relay** section 2. Confirm the transaction in your wallet ![Register your Tanssi-powered appchain on the orchestration layer.](/images/builders/deploy/dapp/dapp-11.webp) Once the transaction has gone through successfully, the dApp will update to show that you have successfully registered your Tanssi appchain under the **Register Network in Relay** section. Lastly, to register your appchain on Tanssi, take the following steps: 1. Click **Register** under the **Register Network in Tanssi** section 2. Confirm the transaction in your wallet ![Register your appchain on Tanssi.](/images/builders/deploy/dapp/dapp-12.webp) Once the transaction has gone through successfully, the dApp will update to show that you have registered your Tanssi-powered appchain. Congratulations! On the dashboard, you can check the status of your deployment and view relevant information, such as the latest block information, RPC and WS endpoints, and more. ![The appchain dashboard on the Tanssi dApp.](/images/builders/deploy/dapp/dapp-13.webp) And that's it! You've successfully registered your Tanssi appchain! The launch process will automatically begin once the Tanssi team has verified your registration. Once your appchain is live, you can return to the **Dashboard** to view the RPC URL and other pertinent chain information. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/manage/dapp/manage-tokens/ --- BEGIN CONTENT --- --- title: Manage Tokens description: Learn how the network governor can manage the token of a Tanssi-powered network using the dApp to mint them, configure the EIP-1559 fee market, and more. icon: octicons-database-24 categories: Appchain --- # Manage Tokens ## Introduction {: #introduction } Any network deployed through Tanssi is sovereign and free to define the governance model that best fits its use case. The network governor has superpowers over the chain administration. Consequently, they can call privileged functions, such as updating the runtime and managing native token-related operations, among other actions. There are some actions related to the native token management that are available to the network governor on the Tanssi dApp: - **Mint tokens** - mints new tokens, increasing the total supply - **Update balances** - increases or decreases the balance of an account, affecting the total supply - **Transfer tokens** - executes a forced token transfer from one account to another - **Configure gas dynamics** - only available on EVM-compatible networks, this action changes the [EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md){target=\_blank} configuration, affecting the transaction pricing mechanism In this guide, you'll learn how to execute the previously listed actions using the [Tanssi dApp](https://apps.tanssi.network){target=\_blank}. ## Checking Prerequisites {: #checking-prerequisites } For the examples in this guide, you will need to have the following: - A Tanssi-powered network (Quick Trial or Dedicated) - The account you used when registering the network, imported in any of the [supported wallets](/builders/deploy/dapp/#supported-wallets){target=\_blank} - Your network's Sudo account, also imported in any of the [supported wallets](/builders/deploy/dapp/#supported-wallets){target=\_blank} !!! note The network's registration account is always a Substrate one, whereas the network's Sudo account depends on the chain type. If the chain is EVM-compatible, then the Sudo account will be an Ethereum type and, otherwise, a Substrate type. ### Retrieving the Registration Account {: #retrieving-registration-account } If you're unsure what your registration account is, you can query it directly from the Tanssi orchestrator chain, which keeps records of every registered network. To do so, head to the **Chain state** section on the Polkadot.js Apps connected to the orchestrator chain for [quick trial networks](https://polkadot.js.org/apps/?rpc=wss://fraa-flashbox-rpc.a.stagenet.tanssi.network#/chainstate){target=\_blank} or [dedicated networks](https://polkadot.js.org/apps/?rpc=wss://services.tanssi-testnet.network/dancelight#/chainstate){target=\_blank}, and take the following steps: 1. Select the **registrar** storage module 2. Select **registrarDeposit** 3. Insert your network ID 4. Press **+** icon You'll see the registration account at the bottom. ![Locating your registration account](/images/builders/manage/dapp/locate-registration-account.webp) !!! note The dApp will show your network in the dashboard only if you have the registration account properly set. ### Retrieving the Sudo Account {: #retrieving-sudo-account } If you're unsure what your Tanssi network's Sudo account is, you can find it in your [Tanssi Dashboard](https://apps.tanssi.network){target=\_blank} underneath the **Properties** section. ![Locating your Sudo address on apps.tanssi.network](/images/builders/manage/locate-sudo-account.webp) !!! warning It's critical to protect your Sudo account key with the utmost security precautions, as it grants privileged access to your Tanssi network. ## Accessing the Token Management Panel {: #accesing-token-management-panel } The Tanssi dApp implements a smooth interface, allowing the network governor to access and execute privileged functions. To do so, head to the [Tanssi dApp](https://apps.tanssi.network/){target=\_blank}, and then: 1. Click on the **Manage** button 2. Click on the **Token Management** button. ![Accessing the token management panel](/images/builders/manage/dapp/token-management/token-management-1.webp) Now you have direct access to the actions presented in the introduction: 1. **Mint Tokens** 2. **Update Balances** 3. **Transfer Tokens** 4. Configure **Gas Dynamics** ![The token management panel](/images/builders/manage/dapp/token-management/token-management-2.webp) !!! note If you don't see your network's details on the dashboard, make sure to comply with the [prerequisites](#checking-prerequisites). ### Minting Tokens {: #minting-tokens } The network governor can mint new tokens, increasing its total supply. To do so, in the **Token Management** panel, click on the **Mint tokens** button, and then: 1. Insert the address that will hold the newly minted tokens !!! note The destination address must be Ethereum type if the chain is EVM-compatible and a Substrate type otherwise. 2. Insert the amount of tokens to mint 3. Click on **Mint** ![Mint tokens](/images/builders/manage/dapp/token-management/token-management-3.webp) You'll be asked to sign the transaction with the network's governor account. Once the transaction has gone through, the destination account's balance will have been increased by the desired amount. ### Updating Balances {: #updating-balances } The network governor can increase or decrease the balance of any account, thus affecting the total supply. To do so, in the **Token Management** panel, click on the **Update Balances** button, and then: 1. Insert the address that will hold the newly minted tokens. Once you enter the address, its current balance will be displayed !!! note The destination address must be Ethereum type if the chain is EVM-compatible and a Substrate type otherwise. 2. Insert the new balance the address will hold 3. Click on **Update** ![Update Balances](/images/builders/manage/dapp/token-management/token-management-4.webp) You'll be asked to sign the transaction with the network's governor account. Once the transaction has gone through, the destination account's balance will reflect exactly the desired amount, regardless of previous holdings. ### Executing Forced Transfers {: #forced-transfers } The network governor can reassign balances, forcing a token transfer from one account to another. To do so, in the **Token Management** panel, click on the **Transfer Tokens** button, and then: 1. Insert the origin address that will transfer its tokens 2. Insert the destination address that will receive the tokens !!! note The origin and destination addresses must be Ethereum type if the chain is EVM-compatible and Substrate type otherwise. 3. Insert the amount of tokens to transfer 4. Click on **Transfer** ![Transfer Tokens](/images/builders/manage/dapp/token-management/token-management-5.webp) You'll be asked to sign the transaction with the network's governor account. Once the transaction has gone through, the destination account will have received the number of tokens from the origin address. ### Setting Gas Dynamics {: #setting-gas } !!! note This option only applies to EVM-compatible networks. The governor of a Tanssi-powered EVM-compatible network can change its [EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md){target=\_blank} configuration, affecting the transaction pricing mechanism. To do so, in the **Token Management** panel, click on the **Gas Dynamics** button, and then: 1. Insert the new base fee, expressed in Wei units (10-18) 2. Insert the elasticity value 3. Click on **Update Dynamics** ![Configure Gas Dynamics](/images/builders/manage/dapp/token-management/token-management-6.webp) You'll be asked to sign the transaction with the network's governor account. Once the transaction has gone through, the network's fee mechanism will run with the new transaction pricing parameters. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/manage/dapp/register-external-assets/ --- BEGIN CONTENT --- --- title: Register External Assets description: Tanssi networks benefit from native cross-chain communication, enabling smooth and fast token transfers between the token’s native chain and other chains. categories: Appchain --- # Register External Assets ## Introduction {: #introduction } Cross-chain asset transfer is crucial because it enables the seamless movement of digital assets across different networks, enhancing interoperability, liquidity, and user experience. To enable asset transfers to and from two networks, first, a bidirectional channel must be open between them. Thanks to the Tanssi dApp, opening a channel is an easy and quick task. Please refer to the [Manage Cross-Chain Communication Channels](/builders/manage/dapp/xcm-channels/){target=\_blank} article to know how to do it. !!! note Opening a bidirectional communication channel requires approval from both networks governors. Once your network's communication channels are established, you can register other chain's assets (external assets) to start operating. This guide will walk you through the process of registering external assets using the [Tanssi dApp](https://apps.tanssi.network){target=\_blank}. ## Checking Prerequisites {: #checking-prerequisites } For the examples in this guide, you will need to have the following: - A Tanssi-powered network (Dedicated) running [runtime 500](https://github.com/moondance-labs/tanssi/releases/tag/runtime-500){target=\_blank} or above - The account you used when registering the network, imported in any of the [supported wallets](/builders/deploy/dapp/#supported-wallets){target=\_blank} - Your network's Sudo account, also imported in any of the [supported wallets](/builders/deploy/dapp/#supported-wallets){target=\_blank} !!! note The network's registration account is always a Substrate one, whereas the network's Sudo account depends on the chain type. If the chain is EVM-compatible, then the Sudo account will be an Ethereum type and, otherwise, a Substrate type. ### Retrieving the Registration Account {: #retrieving-registration-account } If you're unsure what your registration account is, you can query it directly from the Tanssi orchestrator chain, which keeps records of every registered network. To do so, head to the **Chain state** section on the Polkadot.js Apps connected to the orchestrator chain for [quick trial networks](https://polkadot.js.org/apps/?rpc=wss://fraa-flashbox-rpc.a.stagenet.tanssi.network#/chainstate){target=\_blank} or [dedicated networks](https://polkadot.js.org/apps/?rpc=wss://services.tanssi-testnet.network/dancelight#/chainstate){target=\_blank}, and take the following steps: 1. Select the **registrar** storage module 2. Select **registrarDeposit** 3. Insert your network ID 4. Press **+** icon You'll see the registration account at the bottom. ![Locating your registration account](/images/builders/manage/dapp/locate-registration-account.webp) !!! note The dApp will show your network in the dashboard only if you have the registration account properly set. ### Retrieving the Sudo Account {: #retrieving-sudo-account } If you're unsure what your Tanssi network's Sudo account is, you can find it in your [Tanssi Dashboard](https://apps.tanssi.network){target=\_blank} underneath the **Properties** section. ![Locating your Sudo address on apps.tanssi.network](/images/builders/manage/locate-sudo-account.webp) !!! warning It's critical to protect your Sudo account key with the utmost security precautions, as it grants privileged access to your Tanssi network. ## Accessing the External Assets Registration Panel {: #accesing-external-assets-management-panel } The Tanssi dApp makes it easy for the network governor to manage cross-chain communication configurations. It allows requesting new channels, accepting incoming channel opening requests, closing existing channels, managing external assets, and more. To access the cross-chain management panel, head to the [Tanssi dApp](https://apps.tanssi.network/){target=\_blank}, and then: 1. Click on the **Manage** button 2. Click on the **XCM** button ![Accessing the cross-chain management panel](/images/builders/manage/dapp/access-xcm-management-panel.webp) !!! note If you don't see your network's details on the dashboard, make sure to comply with the [prerequisites](#checking-prerequisites). The panel will show your network's cross-chain configuration along with several available actions. Regarding external assets, the relevant elements you are presented with are: 1. **Registered Assets panel** - this section will group and present to you all registered assets your network already has available 2. **Registered Assets List** - already registered external assets will be displayed in this section, along with their associated information such as asset name, symbol, ID, total supply, and network ID where it is native 3. **Asset Registration** - this option allows you to select other available external assets and register them. The [following section](#register-external-asset) explains how to do it ![The cross-chain management panel](/images/builders/manage/dapp/register-external-assets/register-external-assets-1.webp) ## Register an External Asset {: #register-external-asset } Provided your network has already established bidirectional communicaction channels with another network, the network governor can register external assets. To do so, click on **Asset Registration** and then: 1. Select at least one of the available assets from the list 2. Click on **Register** You'll be asked to sign the transaction, and once it's gone through, the external asset will be available locally. ![Asset registration](/images/builders/manage/dapp/register-external-assets/register-external-assets-2.webp) !!! note The dApp only presents well-known assets from well-known networks of the ecosystem. If the asset you need to register is not listed, you'll have to do it using the developer portal. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/manage/dapp/services-payment/ --- BEGIN CONTENT --- --- title: Block Production Services Payment description: Networks deployed through Tanssi benefit from block production services provided by a set of node operators, which are compensated with Tanssi tokens. icon: octicons-server-24 categories: Appchain --- # Block Production Services Payment ## Introduction {: #introduction } As presented in the [Block Production as a Service](/learn/tanssi/network-services/block-production/#block-production-fees){target=_\blank} article, there are two main costs associated that the network governor must cover: - **Sequencers assignment** - for the assignment of sequencers by the Tanssi protocol, which happens once per session - **Block production** - for each block that is produced on the network's behalf In this guide, you'll learn how to use the [Tanssi dApp](https://apps.tanssi.network){target=\_blank} to top-up your account and keep your network's liveness. ## Checking Prerequisites {: #checking-prerequisites } For the examples in this guide, you will need to have the following: - A Tanssi-powered network (Quick Trial or Dedicated) - The account you used when registering the network, imported in any of the [supported wallets](/builders/deploy/dapp/#supported-wallets){target=\_blank} If you're unsure what your registration account is, you can query it directly from the Tanssi orchestrator chain, which keeps records of every registered network. To do so, head to the **Chain state** section on the Polkadot.js Apps connected to the orchestrator chain for [quick trial networks](https://polkadot.js.org/apps/?rpc=wss://fraa-flashbox-rpc.a.stagenet.tanssi.network#/chainstate){target=\_blank} or [dedicated networks](https://polkadot.js.org/apps/?rpc=wss://services.tanssi-testnet.network/dancelight#/chainstate){target=\_blank}, and take the following steps: 1. Select the **registrar** storage module 2. Select **registrarDeposit** 3. Insert your network ID 4. Press **+** icon You'll see the registration account at the bottom. ![Locating your registration account](/images/builders/manage/dapp/locate-registration-account.webp) !!! note The dApp will show your network in the dashboard only if you have the registration account properly set. ## Topping-Up Your Network's Credits {: #topping-up } Following a pay-as-you-go model, the networks must have funds allocated to pay for the services, which, over time, will be deducted and burned by the Tanssi protocol upon every session change for the cost of the sequencer's assignment and for every block for the cost of producing the block. You can check your network's current balance and top it up using the Tanssi dApp. To do so, head to the [Tanssi dApp](https://apps.tanssi.network/){target=\_blank} and connect the network's registration account to the dApp. The site will display a card showing your network status. This card includes the projected liveness forecast underneath the **Block Production** section and the **Top Up** button. ![Top-up action button in the dApp](/images/builders/manage/dapp/services-payment/services-payment-1.webp) Clicking on the **Top Up** button displays a sidebar where the following information can be seen: - **Current balance** - the current balance allocated for the network's block production service - **Available balance** - the balance available in the network's registration account, which is connected to the dApp - **Current cost** - current cost per sequencer's assignment and cost per block - **Projected forecast** - the estimated day when the network runs out of funds and stops being served To extend the network's projected runway, take the following actions: 1. Insert the amount of tokens to buy block production services 2. Click **Top Up** ![Top-up sidebar](/images/builders/manage/dapp/services-payment/services-payment-2.webp) You will be asked to sign the transaction, and after it's gone through, your network will benefit from an extended horizon of liveness. !!! warning If your network doesn't have enough funds to cover the sequencer's assignment and one session's worth of blocks, it will stall. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/manage/dapp/xcm-channels/ --- BEGIN CONTENT --- --- title: Manage Cross-Chain Communication Channels description: Tanssi networks benefit from native cross-chain communication, which allows fast and secure bridging leveraging the architecture they are built on top of. categories: Appchain --- # Manage Cross-Chain Communication Channels ## Introduction {: #introduction } As presented in the [Native Cross-Chain Communication](/learn/framework/xcm/){target=\_blank} article from the Learn section, all Tanssi-powered networks have an inherent capability to communicate and interoperate with any other network in the ecosystem. This native cross-chain communication feature is possible thanks to the unique infrastructure the networks are built on top of, leveraging the Cross-Consensus Message format (XCM for short), which facilitates communication between different consensus systems. The first step to enable communication between networks is [opening a channel](/learn/framework/xcm/#channel-registration){target=\_blank}. The process of opening a channel starts by sending a request to the network you want to establish communications with. Once the request has been accepted by the destination chain's governor, a channel will be opened. In this guide, you'll learn how to use the [Tanssi dApp](https://apps.tanssi.network){target=\_blank} to manage your network's cross-chain communication channels. ## Checking Prerequisites {: #checking-prerequisites } For the examples in this guide, you will need to have the following: - A Tanssi-powered network (Dedicated) running [runtime 500](https://github.com/moondance-labs/tanssi/releases/tag/runtime-500){target=\_blank} or above - The account you used when registering the network, imported in any of the [supported wallets](/builders/deploy/dapp/#supported-wallets){target=\_blank} - Your network's Sudo account, also imported in any of the [supported wallets](/builders/deploy/dapp/#supported-wallets){target=\_blank} !!! note The network's registration account is always a Substrate one, whereas the network's Sudo account depends on the chain type. If the chain is EVM-compatible, then the Sudo account will be an Ethereum type and, otherwise, a Substrate type. ### Retrieving the Registration Account {: #retrieving-registration-account } If you're unsure what your registration account is, you can query it directly from the Tanssi orchestrator chain, which keeps records of every registered network. To do so, head to the **Chain state** section on the Polkadot.js Apps connected to the orchestrator chain for [quick trial networks](https://polkadot.js.org/apps/?rpc=wss://fraa-flashbox-rpc.a.stagenet.tanssi.network#/chainstate){target=\_blank} or [dedicated networks](https://polkadot.js.org/apps/?rpc=wss://services.tanssi-testnet.network/dancelight#/chainstate){target=\_blank}, and take the following steps: 1. Select the **registrar** storage module 2. Select **registrarDeposit** 3. Insert your network ID 4. Press **+** icon You'll see the registration account at the bottom. ![Locating your registration account](/images/builders/manage/dapp/locate-registration-account.webp) !!! note The dApp will show your network in the dashboard only if you have the registration account properly set. ### Retrieving the Sudo Account {: #retrieving-sudo-account } If you're unsure what your Tanssi network's Sudo account is, you can find it in your [Tanssi Dashboard](https://apps.tanssi.network){target=\_blank} underneath the **Properties** section. ![Locating your Sudo address on apps.tanssi.network](/images/builders/manage/locate-sudo-account.webp) !!! warning It's critical to protect your Sudo account key with the utmost security precautions, as it grants privileged access to your Tanssi network. ## Accessing the Channel Management Panel {: #accesing-channel-management-panel } The Tanssi dApp makes it easy for the network governor to manage cross-chain communication configurations. It allows requesting new channels, accepting incoming channel opening requests, closing existing channels, managing external assets, and more. To access the cross-chain management panel, head to the [Tanssi dApp](https://apps.tanssi.network/){target=\_blank}, and then: 1. Click on the **Manage** button 2. Click on the **XCM** button ![Accessing the cross-chain management panel](/images/builders/manage/dapp/access-xcm-management-panel.webp) !!! note If you don't see your network's details on the dashboard, make sure to comply with the [prerequisites](#checking-prerequisites). The panel will show your network's communication channels status along with several available actions. The elements you are presented with are: 1. **Sovereign account** - is a keyless account that belongs to the network in a different consensus system, the relay chain in this case. It can only be used by the network's governor. Before opening a new channel, the network's sovereign account in the relay chain must be funded with enough tokens to be locked as a channel deposit. In this section, you can see your network's sovereign account balance, copy its address, and deposit tokens 2. **Incoming/Outgoing channel requests** - every channel request needs to be accepted by the counterpart before any message can be sent. In this section, you can see the list of pending outgoing requests and cancel them. You can also see any incoming channel requests your network might have received and accept the channel 3. **Established channels** - Once the destination chain's governor has accepted the channel request, the channel becomes open and available for message transmission. In this section, you can see the list of accepted channels your network has, the direction in which the messages flow through the channel, and cancel the channel 4. **Request to open new channels** - this option allows you to select an existing network within the ecosystem and request a channel to be opened. The [next section](#request-new-channel) explains how to do it ![The channel management panel](/images/builders/manage/dapp/xcm-channels/xcm-channels-1.webp) ## Request to Open New Channel {: #request-new-channel } Provided that your network has enough funds for the deposit in its relay chain's sovereign account, the network governor can request to open a new channel with any other network. To do so, click on **HRMP Channels** and then: 1. Select the network you want to establish a channel with 2. Click on **Request Channel** You'll be asked to sign the transaction, and once it's gone through, the destination chain will receive the request. ![Channel opening request](/images/builders/manage/dapp/xcm-channels/xcm-channels-2.webp) --- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/manage/developer-portal/impersonate/ --- BEGIN CONTENT --- --- title: Impersonating Other Accounts With Sudo description: Learn how to use the Sudo key to dispatch calls by signing a transaction as if it came from a different account. icon: octicons-person-add-24 categories: Appchain --- # Using Sudo to Impersonate Other Accounts ## Introduction {: #introduction } [Sudo](https://paritytech.github.io/polkadot-sdk/master/pallet_sudo/index.html){target=\_blank} is a module that enables privileged runtime calls to be dispatched when called from the Sudo account. Sudo is sometimes colloquially referred to as a superuser or god-like account. This allows you to perform privileged actions while managing your network, such as impersonating other accounts. In this guide, you'll learn how to use Sudo to impersonate other accounts. For example, this guide will use the Sudo account to pose as an arbitrary account and transfer funds from said account. !!! warning The balance transfer demonstrated in this guide is dubious, and it is shown only as an example of using Sudo. ## Checking Prerequisites {: #checking-prerequisites } For the examples in this guide, you will need to have the following: - A Tanssi-powered network (Quick Trial or Dedicated) - Your network's Sudo account connected to your network's Polkadot.js Apps. You can refer to the [Managing Sudo guide](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank} for instructions on injecting your Sudo account into Polkadot.js Apps If you're unsure what your Tanssi network's Sudo account is, you can find it in your [Tanssi Dashboard](https://apps.tanssi.network){target=\_blank} underneath the **Properties** section. ![Locating your Sudo address on apps.tanssi.network](/images/builders/manage/locate-sudo-account.webp) !!! warning It's critical to protect your Sudo account key with the utmost security precautions, as it grants privileged access to your Tanssi network. ## Using the Sudo As Method {: #using-the-sudo-as-method } As you know, the Sudo account can perform privileged functions, including impersonating other accounts. When submitting a call via `sudoAs`, the runtime will first authenticate the Sudo key and then dispatch the desired function call with the `Signed` origin from a given account. In the following example, the `sudoAs` method will orchestrate sending some tokens to another account. While the result is similar to using Sudo with a `forceBalanceTransfer` call, the following example uses a regular balance transfer call where the origin is the sender's account rather than the Sudo account. To make a `sudoAs` call to impersonate another account, navigate to the **Developer** tab of Polkadot.js Apps for your Tanssi-powered network and click on **Sudo**. If you do not see **Sudo** in this menu, then you have not associated the Sudo account with Polkadot.js Apps. Ensure that your Sudo account is injected by your wallet and connected to Polkadot.js Apps. Then, take the following steps: 1. Select the **Sudo** pallet 2. Select the **sudoAs** method 3. Select or paste in the desired account to impersonate 4. Select the desired pallet for the call to submit. In this case, it is the **balances** pallet 5. Select the **transferAllowDeath** method 6. Specify the destination account for the balance transfer 7. Specify the number of tokens to send 8. Press **SubmitSudo** and confirm the resulting pop-up ![Make a Sudo as call](/images/builders/manage/developer-portal/impersonate/impersonate-2.webp) The other account had a starting balance of `1,000` tokens before the call, and subsequently dropped to `995` as expected. ![Check balances on Polkadot.js Apps](/images/builders/manage/developer-portal/impersonate/impersonate-3.webp) ## Using Sudo and the Dispatch As Utility {: #using-sudo-and-the-dispatch-as-utility } The following section will demonstrate using Sudo to dispatch calls from an arbitrary origin. When submitting a call in this manner, the runtime will first authenticate the Sudo key and then dispatch the call using the `utility` pallet and the `dispatchAs` function, allowing the transaction's origin to be exactly what you'd like. To do so, navigate to the **Developer** tab of Polkadot.js Apps for your Tanssi-powered network and click on **Sudo**. If you do not see **Sudo** in this menu, you have not associated the Sudo account with Polkadot.js Apps. Ensure that your [Sudo account is injected by your wallet and connected to Polkadot.js Apps](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank}. Then, take the following steps: 1. Select the **Sudo** pallet 2. Select the **Sudo** method 4. Select the desired pallet for the call to submit. In this case, it is the **utility** pallet 5. Select the **dispatchAs** method 6. Select **system** from the dropdown 7. Select the **signed** origin, which sets the origin of the transaction to be the specified account rather than root 8. Select the desired pallet for the call to submit. In this case, it is the **balances** pallet 9. Select the **transferAllowDeath** method 10. Specify the destination account for the balance transfer 11. Specify the number of tokens to send 12. Press **SubmitSudo** and confirm the resulting pop-up ![Use Sudo Dispatch As on Polkadot.js Apps](/images/builders/manage/developer-portal/impersonate/impersonate-4.webp) The other account had a starting balance of `995` tokens prior to the call and dropped to `990` as expected. ![Check balances on Polkadot.js Apps](/images/builders/manage/developer-portal/impersonate/impersonate-5.webp) And that's it! The [Developer Portal](/builders/manage/developer-portal/) section has plenty more guides on how to manage your Tanssi network.
The information presented herein has been provided by third parties and is made available solely for general information purposes. Tanssi does not endorse any project listed and described on the Tanssi Doc Website (https://docs.tanssi.network/). Tanssi Foundation does not warrant the accuracy, completeness or usefulness of this information. Any reliance you place on such information is strictly at your own risk. Tanssi Foundation disclaims all liability and responsibility arising from any reliance placed on this information by you or by anyone who may be informed of any of its contents. All statements and/or opinions expressed in these materials are solely the responsibility of the person or entity providing those materials and do not necessarily represent the opinion of Tanssi Foundation. The information should not be construed as professional or financial advice of any kind. Advice from a suitably qualified professional should always be sought in relation to any particular matter or circumstance. The information herein may link to or integrate with other websites operated or content provided by third parties, and such other websites may link to this website. Tanssi Foundation has no control over any such other websites or their content and will have no liability arising out of or related to such websites or their content. The existence of any such link does not constitute an endorsement of such websites, the content of the websites, or the operators of the websites. These links are being provided to you only as a convenience and you release and hold Tanssi Foundation harmless from any and all liability arising from your use of this information or the information provided by any third-party website or service.
--- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/manage/developer-portal/maintenance/ --- BEGIN CONTENT --- --- title: Enabling Maintenance Mode description: Learn how to use Sudo to turn on and off maintenance mode, which effectively pauses your network while still producing blocks and allowing select calls. icon: octicons-stop-24 categories: Appchain --- # Enabling Maintenance Mode ## Introduction {: #introduction } The [Maintenance pallet](https://moonbeam.network/news/what-is-maintenance-mode/){target=\_blank} is a module that is designed for use only in emergencies that present existential threats to the network. Enabling maintenance mode on your network will suspend the processing of all regular transactions, including EVM interactions. Block production continues at a regular cadence and allows governance and staking functions to continue. Maintenance mode filters (ignores) all calls outside of governance and staking. Once maintenance mode is exited, your chain will process any pending transactions that queued up while your chain was in maintenance mode. Maintenance mode is intended to be used only as a temporary, emergency measure. For example, imagine discovering a critical exploit on your network that could result in significant financial losses if malicious actors exploit it. While you can address the issue by implementing a runtime upgrade, the process takes time—precious time during which your network remains vulnerable to attack. One potential solution is to activate maintenance mode on your network, complete the runtime upgrade, and exit maintenance mode once the fix has been verified. !!! warning Enabling maintenance mode on a production network can significantly impact the contracts on your chain. While maintenance mode is enabled, no smart contract transactions are processed, so it's critical to consider the potential ramifications before activating it. ## Checking Prerequisites {: #checking-prerequisites } For the examples in this guide, you will need to have the following: - A Tanssi-powered network (Quick Trial or Dedicated) - Your network's Sudo account connected to your network's Polkadot.js Apps. You can refer to the [Managing Sudo guide](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank} for instructions on injecting your Sudo account into Polkadot.js Apps If you're unsure what your Tanssi network's Sudo account is, you can find it in your [Tanssi Dashboard](https://apps.tanssi.network){target=\_blank} underneath the **Properties** section. ![Locating your Sudo address on apps.tanssi.network](/images/builders/manage/locate-sudo-account.webp) !!! warning It's critical to protect your Sudo account key with the utmost security precautions, as it grants privileged access to your Tanssi network. ## Enabling Maintenance Mode {: #enabling-maintenance-mode } As you know, the Sudo account can perform privileged functions, such as enabling and disabling maintenance mode. To enter maintenance mode and stop regular transaction processing, navigate to the **Developer** tab of Polkadot.js Apps for your Tanssi-powered network and click on **Sudo**. If you do not see **Sudo** in this menu, you have not associated the Sudo account with Polkadot.js Apps. Make sure that your [Sudo account is injected by your wallet and connected to Polkadot.js Apps](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank}. Then, take the following steps: 1. Select the **maintenanceMode** pallet 2. Select the **enterMaintenanceMode** method 3. Press **Submit Sudo** and confirm the transaction in the resulting pop-up ![Enable maintenance mode](/images/builders/manage/developer-portal/maintenance/maintenance-2.webp) To verify that maintenance mode has been enabled, you can check the **Explorer** section under the **Network** tab and review the recent events. ![Check maintenance mode is enabled](/images/builders/manage/developer-portal/maintenance/maintenance-3.webp) ## Exiting Maintenance Mode {: #exiting-maintenance-mode } To exit maintenance mode and return your network to normal operation, navigate to the **Developer** tab of Polkadot.js Apps for your Tanssi-powered network and click on **Sudo**. If you do not see **Sudo** in this menu, you have not associated the Sudo account with Polkadot.js Apps. Make sure that your [Sudo account is injected by your wallet and connected to Polkadot.js Apps](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank}. Then, take the following steps: 1. Select the **maintenanceMode** pallet 2. Select the **resumeNormalOperation** method 3. Press **Submit Sudo** and confirm the transaction in the resulting pop-up ![Exit maintenance mode](/images/builders/manage/developer-portal/maintenance/maintenance-4.webp) To verify that maintenance mode has been disabled, you can check in the **Explorer** section under the **Network** tab and review the recent events. ![Check maintenance mode is disabled](/images/builders/manage/developer-portal/maintenance/maintenance-5.webp) Remember that using maintenance mode is an emergency action that should only be activated when your chain is at dire risk. It may be worthwhile to establish a policy for your network that sets specific circuit breaker triggers to determine when maintenance mode will be enabled. Establishing a policy in advance will also streamline decision-making during a potential emergency. And that's it! The [Developer Portal](/builders/manage/developer-portal/) section has plenty more guides on how to manage your Tanssi-powered network.
The information presented herein has been provided by third parties and is made available solely for general information purposes. Tanssi does not endorse any project listed and described on the Tanssi Doc Website (https://docs.tanssi.network/). Tanssi Foundation does not warrant the accuracy, completeness or usefulness of this information. Any reliance you place on such information is strictly at your own risk. Tanssi Foundation disclaims all liability and responsibility arising from any reliance placed on this information by you or by anyone who may be informed of any of its contents. All statements and/or opinions expressed in these materials are solely the responsibility of the person or entity providing those materials and do not necessarily represent the opinion of Tanssi Foundation. The information should not be construed as professional or financial advice of any kind. Advice from a suitably qualified professional should always be sought in relation to any particular matter or circumstance. The information herein may link to or integrate with other websites operated or content provided by third parties, and such other websites may link to this website. Tanssi Foundation has no control over any such other websites or their content and will have no liability arising out of or related to such websites or their content. The existence of any such link does not constitute an endorsement of such websites, the content of the websites, or the operators of the websites. These links are being provided to you only as a convenience and you release and hold Tanssi Foundation harmless from any and all liability arising from your use of this information or the information provided by any third-party website or service.
--- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/manage/developer-portal/minting/ --- BEGIN CONTENT --- --- title: Minting Native Tokens with Sudo description: Learn how to use the Sudo key to manage your Tanssi-powered network and perform the privileged action of minting native tokens, changing the total issuance. icon: material-creation-outline categories: Appchain --- # Using Sudo to Mint Native Tokens ## Introduction {: #introduction } [Sudo](https://paritytech.github.io/polkadot-sdk/master/pallet_sudo/index.html){target=\_blank} is a module that enables privileged runtime calls to be dispatched when called from the Sudo account. Sudo is sometimes colloquially referred to as a superuser or god-like account. This enables you to perform privileged actions in the course of managing your network, such as minting new native tokens. In this guide, you'll learn how to use Sudo to properly mint new native tokens. This comprehensive guide shows how to check the balance of an existing account prior to assigning it a new balance with Sudo access. ## Checking Prerequisites {: #checking-prerequisites } For the examples in this guide, you will need to have the following: - A Tanssi-powered network (Quick Trial or Dedicated) - Your network's Sudo account connected to your network's Polkadot.js Apps. You can refer to the [Managing Sudo guide](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank} for instructions on injecting your Sudo account into Polkadot.js Apps If you're unsure what your Tanssi network's Sudo account is, you can find it in your [Tanssi Dashboard](https://apps.tanssi.network){target=\_blank} underneath the **Properties** section. ![Locating your Sudo address on apps.tanssi.network](/images/builders/manage/locate-sudo-account.webp) !!! warning It's critical to protect your Sudo account key with the utmost security precautions, as it grants privileged access to your Tanssi network. ## Minting Tokens {: #minting-tokens } As you know, the Sudo account has the ability to perform privileged functions, including minting additional tokens. When setting up your network on the [Tanssi dApp](https://apps.tanssi.network){target=\_blank}, you can specify genesis account balances. In other words, you have the ability to endow accounts with initial balances upon launching your Tanssi network. However, you can also mint new tokens after launch with the help of the Sudo account. !!! note This tutorial demonstrates assigning arbitrary token balances on a TestNet network that has no value. You should carefully consider the ramifications of creating additional tokens on your own Tanssi-powered network. ### Checking Existing Account Balance {: #checking-existing-account-balance } The next section will demonstrate how to assign arbitrary token balances to accounts using the Sudo account. This process will overwrite the specified account's existing balance, so verifying the account is empty is a good practice before continuing. To check an account's balance, take the following steps: 1. Navigate to the **Developer** tab of [Polkadot.js Apps](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank} and click on **Chain State** 2. Select the **system** pallet to query 3. Select **account** 4. Paste in the account address or select it from the dropdown 5. Press **+** icon 6. You'll see the balance information returned at the bottom, including free, reserved, and frozen balances ![Check balances on Polkadot.js Apps](/images/builders/manage/developer-portal/minting/minting-2.webp) ### Assigning Balances with Sudo {: #assigning-balances-with-sudo } To assign an account balance to an account, make sure to have your Sudo account accessible in [Polkadot.js Apps](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank}. Then, take the following steps: 1. Navigate to the **Developer** Tab of Polkadot.js Apps for your Tanssi network 2. Click on **Sudo**. If you do not see **Sudo** in this menu, then you have not associated the Sudo account with Polkadot.js Apps. Make sure that your Sudo account is injected by your wallet and connected to Polkadot.js Apps 3. Select the **balances** pallet 4. Select the **forceSetBalance** method 5. Paste in the account address to endow with tokens or select it from the dropdown 6. Enter the amount of tokens to endow the account with. In this example, we specify `9000000000000000000` for nine native tokens. Remember that Tanssi-powered EVM networks have 18 decimals, while Substrate or custom networks configure the decimals when launching the chain. If you're unsure how many decimals your network has, navigate to the **Settings** tab and click on **Metadata** 7. Press **Submit Sudo** and confirm the transaction in your wallet ![Force assign balances on Polkadot.js Apps](/images/builders/manage/developer-portal/minting/minting-3.webp) And that's it! The [Developer Portal](/builders/manage/developer-portal/) section has plenty more guides on how to manage your Tanssi network.
The information presented herein has been provided by third parties and is made available solely for general information purposes. Tanssi does not endorse any project listed and described on the Tanssi Doc Website (https://docs.tanssi.network/). Tanssi Foundation does not warrant the accuracy, completeness or usefulness of this information. Any reliance you place on such information is strictly at your own risk. Tanssi Foundation disclaims all liability and responsibility arising from any reliance placed on this information by you or by anyone who may be informed of any of its contents. All statements and/or opinions expressed in these materials are solely the responsibility of the person or entity providing those materials and do not necessarily represent the opinion of Tanssi Foundation. The information should not be construed as professional or financial advice of any kind. Advice from a suitably qualified professional should always be sought in relation to any particular matter or circumstance. The information herein may link to or integrate with other websites operated or content provided by third parties, and such other websites may link to this website. Tanssi Foundation has no control over any such other websites or their content and will have no liability arising out of or related to such websites or their content. The existence of any such link does not constitute an endorsement of such websites, the content of the websites, or the operators of the websites. These links are being provided to you only as a convenience and you release and hold Tanssi Foundation harmless from any and all liability arising from your use of this information or the information provided by any third-party website or service.
--- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/manage/developer-portal/pause-transactions/ --- BEGIN CONTENT --- --- title: Pausing Transactions description: Learn how to use Sudo to temporarily pause hand-picked transactions, preventing their execution while allowing all other transactions to proceed as usual. icon: octicons-stopwatch-24 categories: Appchain --- # Pausing Transactions ## Introduction {: #introduction } The [Transaction Pause module](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/tx-pause/src/lib.rs){target=\_blank} is one of the [built-in modules](/learn/framework/modules/#built-in-modules){target=\_blank} included in the Polkadot SDK, and it is available in any Tanssi-powered network based on the [official templates](/builders/build/templates/overview/){target=\_blank} version [400](https://github.com/moondance-labs/tanssi/releases/tag/runtime-400-templates){target=\_blank} or higher. This module allows a network governor to temporarily avoid executing a set of hand-picked transactions while the rest of the transactions carry on as usual. This feature is helpful in several scenarios, such as disabling functionality in which a security threat has been discovered, enabling seasonal functionality only when needed, and enabling a set of transactions exactly on a launch date. In an emergency scenario, when a critical exploit is discovered, this module allows the network to isolate and stop only the affected functionality, effectively minimizing the overall impact. !!! warning At the time of this writing, this module hasn't yet been audited; therefore, it is not recommended for production use. ## Checking Prerequisites {: #checking-prerequisites } For the examples in this guide, you will need to have the following: - A Tanssi-powered network (Quick Trial or Dedicated) featuring the Transaction Pause module. Any new network deployment based on one of the templates will do; otherwise, make sure to [include the module](/builders/build/customize/adding-built-in-module/){target=\_blank} in your custom-made network runtime - Your network's Sudo account connected to your network's Polkadot.js Apps. You can refer to the [Managing Sudo guide](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank} for instructions on injecting your Sudo account into Polkadot.js Apps If you're unsure what your Tanssi network's Sudo account is, you can find it in your [Tanssi Dashboard](https://apps.tanssi.network){target=\_blank} underneath the **Properties** section. ![Locating your Sudo address on apps.tanssi.network](/images/builders/manage/locate-sudo-account.webp) !!! warning It's critical to protect your Sudo account key with the utmost security precautions, as it grants privileged access to your Tanssi network. ## Module and Transaction Names {: #modules-transaction-names } The [Transaction Pause module](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/tx-pause/src/lib.rs){target=\_blank} works by filtering the execution of specific transactions contained in the modules included in the network runtime. To do so, it keeps an internal list of the banned transactions identified by module and transaction name. This list is case-sensitive and works only when there is an exact match between one item in the paused transactions list and the transaction being processed. Therefore, using the exact names of the modules and the transactions is crucial. To find out the names of the modules available in your runtime, you need to read the `construct_runtime!()` section in the `lib.rs` file of your network runtime in your project repository. If your network is based on one of the official templates, you'll find the file in the [Tanssi repository](https://github.com/moondance-labs/tanssi){target=\_blank}: - For networks based on the EVM template: [the lib.rs file](https://github.com/moondance-labs/tanssi/blob/master/chains/container-chains/runtime-templates/frontier/src/lib.rs){target=\_blank} - For networks based on the Substrate template: [the lib.rs file](https://github.com/moondance-labs/tanssi/blob/master/chains/container-chains/runtime-templates/simple/src/lib.rs){target=\_blank} The following snippet is an example of how the `construct_runtime!()` section looks like. The module names are those located to the left of the colon. ```rust construct_runtime!( pub enum Runtime { ... Migrations: pallet_migrations = 7, MaintenanceMode: pallet_maintenance_mode = 8, TxPause: pallet_tx_pause = 9, Balances: pallet_balances = 10, Multisig: pallet_multisig = 16, ... } ``` To identify the transaction names included in a module, you need to refer to its source code. Modules built in [Substrate](/learn/framework/overview/#substrate-framework){target=\_blank} identify their transactions using a macro `#[pallet::call_index(INDEX)]`, where `INDEX` is a number. In the case of a [built-in module](/builders/build/customize/adding-built-in-module/){target=\_blank}, the code is located within the [FRAME folder](https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame){target=\_blank} of the Polkadot-SDK repository. For example, if you want to know about the transaction names in the `Balances` module, refer to its [lib.rs](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/balances/src/lib.rs){target=\_blank} file and look for the function names below the `#[pallet::call_index(INDEX)]` macros. The following snippet is the transaction `transfer_allow_death` of the module `Balances`, which is the one used as an example in this guide: ```rust #[pallet::call_index(0)] pub fn transfer_allow_death( origin: OriginFor, dest: AccountIdLookupOf, #[pallet::compact] value: T::Balance, ) -> DispatchResult { // Code Ok(()) } ``` ### Some Frequently Used Modules and Transactions {: #frequently-used-modules-transactions } When using any of the built-in Substrate modules, the name with which it's referenced within the runtime is entirely up to the developer, but the transaction names aren't customizable. Here is a list of some of the most commonly used modules with the most commonly used transactions they contain. Those are the transaction names to be used in this Transaction Pause module. ???+ function "[**pallet-ethereum**](https://github.com/polkadot-evm/frontier/blob/master/frame/ethereum/src/lib.rs){target=\_blank} — This module, along with the EVM module, provides full Ethereum compatibility to the network" | Transaction Name | Description | |:----------------:|:-------------------------:| | `transact` | Executes an Ethereum call | ??? function "[**pallet_balances**](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/balances/src/lib.rs){target=\_blank} — This module provides functionality for handling accounts and balances for the network native currency" | Transaction Name | Description | |:----------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:| | `transfer_allow_death` | Executes a balance transfer, deleting the sender's account when its final balance goes below the minimal requirement for existence | | `transfer_keep_alive` | Executes a balance transfer, keeping the sender's account alive even when its final balance goes below the minimal requirement for existence | | `transfer_all` | Transfer all non-locked balances to a destination | | `burn` | Burns balance from the origin's account, reducing the total issuance | ??? function "[**pallet_assets**](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/assets/src/lib.rs){target=\_blank} — This module provides functionality for handling fungible tokens" | Transaction Name | Description | |:---------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:| | `create` | Issues a new class of fungible assets | | `start_destroy` | Starts the process of destroying a fungible asset class | | `destroy_accounts` | Destroys all accounts associated with a given asset for which the destroy process was started | | `destroy_approvals` | Destroys all approvals associated with a given asset for which the destroy process was started | | `finish_destroy` | Completes the destroy process of a given asset for which the destroy process was started | | `mint` | Mints assets | | `burn` | Burns assets | | `transfer` | Executes an asset transfer deleting the sender's account when its final balance goes below the minimal requirement for existence | | `transfer_keep_alive` | Executes an asset transfer keeping the sender's account alive even when its final balance goes below the minimal requirement for existence | | `freeze` | Disallows transfers of an asset from a specific account | | `thaw` | Allows again transfers of an asset from a specific account | | `freeze_asset` | Disallows transfers of an asset | | `thaw_asset` | Allows again transfers of an asset | | `set_metadata` | Sets the metadata for an asset | | `clear_metadata` | Clears the metadata for an asset | ??? function "[**pallet_nfts**](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/nfts/src/lib.rs){target=\_blank} — This module provides functions for handling non-fungible tokens" | Transaction Name | Description | |:---------------------------:|:----------------------------------------------------------:| | `create` | Issues a new collection of non-fungible items | | `destroy` | Destroys a collection of non-fungible items | | `mint` | Mints an item in an NFT collection | | `burn` | Destroys an item from an NFT collection | | `transfer` | Transfers an NFT | | `lock_item_transfer` | Disallow the transfer of an item | | `unlock_item_transfer` | Allows again the transfer of a locked item | | `set_attribute` | Sets an attribute for an NFT collection or an item | | `clear_attribute` | Clears an attribute for an NFT collection or an item | | `set_metadata` | Sets the metadata for an item | | `clear_metadata` | Clears the metadata for an item | | `set_collection_metadata` | Sets the metadata for a collection of non-fungible items | | `clear_collection_metadata` | Clears the metadata for a collection of non-fungible items | | `set_price` | Sets the price for an item | | `buy_item` | Buy an item, provided that it's up for sale | ??? function "[**pallet_multisig**](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/multisig/src/lib.rs){target=\_blank} — This module provides functions for dealing with multi-signature schemas" | Transaction Name | Description | |:----------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------:| | `as_multi_threshold_1` | Registers a multi-signature call with a single approval | | `as_multi` | Registers a multi-signature call to be made from a composite account if approved by the specified minimum threshold of the other signatories | | `approve_as_multi` | Registers approval for a multi-signature call and dispatches the call when the threshold of signatories is reached | | `cancel_as_multi` | Cancels a pre-existing, ongoing multi-signature transaction | ## Pausing Transactions {: #pausing-transactions } As you know, the Sudo account [can perform privileged actions](/builders/manage/developer-portal/sudo/){target=\_blank}, such as network upgrades, minting new tokens, and, in this case, pausing and unpausing transactions. To pause a transaction, navigate to the **Developer** tab of Polkadot.js Apps for your Tanssi-powered network and click on **Sudo**. If you do not see **Sudo** in this menu, you have not associated the Sudo account with Polkadot.js Apps. Make sure that your [Sudo account is injected by your wallet and connected to Polkadot.js Apps](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank}. Then, take the following steps: 1. Select the **txPause** module 2. Select the **pause** method 3. Insert the **module** name that contains the transaction that will be paused 4. Insert the **transaction** name that will be paused 5. Press **Submit Sudo** and confirm the transaction in the resulting pop-up In this example, the transaction paused is `transfer_allow_death` from the `Balances` module: ![Pause transaction](/images/builders/manage/developer-portal/pause-transactions/pause-transactions-2.webp) To verify that the transaction has been effectively paused, try executing it. You should get an error. ![Check that the transaction is paused](/images/builders/manage/developer-portal/pause-transactions/pause-transactions-3.webp) !!! warning The `pause` transaction doesn't verify the module or transaction names and is case-sensitive, so any misspelling will go unnoticed, and the transaction will execute successfully. You should always verify that the transaction has been effectively paused. ## Unpausing Transactions {: #unpausing-transactions } To unpause a transaction and return it to normal operation, navigate to the **Developer** tab of Polkadot.js Apps for your Tanssi-powered network and click on **Sudo**. If you do not see **Sudo** in this menu, you have not associated the Sudo account with Polkadot.js Apps. Make sure that your [Sudo account is injected by your wallet and connected to Polkadot.js Apps](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank}. Then, take the following steps: 1. Select the **txPause** module 2. Select the **unpause** method 3. Insert the **module** name that contains the transaction that will be unpaused 4. Insert the **transaction** name that will be unpaused 5. Press **Submit Sudo** and confirm the transaction in the resulting pop-up In this example, the transaction to unpause is `transfer_allow_death` from the `Balances` module: ![Unpause transaction](/images/builders/manage/developer-portal/pause-transactions/pause-transactions-4.webp) The `unpause` transaction executes successfully only if the module and transaction parameters have been previously paused; otherwise, it fails. After the successful unpausing, the transaction can be called and executed again. And that's it! The [Developer Portal](/builders/manage/developer-portal/) section has plenty more guides on how to manage your Tanssi network.
The information presented herein has been provided by third parties and is made available solely for general information purposes. Tanssi does not endorse any project listed and described on the Tanssi Doc Website (https://docs.tanssi.network/). Tanssi Foundation does not warrant the accuracy, completeness or usefulness of this information. Any reliance you place on such information is strictly at your own risk. Tanssi Foundation disclaims all liability and responsibility arising from any reliance placed on this information by you or by anyone who may be informed of any of its contents. All statements and/or opinions expressed in these materials are solely the responsibility of the person or entity providing those materials and do not necessarily represent the opinion of Tanssi Foundation. The information should not be construed as professional or financial advice of any kind. Advice from a suitably qualified professional should always be sought in relation to any particular matter or circumstance. The information herein may link to or integrate with other websites operated or content provided by third parties, and such other websites may link to this website. Tanssi Foundation has no control over any such other websites or their content and will have no liability arising out of or related to such websites or their content. The existence of any such link does not constitute an endorsement of such websites, the content of the websites, or the operators of the websites. These links are being provided to you only as a convenience and you release and hold Tanssi Foundation harmless from any and all liability arising from your use of this information or the information provided by any third-party website or service.
--- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/manage/developer-portal/smart-contracts-creation-filter/ --- BEGIN CONTENT --- --- title: Smart EVM - Whitelist Contract Deployments description: Learn how to use Sudo to whitelist smart contract deployers for your Smart EVM Tanssi-powered network, increasing overall security. icon: octicons-file-binary-24 categories: Appchain, EVM-Template --- # Smart EVM - Whitelist Contract Deployments ## Introduction {: #introduction } EVM-compatible Tanssi-powered networks benefit from a unique feature: the network governor can define which accounts are authorized to deploy smart contracts, forbidding the action for any other non-whitelisted account. This feature brings several key benefits that might be a great fit for different use cases or contexts. Some of those benefits are: - **Enhanced Security** - by restricting deployment to trusted accounts, the risk of deploying malicious or vulnerable smart contracts is reduced - **Quality Assurance** - known and vetted accounts can be required to follow specific coding standards and undergo thorough testing before deployment - **Regulatory Compliance** - uses cases that are highly regulated can limit deployment to ensure that smart contracts meet legal and compliance requirements - **Spam and Abuse Prevention** - prevent bad actors from deploying large numbers of unnecessary or harmful contracts In this guide, you'll learn how to use the Sudo account to manage the whitelisted accounts that can deploy smart contracts on your network. ## Checking Prerequisites {: #checking-prerequisites } For the examples in this guide, you will need to have the following: - An EVM-compatible Tanssi-powered network (Quick Trial or Dedicated) running [runtime 700](https://github.com/moondance-labs/tanssi/releases/tag/runtime-700){target=\_blank} or above. Any new network deployment based on the [EVM template](/builders/build/templates/evm/){target=\_blank} will do - Your network's Sudo account connected to your network's Polkadot.js Apps. You can refer to the [Managing Sudo guide](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank} for instructions on injecting your Sudo account into Polkadot.js Apps If you're unsure what your Tanssi network's Sudo account is, you can find it in your [Tanssi Dashboard](https://apps.tanssi.network){target=\_blank} underneath the **Properties** section. ![Locating your Sudo address on apps.tanssi.network](/images/builders/manage/locate-sudo-account.webp) !!! warning It's critical to protect your Sudo account key with the utmost security precautions, as it grants privileged access to your Tanssi network. ## Getting Started {: #getting-started } To follow the next sections of this guide, head to Polkadot.js Apps for your Tanssi network. The Polkadot.js Apps link for your Tanssi network can be found in your [Tanssi Dashboard](https://apps.tanssi.network){target=\_blank} underneath the **Tooling** section. ![Locating your Polkadot.js Apps Link on apps.tanssi.network](/images/builders/manage/developer-portal/smart-contracts-creation-filter/smart-contracts-creation-filter-1.webp) Once in Polkadot.js Apps, navigate to the **Developer** tab and click on **Sudo**. !!! note If you do not see **Sudo** in this menu, then you have not associated the Sudo account with Polkadot.js Apps. Make sure that your [Sudo account is injected by your wallet and connected to Polkadot.js Apps](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank}. ## Whitelisting Accounts {: #whitelist-accounts } To define the accounts that will have authorization to deploy smart contracts, [get your Polkadot.js Apps started](#getting-started) and then take the following steps: 1. Select the **parameters** pallet. **setParameter** will be automatically selected in the functions selector and **ContractDeployFilter** in the **keyValue** parameter 2. Two options will be available in the **ContractDeployFilter** selector: **AllowedAddressesToCreate** and **AllowedAddressesToCreateInner**. Select the **AllowedAddressesToCreate** option if you want to whitelist the accounts for smart contract deployments and the latter to whitelist the accounts for indirect (via a smart contract call) smart contract deployments 3. Toggle the **Include option** switch 4. Select the **Whitelisted** option 5. Insert the whitelisted account 6. If you need to insert more than one account, click on **Add item** 7. Press **Submit Sudo** and confirm the transaction in your wallet ![Whitelisting Accounts](/images/builders/manage/developer-portal/smart-contracts-creation-filter/smart-contracts-creation-filter-2.webp) These same steps can be repeated at any moment to remove an account from the whitelist or to add new ones. ## Restoring Permissions to Deploy Smart Contracts {: #restoring-permission} If you previously authorized some accounts to deploy smart contracts and want to allow any account to deploy smart contracts (as long as they can cover regular transaction fees), then [get your Polkadot.js Apps started](#getting-started) and take the following steps: 1. Select the **parameters** pallet. **setParameter** will be automatically selected in the functions selector and **ContractDeployFilter** in the **keyValue** parameter 2. Two options will be available in the **ContractDeployFilter** selector: **AllowedAddressesToCreate** and **AllowedAddressesToCreateInner**. Select the **AllowedAddressesToCreate** option if you want to clear the whitelist for smart contract deployments and the latter to clear the whitelist for indirect (via a smart contract call) smart contract deployments 3. Toggle the **Include option** switch 4. Select the **All** option 5. Press **Submit Sudo** and confirm the transaction in your wallet ![Clearing the Whitelisted Accounts](/images/builders/manage/developer-portal/smart-contracts-creation-filter/smart-contracts-creation-filter-3.webp) ## Query the Whitelisted Accounts {: #query-whitelisted-accounts } To get the current configuration containing the whitelisted accounts that can deploy smart contracts, go to Polkadot.js Apps (as explained in the [Getting Started](#getting-started) section), navigate to the **Developer** tab, click on **Chain state**, and take the following steps: 1. Select the **parameters** storage 2. Select the **parameters(ContainerChainTemplateFrontierRuntimeParametersKey)** option 3. Make sure that the **Include option** switch is on 4. Make sure that the **ContractDeployFilter** option is selected 5. Two options will be available in the **ContractDeployFilter** selector: **AllowedAddressesToCreate** and **AllowedAddressesToCreateInner**. Select the **AllowedAddressesToCreate** option if you want to query the whitelist for smart contract deployments and the latter to query the whitelist for indirect (via a smart contract call) smart contract deployments 6. Click the **+** button 7. The current configuration will be displayed ![Query the Whitelists](/images/builders/manage/developer-portal/smart-contracts-creation-filter/smart-contracts-creation-filter-4.webp) --- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/manage/developer-portal/sudo/ --- BEGIN CONTENT --- --- title: Managing the Sudo Account description: Learn how to manage the Sudo account of your network, including viewing and importing the Sudo key into Polkadot.js Apps and changing the current Sudo key. icon: octicons-key-24 categories: Appchain --- # Managing Your Network's Sudo Account ## Introduction {: #introduction } [Sudo](https://paritytech.github.io/polkadot-sdk/master/pallet_sudo/index.html){target=\_blank} is a module that enables privileged runtime calls to be dispatched when called from the Sudo account. Sudo is sometimes colloquially referred to as a superuser or god-like account. There can only be a single Sudo account at a time. However, the Sudo keys can be rotated to give Sudo privileges to a new account. All Tanssi-powered networks come with the Sudo pallet by default, and you're required to designate an account as the Sudo address when launching your network. This enables you to perform privileged actions to manage your chain, such as upgrading your runtime or minting new native tokens. While the Sudo pallet is required to launch your Tanssi network on the TestNet, you can decommission the Sudo pallet and transition to decentralized governance after the MainNet launch. In the following guide, you'll learn how to view the current Sudo account for your network and how to change it, alongside importing it into Polkadot.js Apps. There are similar guides in this section explaining how to use the Sudo account to perform privileged actions, such as [upgrading your runtime](/builders/manage/developer-portal/upgrade/){target=\_blank} and [minting native tokens](/builders/manage/developer-portal/minting/){target=\_blank}. ## Checking Prerequisites {: #checking-prerequisites } For the examples in this guide, you will need to have the following: - A Tanssi-powered network (Quick Trial or Dedicated) - Your network's Sudo account connected to your network's Polkadot.js Apps If you're unsure what your Tanssi network's Sudo account is, you can find it in your [Tanssi Dashboard](https://apps.tanssi.network){target=\_blank} underneath the **Properties** section. ![Locating your Sudo address on apps.tanssi.network](/images/builders/manage/locate-sudo-account.webp) !!! warning It's critical to protect your Sudo account key with the utmost security precautions, as it grants privileged access to your Tanssi network. ### Configuring Polkadot.js Apps { : #configuring-polkadotjs-apps } After navigating to Polkadot.js Apps for your network, you'll need to add your Sudo account. Injecting your Sudo account into Polkadot.js Apps from a browser extension is considered safer than storing accounts directly in the browser. However, you can still import your Sudo account directly into the browser's cache. This method does not require the use of any extensions. To import an account into Polkadot.js in this manner, take the following steps: 1. Click on **Settings** 2. Under **in-browser account creation** select **Allow local in-browser account creation** 3. Press **Save** ![Allowing creation of in-browser storage](/images/builders/manage/developer-portal/sudo/sudo-2.webp) Then, head back to the accounts tab and press **Account**. You'll then be able to replace the pre-generated private key with that of your Sudo account. ![Adding account on Polkadot.js Apps](/images/builders/manage/developer-portal/sudo/sudo-3.webp) !!! warning In-browser key storage is not suitable for production environments. This example is provided for demonstration purposes only in a TestNet environment. ## Changing the Sudo Account {: #changing-the-sudo-account } Changing your Tanssi-powered network's Sudo account is a straightforward process. Also known as rotating your Sudo keys, this process will remove Sudo access from the existing Sudo account and grant it to the new account. There can only be one Sudo account at any time. However, you are free to change the Sudo account as often as you would like. Prior to getting started, make sure that you have your existing Sudo account accessible in [Polkadot.js Apps](#configuring-polkadotjs-apps). Then, take the following steps: 1. Navigate to the **Developer** Tab of Polkadot.js Apps for your network 2. Click on **Sudo**. If you do not see **Sudo** in this menu, then you have not associated the Sudo account with Polkadot.js Apps. Make sure that your Sudo account is injected by your wallet and connected to Polkadot.js Apps 3. Select the **Set Sudo key** heading 4. Select the new account you'll transfer Sudo privileges to 5. Press **Reassign** and confirm the transaction in your wallet ![Change Sudo account on Polkadot.js Apps](/images/builders/manage/developer-portal/sudo/sudo-4.webp) !!! note Ensure that you have access to the new Sudo account. Once Sudo is transferred, it cannot be undone without access to the current Sudo key. And that's it! The [Developer Portal](/builders/manage/developer-portal/) section has plenty more guides on how to manage your Tanssi network.
The information presented herein has been provided by third parties and is made available solely for general information purposes. Tanssi does not endorse any project listed and described on the Tanssi Doc Website (https://docs.tanssi.network/). Tanssi Foundation does not warrant the accuracy, completeness or usefulness of this information. Any reliance you place on such information is strictly at your own risk. Tanssi Foundation disclaims all liability and responsibility arising from any reliance placed on this information by you or by anyone who may be informed of any of its contents. All statements and/or opinions expressed in these materials are solely the responsibility of the person or entity providing those materials and do not necessarily represent the opinion of Tanssi Foundation. The information should not be construed as professional or financial advice of any kind. Advice from a suitably qualified professional should always be sought in relation to any particular matter or circumstance. The information herein may link to or integrate with other websites operated or content provided by third parties, and such other websites may link to this website. Tanssi Foundation has no control over any such other websites or their content and will have no liability arising out of or related to such websites or their content. The existence of any such link does not constitute an endorsement of such websites, the content of the websites, or the operators of the websites. These links are being provided to you only as a convenience and you release and hold Tanssi Foundation harmless from any and all liability arising from your use of this information or the information provided by any third-party website or service.
--- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/manage/developer-portal/upgrade/ --- BEGIN CONTENT --- --- title: Upgrade Your Appchain's Runtime description: Learn how to use the Sudo account to perform the privileged action of upgrading the runtime of your Tanssi-powered appchain through the developer portal. icon: octicons-arrow-up-24 categories: Appchain --- # Upgrading Your Appchain Runtime with Sudo ## Introduction {: #introduction } [Sudo](https://paritytech.github.io/polkadot-sdk/master/pallet_sudo/index.html){target=\_blank} is a module that enables privileged runtime calls to be dispatched when called from the Sudo account. Sudo is sometimes colloquially referred to as a superuser or god-like account. This enables you to perform privileged actions in the course of managing your appchain, such as upgrading your Tanssi-powered appchain's runtime. In this guide, you'll learn how to use Sudo to upgrade your appchain's runtime. With Sudo access, upgrading your chain is a quick and easy process. Note that appchain teams in production will have the option to phase out Sudo access and rely on governance to process runtime upgrades. ## Checking Prerequisites {: #checking-prerequisites } For the example in this guide, you will need to have the following: - A Tanssi-powered appchain (Quick Trial, Dedicated, or MainNet). - Your appchain's Sudo account connected to your appchain's developer portal. You can refer to the [Managing Sudo guide](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank} for instructions on injecting your Sudo account into the developer portal. - The new [Wasm runtime](/learn/framework/architecture/#runtime){target=\_blank} binary file, built with a higher version than the current one. If you're unsure what your Tanssi network's Sudo account is, you can find it in your [Tanssi Dashboard](https://apps.tanssi.network){target=\_blank} underneath the **Properties** section. ![Locating your Sudo address on apps.tanssi.network](/images/builders/manage/locate-sudo-account.webp) !!! warning It's critical to protect your Sudo account key with the utmost security precautions, as it grants privileged access to your Tanssi network. ## Obtaining the Wasm Runtime {: #obtaining-wasm-runtime } If your chain is based on one of the official templates, you can download the official Wasm runtime binary file from the table below. The official releases are published in the [releases section](https://github.com/moondance-labs/tanssi/releases){target\_blank} in the Tanssi repository. | Version | EVM Template | Substrate Template | |:----------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| | [1400](https://github.com/moondance-labs/tanssi/releases/tag/runtime-1400-templates){target=\_blank} | [Download EVM V1400 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-1400-templates/frontier-template-runtime-1400.wasm){target=\_blank} | [Download Substrate V1400 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-1400-templates/simple-template-runtime-1400.wasm){target=\_blank} | | [1300](https://github.com/moondance-labs/tanssi/releases/tag/runtime-1300-templates){target=\_blank} | [Download EVM V1300 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-1300-templates/frontier-template-runtime-1300.wasm){target=\_blank} | [Download Substrate V1300 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-1300-templates/simple-template-runtime-1300.wasm){target=\_blank} | | [1201](https://github.com/moondance-labs/tanssi/releases/tag/runtime-1201-templates){target=\_blank} | [Download EVM V1201 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-1201-templates/frontier-template-runtime-1201.wasm){target=\_blank} | [Download Substrate V1201 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-1201-templates/simple-template-runtime-1201.wasm){target=\_blank} | | [1100](https://github.com/moondance-labs/tanssi/releases/tag/runtime-1100-templates){target=\_blank} | [Download EVM V1100 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-1100-templates/frontier-template-runtime-1100.wasm){target=\_blank} | [Download Substrate V1100 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-1100-templates/simple-template-runtime-1100.wasm){target=\_blank} | | [1000](https://github.com/moondance-labs/tanssi/releases/tag/runtime-1000-templates){target=\_blank} | [Download EVM V1000 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-1000-templates/frontier-template-runtime-1000.wasm){target=\_blank} | [Download Substrate V1000 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-1000-templates/simple-template-runtime-1000.wasm){target=\_blank} | | [900](https://github.com/moondance-labs/tanssi/releases/tag/runtime-900-templates){target=\_blank} | [Download EVM V900 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-900-templates/frontier-template-runtime-900.wasm){target=\_blank} | [Download Substrate V900 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-900-templates/simple-template-runtime-900.wasm){target=\_blank} | | [800](https://github.com/moondance-labs/tanssi/releases/tag/runtime-800){target=\_blank} | [Download EVM V800 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-800/frontier-template-runtime-800.wasm){target=\_blank} | [Download Substrate V800 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-800/simple-template-runtime-800.wasm){target=\_blank} | | [700](https://github.com/moondance-labs/tanssi/releases/tag/runtime-700){target=\_blank} | [Download EVM V700 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-700/frontier-template-runtime-700.wasm){target=\_blank} | [Download Substrate V700 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-700/simple-template-runtime-700.wasm){target=\_blank} | | [600](https://github.com/moondance-labs/tanssi/releases/tag/runtime-600){target=\_blank} | [Download EVM V600 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-600/frontier-template-runtime-600.wasm){target=\_blank} | [Download Substrate V600 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-600/simple-template-runtime-600.wasm){target=\_blank} | | [500](https://github.com/moondance-labs/tanssi/releases/tag/runtime-500){target=\_blank} | [Download EVM V500 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-500/frontier-template-runtime-500.wasm){target=\_blank} | [Download Substrate V500 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-500/simple-template-runtime-500.wasm){target=\_blank} | | [400](https://github.com/moondance-labs/tanssi/releases/tag/runtime-400-templates){target=\_blank} | [Download EVM V400 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-400-templates/frontier-template-runtime-400.wasm){target=\_blank} | [Download Substrate V400 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-400-templates/simple-template-runtime-400.wasm){target=\_blank} | | [300](https://github.com/moondance-labs/tanssi/releases/tag/templates-runtime-300){target=\_blank} | [Download EVM V300 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/templates-runtime-300/frontier-template-runtime-300.wasm){target=\_blank} | [Download Substrate V300 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/templates-runtime-300/simple-template-runtime-300.wasm){target=\_blank} | | [200](https://github.com/moondance-labs/tanssi/releases/tag/runtime-200){target=\_blank} | [Download EVM V200 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-200/frontier-template-runtime-200.wasm){target=\_blank} | [Download Substrate V200 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-200/simple-template-runtime-200.wasm){target=\_blank} | | [101](https://github.com/moondance-labs/tanssi/releases/tag/runtime-101-templates){target=\_blank} | [Download EVM V101 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-101-templates/frontier-template-runtime-101.wasm){target=\_blank} | [Download Substrate V101 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-101-templates/simple-template-runtime-101.wasm){target=\_blank} | | [100](https://github.com/moondance-labs/tanssi/releases/tag/runtime-100-templates){target=\_blank} | [Download EVM V100 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-100-templates/frontier-template-runtime-100.wasm){target=\_blank} | [Download Substrate V100 Wasm file](https://github.com/moondance-labs/tanssi/releases/download/runtime-100-templates/simple-template-runtime-100.wasm){target=\_blank} | You should always upgrade the runtime following the releases in an orderly fashion, applying one release after another without skipping any of them. To do so, you need to know your appchain's current runtime version, which you'll find in your [Tanssi Dashboard](https://apps.tanssi.network){target=\_blank} underneath the **Properties** section. For example, if your runtime version is `1000`, you should upgrade first to `1100`, then `1201`, then `1300`, and so on until the latest available version. !!! warning Applying the upgrades in order ensures that the changes (migrations) in the internal data structures are applied, preserving data consistency. Doing otherwise might **stall** your appchain. !!! note If you are compiling the runtime manually, make sure to use the Wasm version `compact` and `compressed`, which is optimized and lighter. ## Upgrading Your Runtime {: #upgrading-your-runtime } To get started, head to the developer portal for your Tanssi appchain, which can be found in your [Tanssi Dashboard](https://apps.tanssi.network){target=\_blank} underneath the **Tooling** section. ![Locating your Developer Portal Link on apps.tanssi.network](/images/builders/manage/developer-portal/upgrade/upgrade-1.webp) !!! warning If your appchain was deployed using an official template and the intended upgrade is a custom runtime, make sure to have changed the default spec name (*frontier-template* or *container-chain-template*) to a different one before building the Wasm file. You'll also need to execute the `setCodeWithoutChecks` extrinsic instead of `setCode`. With your [Wasm runtime](/learn/framework/architecture/#runtime){target=\_blank} ready to upload and your [Sudo account accessible in the developer portal](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank}, take the following steps: 1. Navigate to the **Developer** tab of the developer portal for your Tanssi appchain. 2. Click on **Sudo**. If you do not see **Sudo** in this menu, then you have not associated the Sudo account with the developer portal. Make sure that your [Sudo account is injected by your wallet and connected to the developer portal](/builders/manage/developer-portal/sudo/#configuring-polkadotjs-apps){target=\_blank}. 3. Select the **system** pallet. 4. Select **setCode**. 5. Toggle the **fileUpload** switch to enable uploading your Wasm runtime file. 6. Upload your Wasm runtime. 7. Press **Submit Sudo** and confirm the transaction in your wallet. ![Upgrading your Runtime on the Developer Portal](/images/builders/manage/developer-portal/upgrade/upgrade-2.webp) You can verify that your runtime upgrade was successful by checking the runtime version in the upper left-hand corner. In this case, you can see that the Tanssi-powered appchain's runtime was successfully upgraded to version `400`. ![Check Runtime version on Polkadot.js Apps](/images/builders/manage/developer-portal/upgrade/upgrade-3.webp) And that's it! The [developer portal](/builders/manage/developer-portal/) section has plenty more guides on how to manage your Tanssi appchain.
The information presented herein has been provided by third parties and is made available solely for general information purposes. Tanssi does not endorse any project listed and described on the Tanssi Doc Website (https://docs.tanssi.network/). Tanssi Foundation does not warrant the accuracy, completeness or usefulness of this information. Any reliance you place on such information is strictly at your own risk. Tanssi Foundation disclaims all liability and responsibility arising from any reliance placed on this information by you or by anyone who may be informed of any of its contents. All statements and/or opinions expressed in these materials are solely the responsibility of the person or entity providing those materials and do not necessarily represent the opinion of Tanssi Foundation. The information should not be construed as professional or financial advice of any kind. Advice from a suitably qualified professional should always be sought in relation to any particular matter or circumstance. The information herein may link to or integrate with other websites operated or content provided by third parties, and such other websites may link to this website. Tanssi Foundation has no control over any such other websites or their content and will have no liability arising out of or related to such websites or their content. The existence of any such link does not constitute an endorsement of such websites, the content of the websites, or the operators of the websites. These links are being provided to you only as a convenience and you release and hold Tanssi Foundation harmless from any and all liability arising from your use of this information or the information provided by any third-party website or service.
--- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/tanssi-network/testnet/demo-evm-network/ --- BEGIN CONTENT --- --- title: Demo EVM Tanssi Network description: Test our demo EVM Tanssi network to discover the capabilities of a fully Ethereum-compatible network deployed through Tanssi in just a few minutes. icon: material-ethereum categories: Appchain, EVM-Template --- ## Introduction Explore the functionalities of a fully Ethereum-compatible network deployed through Tanssi by interacting with the demo EVM network on [Dancelight](/builders/tanssi-network/testnet/dancelight/){target=\_blank}. This quick reference page offers all the essentials you need to interact with this demo network. ## Faucet for TestNet Tokens {: #faucet } You can access {{ networks.dancelight.demo_evm_token_symbol }} tokens, the native currency of the EVM demo network, at the faucet on the [Tanssi dApp](https://apps.tanssi.network/demo){target=\_blank}. You can receive up to 100 {{ networks.dancelight.demo_evm_token_symbol }} tokens every 12 hours. To request tokens from the faucet, head to the [Tanssi dApp](https://apps.tanssi.network/demo){target=\_blank} and press **Add to MetaMask**. ![Add to MetaMask](/images/builders/tanssi-network/testnet/demo-evm-network/demo-1.webp) Then, take the following steps: 1. Press **Request Tokens** 2. Select the account you'd like to receive {{ networks.dancelight.demo_evm_token_symbol }} tokens and press **Next** 3. Press **Connect** ![Request tokens](/images/builders/tanssi-network/testnet/demo-evm-network/demo-2.webp) !!! note {{ networks.dancelight.demo_evm_token_symbol }} tokens have no value. Please don't spam the faucet with unnecessary requests. Your tokens will be disbursed shortly, and you can verify your {{ networks.dancelight.demo_evm_token_symbol }} token balance by looking up your address on the [explorer]({{ networks.dancelight.demo_evm_blockscout_url }}){target=\_blank}. ## Network Endpoints {: #network-endpoints } The demo EVM network HTTPS and WSS endpoints are as follows: === "HTTPS" ```text {{ networks.dancelight.demo_evm_rpc_url }} ``` === "WSS" ```text {{ networks.dancelight.demo_evm_rpc_wss_url }} ``` ## Block Explorers {: #block-explorers } For the demo EVM network, you can use any of the following explorers: - [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc={{ networks.dancelight.demo_evm_rpc_wss_url }}){target=\_blank} (Substrate API) - [Blockscout]({{ networks.dancelight.demo_evm_blockscout_url }}){target=\_blank} (Ethereum API) - [Expedition](https://evmexplorer.tanssi-chains.network/?rpcUrl={{ networks.dancelight.demo_evm_rpc_url }}){target=\_blank} (Ethereum API) ## Chain ID {: #chain-id } The demo EVM network has a [chain ID](https://chainlist.org/chain/{{ networks.dancelight.demo_evm_chain_id }}){target=\_blank} of: `{{ networks.dancelight.demo_evm_chain_id }}`, which is `{{ networks.dancelight.demo_evm_chain_hex_id }}` in hex. ## Quick Start {: #quick-start } You can interact with a Tanssi-powered EVM network using standard Ethereum libraries, like [Ethers.js](/builders/toolkit/ethereum-api/libraries/ethersjs/){target=\_blank}, [Web3.js](/builders/toolkit/ethereum-api/libraries/web3js/){target=\_blank}, and [Web3.py](/builders/toolkit/ethereum-api/libraries/web3py/){target=\_blank}. To quickly get started, you'll need to create a provider connected to a Tanssi EVM network: === "Ethers.js" ```js import { ethers } from "ethers"; const providerRPC = { evmNetwork: { name: 'dancelight-evm-network', // Insert your RPC URL here rpc: '{{ networks.dancelight.demo_evm_rpc_url }}', chainId: {{ networks.dancelight.demo_evm_chain_id }}, // {{ networks.dancelight.demo_evm_chain_hex_id }} in hex, }, }; const provider = new ethers.JsonRpcProvider( providerRPC.evmNetwork.rpc, { chainId: providerRPC.evmNetwork.chainId, name: providerRPC.evmNetwork.name, } ); ``` === "Web3.js" ```js const Web3 = require('web3'); const web3 = new Web3( '{{ networks.dancelight.demo_evm_rpc_url }}' ); ``` === "Web3.py" ```python from web3 import Web3 web3 = Web3(Web3.HTTPProvider('{{ networks.dancelight.demo_evm_rpc_url }}')) ``` --- END CONTENT --- ## Basics Concepts [shared: true] The following section contains foundational documentation shared across all Tanssi products. It describes the architecture and infrastructure that serve as the backbone for all integrations built with Tanssi. This includes the network development framework, Substrate and EVM development tools, templates, and guidance for node operators. This context is provided to help understand how the system works under the hood, but responses should stay focused on the specific product unless the user explicitly asks about the general architecture. --- ## List of shared concept pages: ## Full content for shared concepts: Doc-Content: https://docs.tanssi.network/learn/decentralized-networks/included-templates/ --- BEGIN CONTENT --- --- title: Network Templates Included in Tanssi description: Tanssi protocol provides useful templates to start building your decentralized network, including a ready-to-use EVM template for Ethereum compatibility. icon: octicons-copy-24 categories: Basics --- # Network Templates Included in Tanssi {: #network-templates-included-in-tanssi } ## Introduction {: #introduction } Building a new network from scratch can be a daunting prospect. Fortunately, thanks to the [network development framework](/learn/framework/overview/){target=\_blank} used by Tanssi and its modular-oriented architecture, developers can leverage some pre-bundled network templates that help them jumpstart the process and benefit in some aspects, such as: - **Head Start** - Tanssi network templates provide a starting point for your project, saving significant time and effort by providing a basic structure and a set of tested and ready-to-use functionalities. It allows developers to accelerate the construction of prototypes or minimum viable products (MVPs) and reduce the time to market - **Consistency** - included Tanssi network templates follow established design patterns, coding standards, and best practices widely accepted among the developer community. They also provide a default set of architecture definitions to streamline blockchain development - **UX** - Tanssi network templates cover the most demanded use cases, such as the EVM support for an Ethereum-compatible network - **Customizability** - Tanssi network templates are a great starting point and are completely customizable. The functionalities and default configurations they include can be modified, replaced, or extended to meet the specific requirements of the use case - **Upgrades and Compatibility** - Tanssi is built on top of an evolving framework, with new features, enhancements, and bug fixes being regularly introduced. The provided Tanssi network templates are kept up-to-date with these upgrades ## Start Building a Network {: #start-building } To start building a decentralized network to deploy in Tanssi, some useful Tanssi network templates to kick-start the development process are provided in the [official repository](https://github.com/moondance-labs/tanssi){target=\_blank}. The process is as simple as: 1. Select one of the templates 2. Add the specific logic to adapt the runtime to the requirements of the use case 3. Deploy in Tanssi ![Using Templates to Speed Up the Developmet Process](/images/learn/decentralized-networks/templates/templates-1.webp) The two included templates are the *baseline network template* and the *baseline EVM template*, which are presented in the following sections. ### Baseline Network Template {: #baseline-network-template } As presented in the [Overview](/learn/tanssi/overview/){target=\_blank} article, networks deployed through Tanssi are fully sovereign and customizable blockchains. As part of the Tanssi ecosystem, networks must include the essential components to implement the consensus mechanism and be able to interact and synchronize with the security provider of their choice (for example, [Symbiotic](https://symbiotic.fi/){target=\_blank} on Ethereum). The baseline Tanssi network template includes all the necessary functionality for the sequencers logic, p2p, database, and synchronization layers between the network and the security provider, allowing developers to focus solely on customizing their product. This template also includes Tanssi's [Author Noting](https://github.com/moondance-labs/tanssi/blob/master/pallets/author-noting/src/lib.rs){target=\_blank} module, which implements the logic for retrieving and validating the set of sequencers assigned to provide block production services to the network. It also includes logic that allows a sequencer to sign the block when the consensus mechanism determines that it is the sequencer's turn to produce the block (and thus be rewarded accordingly). The source code for this template is public and accessible on the [Tanssi GitHub repository](https://github.com/moondance-labs/tanssi/blob/master/chains/container-chains/runtime-templates/simple/src/lib.rs){target=\_blank}. ### Baseline EVM (Ethereum Virtual Machine) Template {: #baseline-evm-template } Extending the [baseline Tanssi network template](#baseline-network-template), this template provides not only Tanssi protocol support but also an EVM and full Ethereum compatibility. Leveraging a set [EVM-specific modules](https://github.com/polkadot-evm/frontier){target=\_blank}, this template includes an Ethereum compatibility layer for networks to allow running unmodified Ethereum dApps. Using this template, networks support the deployment and running of any existing smart contract written in Solidity or Vyper with no changes. By emulating Ethereum block production and exposing the expected RPC interface, developers can also continue using the same tools like [Metamask](https://metamask.io){target=\_blank}, [Hardhat](https://hardhat.org){target=\_blank}, [Remix](https://remix.ethereum.org){target=\_blank}, [Foundry](https://github.com/foundry-rs/foundry){target=\_blank}, and many more out of the box, with no extra adapters. With this EVM template, developers can deploy a [Moonbeam](https://moonbeam.network){target=\_blank}-like network in no time and add their custom logic and features specific to their use case. The source code for this template is public and accessible on the [Tanssi GitHub repository](https://github.com/moondance-labs/tanssi/blob/master/chains/container-chains/runtime-templates/frontier/src/lib.rs){target=\_blank}. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/learn/decentralized-networks/overview/ --- BEGIN CONTENT --- --- title: Network Overview description: Learn the high-level definitions of how a Tanssi network works, its architecture, and its block production as a service mechanism with deterministic finality. icon: octicons-home-24 categories: Basics --- # Tanssi Networks Overview {: #networks-tanssi-overview } ## Introduction {: #introduction } Networks deployed through Tanssi receive many [benefits](/learn/tanssi/overview/#what-tanssi-provides){target=\_blank}, like block production as a service, data retrievability as a service, and security through an [external security providers](/learn/tanssi/external-security-providers/){target=\_blank} such as [Symbiotic](https://symbiotic.fi/){target=\_blank} on Ethereum. Also, because Tanssi-powered networks are based on a [modular tech stack](/learn/framework/){target=\_blank}, they profit from unique advantages when customizations are required at a runtime level. This [modularity](/learn/framework/modules/){target=\_blank} allows developers to add functionality directly into the runtime or extend the capabilities of the EVM itself via precompiled contracts. For example, Tanssi provides a ready-to-use [template](/learn/decentralized-networks/included-templates#baseline-evm-template){target=\_blank} that includes [Frontier](https://github.com/polkadot-evm/frontier){target=\_blank} modules, enabling the effortless deployment of an EVM-compatible networks, similar to [Moonbeam](https://moonbeam.network){target=\_blank}. This section covers the fundamentals of a Tanssi network, its architecture, its core modules and functionalities, and the transaction fee mechanism. ## General Architecture {: #general-architecture} As previously discussed, networks deployed through Tanssi are customizable blockchains that, among other features, receive block production as a service and inherit security with deterministic block finality within seconds from an external security provider. Tanssi-powered networks are fully decentralized networks. The decentralized nature of the networks considerably increases their resilience and fault tolerance since they don't rely on a single authority or entity to ensure their liveness, security, and performance but on trustless, decentralized protocols. For example, they receive block production services from a decentralized and incentivized set of sequencers managed by Tanssi. The Tanssi protocol runs with an [external security provider](/learn/tanssi/external-security-providers/){target=\_blank}, which has a set of operators (also called validators) with assets at stake, validating the transactions from the Tanssi network itself and all of the networks deployed through Tanssi. This way, all Tanssi-powered networks inherit the economic security derived from the Tanssi protocol and, indirectly, from the operators, which verify every transaction from every network. Tanssi networks don't need to run their own operator set nor bootstrap liquidity to secure their protocol. Tanssi networks also benefit from a set of Data-Preservers, with full archive nodes, ensuring the data availability layer availability. These data-preservers are incentivized through Tanssi's data retrieval services and also provide the RPC infrastructure for apps and users interacting with Tanssi networks. ```mermaid flowchart TB networks["Tanssi Networks
(Decentralized Networks)"] subgraph tanssi["Tanssi Protocol"] direction TB sequencers["Decentralized Sequencers Set"] node["Full Archive Nodes with
RPC Services"] end security["External Security Provider
Operators"] networks<--Block Production-->tanssi networks<--Shared Security Model-->tanssi networks<--Data Availability
RPC endpoints-->tanssi tanssi<--Transactions
Validation and Finality-->security ``` ## Network Transaction Flow {: #network-transaction-flow } A transaction submitted to a Tanssi-powered network follows a complex yet seamless path from submission to block inclusion and finalization. The network infrastructure, Tanssi, and the chosen [security provider](/learn/tanssi/external-security-providers/){target=\_blank} work together at different levels to ensure the process happens as quickly as possible, usually taking around 30 seconds. Remember that a transaction in a Tanssi network reaches deterministic finality. Consequently, once the transaction is final, it becomes irreversible and unchangeable, and the state transition resulting from executing that transaction is final. For example, a user initiates a transaction when interacting via an application deployed to a Tanssi-powered network. The RPC provider will share the transaction, which sits in the chain's transaction pool, with all network participants. A sequencer assigned by Tanssi to that network will eventually pick up the transaction and include it in the next network block. Then, the sequencer will share with the security provider's operators: - The block itself with the state transitions - The storage components in the Tanssi network database that the block is modifying - The necessary hashes of the unaffected points in the Merkle tree of the storage These components constitute the proof of validity (PoV). Next, the PoV is verified by the security provider's operators. Note that the operators do not check that the Tanssi network storage is valid but that the state transitions that affect it are. A summary of that verification is then gossiped to other operators so they can verify it and include it in the next Tanssi block. Lastly, that Tanssi block with all the networks' verifications is finalized. The transaction flow process is summarized in the following diagram: ![Path of a Tanssi Network Block in Tanssi](/images/learn/decentralized-networks/overview/overview-1.webp) --- END CONTENT --- Doc-Content: https://docs.tanssi.network/learn/decentralized-networks/runtime-features/ --- BEGIN CONTENT --- --- title: Core Runtime Features description: Learn about the core features of a Tanssi network, the transactions types, how they are executed and included in a block, and the forkless runtime upgrades. icon: octicons-package-24 categories: Basics --- # Core Runtime Features {: #core-runtime-features } ## Introduction {: #introduction} Networks deployed through Tanssi have [many benefits](/learn/tanssi/overview/#what-tanssi-provides){target=\_blank} due to its unique [architecture](/learn/tanssi/overview/#tanssi-architecture){target=\_blank}. Nevertheless, Tanssi-powered networks are also unique due to the [framework](/learn/framework/){target=\_blank} (Substrate) they are built on top of, which provides some unique characteristics that developers can leverage to fine-tune specific behaviors in their runtime. This section covers some of these Tanssi network core runtime-specific features, including the different origins a transaction might have, the different types of transactions and how they are executed and included in a block, the special account known as _SUDO_, and the quite unique feature of Tanssi networks: the forkless runtime upgrades. ## Origins {: #origins} Generally speaking, all calls in a Tanssi network have an origin. But what is an origin? Developers from the EVM realm might be familiar with the concept of _msg.sender_ in EVM transactions. Origins are to Tanssi networks what _msg.sender_ is to an EVM transaction, but supercharged with many extra functionalities. An origin defines where the call is coming from. In contrast to Ethereum-compatible chains, there can be many origins in Tanssi networks. For example, the _msg.sender_ of an EVM transaction is known as a _signed origin_, which means that the call is a transaction that was signed by some on-chain account's private key. This allows the runtime to authenticate the source of the call and, for example, charge transaction fees to the associated account. However, origins can do much more than represent a private key/public key pair. Origins also have different privilege levels. For example, a _signed origin_ can send a transaction that is dispatched by the private key/public key pair but should not be able to authorize a runtime upgrade. Some of the most common types of origins are: - **Root** - a system-level origin with the highest privilege level. It can be thought of as a superuser of the chain, which can execute any call - **Signed** - as mentioned before, the origin of a transaction signed by an on-chain account's private key, which includes the account identifier (address) as the signer - **None** - a lack of origin. Used in specific actions that must be agreed upon at a runtime level. For example, you can program your runtime so that a transaction with _none_ origin can enact a pre-authorized runtime upgrade, which means that the transaction has no fee associated with it - **Custom** - developers can also create custom origins for specific use cases. For example, [Moonbeam's on-chain governance](https://docs.moonbeam.network/learn/features/governance){target=\_blank} has specific origins for each type of governance vote, called _tracks_. Consequently, each track can be configured to only execute calls with specific privilege levels. One track is _Root_, whose origin is the _Root_ origin mentioned before, and has a very restrictive configuration for votes to go through. But other tracks have much lower privilege levels to do some less critical network operations ## Transaction Types {: #transaction-types} Tanssi networks have three main types of transactions: - **Signed Transactions** - include a signed payload requesting to execute some runtime call. Generally, the signature is associated with a private key/public key pair. Depending on the runtime logic, the account associated with the signature pays a transaction fee - **Unsigned Transactions** - include an unsigned payload requesting to execute some runtime call. Because these transactions are unsigned, there is no account associated with them. Consequently, runtimes need to define specific conditions that prevent network spam or replay attacks because there is no fee mechanism to prevent such malicious behaviors. One example of an unsigned transaction is executing pre-approved actions, like a runtime upgrade - **Inherent Transactions** - an unsigned transaction that a sequencer inserts into a block when initializing its construction. These transactions are part of the block and are not stored in the transaction pool or shared among network participants. In addition, the data inserted through inherent transactions can skip runtime validation, and it might be up to operators to accept it. One example is the block timestamp. This is injected into the block by an inherent transaction, and operators can accept or reject the block based on whether the timestamp is within some acceptable range ## Transaction Execution {: #transaction-execution} When a user or application submits a signed transaction to a Tanssi network, the transaction is validated at a full-node level using rules defined in the runtime, and then it is queued in a transaction pool. This ensures that only transactions that comply with certain chain-specific conditions are considered to be included in a block. !!! note The most common type of transaction is a signed transaction. Nevertheless, unsigned transactions are also validated before they are queued in the transaction pool. The valid transaction queue comprises two pools: ready and future. The ready queue contains all transactions that can be included in a new pending block. The future queue is for transactions that don't meet all the criteria to be included now but might become valid. For example, transactions with a future nonce. Invalid transactions are directly rejected. During the block-building process, a sequencer uses a [priority system](https://github.com/paritytech/substrate/blob/fb24fda76d613305ebb2e5728c75362c94b64aa1/frame/transaction-payment/src/lib.rs#L614-L681){target=\_blank} through a transaction orchestration module to order transactions for the next block, until the block reaches its maximum capacity. The block building and execution order has the following operations: - **Initializing a Block** - known as `on_initialize`, enables you to define runtime logic executed before any other transaction is accounted for. For example, inherent transactions, like the timestamp in the previous example, are commonly executed when initializing a block. Once the initialization logic is completed, the transaction orchestration module verifies the parent hash in the block header and the trie root to ensure the information is correct - **Transaction Execution** - with the block already initialized, the transaction orchestration module executes each valid transaction according to its priority. The initial state is not cached before the execution, meaning that if one of the transactions fails mid-execution, any state changes committed up to that moment cannot be reverted, and the subsequent block will be invalid. Consequently, runtime logic should perform all necessary checks to ensure all valid transactions will succeed - **Finalizing a Block** - after all queued valid transactions are executed or the block limit is reached, the orchestration module calls into each runtime module the `on_idle` and `on_finalize` functions. These two functions allow the definition of extra business logic that is automatically executed in the block finalization process. After the last `on_finalize` function is called, the orchestration module ensures that the block digest and storage root match what was calculated when the block was initialized ## Forkless Upgrades {: #forkless-upgrades} Networks deployed through Tanssi have a thrilling feature: [forkless upgrades](https://docs.polkadot.com/develop/parachains/maintenance/runtime-upgrades/){target=\_blank}. Forkless upgrades allow developers to change the state transition function that governs the chain without creating a network fork, as seen on Ethereum multiple times. Furthermore, if the Tanssi network is set up with an on-chain governance system, upgrades to the network can happen in a truly decentralized and trustless way. Forkless upgrades are made possible by storing the state transition function as a WebAssembly (Wasm) blob in both the Tanssi network itself and the Tanssi-powered network. When a new runtime is scheduled through a function call in the Tanssi-powered network, the Tanssi network validates this block, so it is notified and readies itself to validate incoming blocks using the most recent state transition function. Following a specified runtime upgrade delay period, a Tanssi sequencer on the Tanssi-powered network constructs a block that references a Tanssi network block, signaling to the Tanssi network that it can now apply the new runtime. Consequently, this new state transition function is utilized for that specific block. As all infrastructure participants at the network level employ the on-chain Wasm blob, every Tanssi network node operator can validate new blocks using the latest state transition function. A high-level summary of the runtime upgrade process is shown in the following diagram: ![Runtime Upgrade Process Tanssi Networks](/images/learn/decentralized-networks/runtime-features/runtime-features-1.webp) ## SUDO Account {: #sudo-account} Tanssi networks may use a specific module called [SUDO](https://paritytech.github.io/polkadot-sdk/master/pallet_sudo/pallet/struct.Pallet.html){target=\_blank}. This module introduces a new type of account, also named _SUDO_, that can execute transactions with the [_Root_ origin](#origins). Consequently, the SUDO account can perform **any** action that the runtime allows the _Root_ origin to execute. This can include: - Mint new native Tanssi network tokens - Perform [forkless runtime upgrades](#forkless-upgrades) - Send transactions impersonating other [origin types](#origins). Therefore, SUDO can send transactions on behalf of other users without accessing their private key _SUDO_ is recommended for TestNets as it allows them to swiftly make changes without the need to go through a lengthy on-chain governance process. It is good practice to have _SUDO_ keys stored safely and grant access to _SUDO_ calls via proxy accounts. Nevertheless, having _SUDO_ enabled in a production environment can lead to undesired consequences. **Understanding the centralization risks of having _SUDO_ in a production environment is key.** --- END CONTENT --- Doc-Content: https://docs.tanssi.network/learn/decentralized-networks/tx-fees/ --- BEGIN CONTENT --- --- title: Transaction Fees description: Learn about the transaction fee mechanism in Tanssi networks, how it works from a Substrate perspective, and in the Ethereum EVM emulation layer with EIP-1559. icon: material-piggy-bank-outline categories: Basics --- # Transaction Fees {: #transaction-fees } ## Introduction {: #introduction} Tanssi-powered networks are built with a [modular framework](/learn/framework/){target=\_blank} called [Substrate](https://docs.polkadot.com/develop/parachains/intro-polkadot-sdk/){target=\_blank}. With this framework, you can build unique ways to handle transaction fees. For example, most transactions use a specific module called [Transaction Payment](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment){target=\_blank}. However, transaction fees on Tanssi-powered EVM-compatible networks can be charged at an EVM execution level, bypassing other fee-related modules. Under the hood, for execution time, instead of working with a gas-based mechanism, all Tanssi networks work with a [weight-based mechanism](https://docs.polkadot.com/polkadot-protocol/basics/blocks-transactions-fees/fees/){target=\_blank}. Weight refers to the time (in picoseconds) it takes to validate a block. Generally speaking, for both EVM and non-EVM Tanssi networks, all function calls have a weight associated with them, which sets limits on storage input/output and computation. For Tanssi EVM networks, there is a gas-to-weight mapping that fully complies with the expected gas requirements for Ethereum API-based tools. A transaction fee scheme is applied on top of the weight-based mechanism to ensure economic incentives are in line to limit the execution time, computation, and number of calls (database read/writes) to perform operations. Transaction fees are fundamental to preventing network spam, as they represent the cost of using the Tanssi network service. Consequently, a user interacting with the network through a specific function call will pay a transaction fee determined by a baseline fee algorithm. This page covers the fundamentals of transaction fees for Tanssi networks. It first covers the underlying transaction fee architecture and how it is adapted to a fully EIP-1559-compliant model for Tanssi EVM networks. ## Baseline Fees Calculation {: #baseline-fees } Every action that alters the state of a Tanssi network incurs a transaction fee. This fee is essential for the network's operation, covering the computational resources required to process transactions, similar to the gas and gas price parameters in EVM-compatible chains like Ethereum. Tanssi networks [modular framework](/learn/framework/){target=\_blank} use a weight-based fee calculation mechanism to determine transaction fees. This approach considers various factors, including computational resources and storage operations (inputs/outputs), to reflect the true cost of transactions accurately. By accounting for these elements, the network ensures fair and efficient resource allocation. Furthermore, Tanssi networks modularity ensures that EVM-compatible networks support legacy and [EIP-1559 compatible](https://eips.ethereum.org/EIPS/eip-1559){target=\_blank} transaction pricing mechanisms, ensuring full compatibility with development environments commonly used in Ethereum. This section outlines all the different concepts associated with transaction fees for Tanssi networks. ### Weight {: #baseline-weight} Broadly speaking, weight refers to the execution time it takes to validate a block, measured in picoseconds. Weight is divided into two separate variables: - **`refTime`** - corresponds to the weight associated with computation time and database reads/writes - **`proofSize`** - corresponds to the weight associated with the size of the Proof-Of-Validity (or PoV for short). The PoV is associated with the relevant state of a transaction, and it is what the Tanssi network sequencer shares with the security provider operators to get a block validated and finalized as part of the [network transaction flow](/learn/decentralized-networks/overview/#network-transaction-flow){target=\_blank} To find the weights for all function calls, they are benchmarked in a system with reference hardware, and the approximate values of `refTime` and `proofSize` are set. This process is repeated for all function calls that consume blockspace and affect the PoV. For transactions in which the fees are handled by the [transaction payment](https://docs.rs/pallet-transaction-payment/latest/pallet_transaction_payment){target=\_blank} module, all weight-based parameters are then passed through a _weight to fee_ algorithm that converts all to a final value, deducted from the sender's account when executing the function call. The algorithm can be customized, but Tanssi networks have a constant value set. For EVM transactions, gas is converted to weight through a gas-to-weight algorithm so that all EVM calls can be mapped to block execution time. Nevertheless, fees are handled at an EVM execution level. ### Baseline Transaction Fees {: #baseline-transaction-fees} With all function calls benchmarked, the transaction fee for each specific call can be obtained. Transaction fees are typically comprised of the following elements: - **`BaseFee`** - baseline cost for a transaction to be included. It accounts for the transaction inclusion overhead, like signature verification. The fee is defined by two separate parameters: - **`ExtrinsicBaseWeight`** - a constant value that represents the weight of the transaction inclusion overhead - **`WeightToFee`** - a polynomial function that converts weight to fee - **`WeightFee`** - fee defined by two separate parameters: - **`BenchmarkedWeight`** - weight that accounts for the complexity (execution time) of a specific call - **`CongestionMultiplier`** - a function that converts weight to fee and can be adjusted to account for the congestion of the network (weight consumed in the previous block). The default strategy for Tanssi networks is [`SlowAdjustingFeeUpdate`](https://research.web3.foundation/Polkadot/overview/token-economics#2-slow-adjusting-mechanism){target=\_blank}, which adjusts this multiplier slowly over time following the network load - **`LengthFee`** - a fee correlated to the length in bytes of the function call. The fee is defined by two separate parameters: - **`ByteLengthFunctionCall`** - length in bytes of the call being executed - **`LengthToFee`** - a function that defines the per-byte fee algorithm. For Tanssi networks, this is a constant value - **`Tip`** - an optional value that increases the overall fee, increasing the priority of the transaction by incentivizing sequencers to include it in the next block Therefore, in general terms, the transaction fee can be calculated with the following equation: ```text BaseFee = ExtrinsicBaseWeight * WeightToFee WeightFee = BenchmarkedWeight * CongestionMultiplier LengthFee = ByteLengthFunctionCall * LengthToFee InclusionFee = BaseFee + WeightFee + LengthFee FinalFee = InclusionFee + Tip ``` All non-EVM function calls available to developers use these baseline calculations for transaction fees. Tanssi EVM networks have an extra layer to translate this fee scheme into an Ethereum-like scheme from an Ethereum JSON-RPC and EVM perspective. ### EVM Transaction Fees {: #evm-transaction-fees } Tanssi offers [templates for full Tanssi EVM-compatible networks](/builders/build/templates/evm/){target=\_blank}. Such networks provide an Ethereum-like environment for developers, where they can use Eth-specific libraries like [Ethers.js](/builders/toolkit/ethereum-api/libraries/ethersjs/){target=\_blank}, [Hardhat](/builders/toolkit/ethereum-api/dev-env/hardhat/){target=_blank}, and [Foundry](/builders/toolkit/ethereum-api/dev-env/foundry/){target=\_blank}. In addition, all Tanssi EVM-compatible networks have an [EIP-1559 compatible](https://eips.ethereum.org/EIPS/eip-1559){target=\_blank} transaction pricing mechanism for EVM transactions. But they support both commonly used EVM transaction types: - **Type 0 (Legacy)** - the transaction fee is calculated through a single gas price value that is included in the signed transaction blob. Because Tanssi EVM-compatible networks have a dynamic pricing mechanism, gas price must be greater than the current block's `baseFee` for a transaction to be considered valid - **Type 2 (EIP-1559)** - the transaction fee is calculated with a combination of the `maxFeePerGas` and `maxPriorityFeePerGas` from the signed transaction blob, and the network's `baseFee` dynamically changes based on block congestion Independently of the transaction type, the outcome of all EVM transactions is that there is an associated cost in native tokens that the network must charge. By default, Tanssi EVM-compatible networks are configured with the following parameters: - **Minimum BaseFee** - the minimum gas price of the network in case there are no transactions for long periods. The default value is set to 1 GWei - **Block Fulness Target (Elasticity)** - the target gas used in a block so that the `baseFee` remains the same. [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559){target=\_blank} defines this value as a constant set to 2, meaning that the target usage is 50% of the block gas limit. All Tanssi EVM-compatible networks are set with the same target - **Maximum BaseFee Increase** - the maximum amount the `baseFee` can increase or decrease, in percent points, based on the previous block target usage. [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559){target=\_blank} defines this value as a constant set to 12.5%. Consequently, if the block is full/empty, the `baseFee` will increase/decrease by 12.5%, and any intermediate values are linearly adjusted. Developers can configure this value for Tanssi EVM-compatible networks, but the default value is 12.5% !!! note One key difference in Tanssi EVM-compatible networks EIP-1559 implementation is that the transaction fees are calculated using the previous block `baseFee`. The EVM transaction fee cost associated with all Tanssi EVM-compatible networks is captured at an EVM execution level. Nevertheless, EVM transactions do take block execution time. Therefore a gas-to-weight algorithm is required to account for the weight consumed by a specific call relative to the gas it is consuming. Ultimately, the transaction fee and weight associated to an EVM call in a Tanssi EVM-compatible network can be calculated with the following formula: === "EIP-1559" ```text Gas Price = baseFee + maxPriorityFeePerGas < maxFeePerGas ? baseFee + maxPriorityFeePerGas : maxFeePerGas; Transaction Fee = Gas Price * Gas Used Transaction Weight = Gas Used * GasToWeight ``` === "Legacy" ```text Transaction Fee = GasPrice * GasUsed Transaction Weight = GasUsed * GasToWeight ``` `GasToWeight` is a constant value set to `{{ templates.evm.gas_to_weight }}`. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/learn/framework/architecture/ --- BEGIN CONTENT --- --- title: Framework Architecture description: In a Substrate node, two main components are the runtime, which controls the blockchain's state transition, and the client, which manages everything else. icon: octicons-stack-24 categories: Basics --- # Framework Architecture {: #framework-architecture } ## Introduction {: #introduction } Substrate is a software development kit (SDK) for building blockchains. This framework is the foundation and engine powering many projects across the Web3 ecosystem, including the Tanssi network itself and the networks deployed through Tanssi. Written in the Rust language and designed with a modular architecture, Substrate is extremely performant, flexible, and highly customizable, making it the best choice for developing blockchains. In this article, the architecture of a Substrate node is covered. ## Architecture {: #architecture } The Substrate framework is designed for maximum customizability, providing a fully functional implementation for every important internal aspect of a blockchain. It allows developers to focus on the specifics of the use case and the runtime characteristics, and it provides the ability to change any of the default features (should the need arise). The architecture of a Substrate node contains two main components: - **Core Client** - handles the communication with the outer world (other nodes, dApps, end users, among others), and many other internal responsibilities, such as storage and communication - **Runtime** - implements the custom logic of the Tanssi network, executes transactions, and manages the state transitions From the end-user perspective, all the interaction with the Tanssi network is usually made through dApps or directly via the node RPC endpoints, for example, using a wallet. When a user triggers a request to fetch data or sends transactions to a node, the core client is responsible for responding or queuing the transactions until execution in the runtime. Still, all these internal aspects of the node design are kept transparent to the user. ![Basic substrate node architecture](/images/learn/framework/architecture/architecture-1.webp) ## The Core Client {: #core-client } The core client comprises components responsible for everything in the operation of a node in the network except for what happens in the runtime. Some of the main components are: - **Networking** - this component handles the communication with the peers in the network (synchronizing blocks, propagating transactions, and so on) and exposes the endpoints that allow dApps to integrate and interact with the Tanssi network - **Storage** - this component manages the state storage of the Tanssi network in a highly efficient key-value database - **Consensus** - this component ensures that all the participants in the network agree on the state of the blockchain, validating transactions, state transitions, and the resulting blocks The default configuration of a Substrate node and the built-in implementations of the components are usually the best choice for most use cases. Still, teams are welcome to innovate and change or replace any piece of the node or even write a completely different implementation of the core client, such as [Kagome](https://github.com/soramitsu/kagome#intro){target=\_blank} (C++ implementation) and [Gossamer](https://github.com/ChainSafe/gossamer#a-go-implementation-of-the-polkadot-host){target=\_blank} (Golang implementation). ## The Runtime {: #runtime } The runtime plays a crucial role in the operation of the Tanssi network. It contains the core logic and rules to meet the requirements of the use case the developers are building, and, therefore, it is responsible for validating the transactions and executing the state transitions. Being the core element in a Tanssi network, designing the Substrate architecture an important decision has been made regarding the format for the runtime: it is compiled to [WebAssembly (Wasm)](https://webassembly.org){target=\_blank} byte code. The Wasm format offers many advantages to a deployed Tanssi network, including: - **Portability** - the Wasm format is platform-independent, meaning that the same binary can be distributed and run on different nodes using different hardware architectures and operating systems - **Deterministic Execution** - the Wasm format ensures deterministic execution of code, which means that the same input will always produce the same output. Determinacy is a critical aspect in blockchains to obtain the same state transitions across every node in the network and reach a consensus - **Forkless Upgradeability** - Substrate stores the runtime Wasm blob on-chain, meaning that the runtime itself becomes part of the state. This design allows upgrading the runtime logic in a forkless way using a transaction Besides the format, internally, a Substrate runtime is built by composing different modules, either provided and ready-to-use by Substrate or custom-made. Each one of these modules define, among other things, the transactions they expose, the logic behind them, what needs to be stored in the chain state, the best format to do it, and how they cooperate with other modules composing functionality. More details about building a runtime will be covered in the [modules](/learn/framework/modules/){target=\_blank} section. ## Client-Runtime Communication {: #client-runtime-communication } As previously described, the two main components of a Substrate node (the core client and the runtime) have a clear separation of concerns. Beyond the functional responsibilities, at a lower level, their binary representation and execution environments are different. While the node is compiled to be installed and run on a specific platform (be it Linux x64 or any other), the Tanssi network runtime is compiled to a Wasm format that is platform-agnostic and runs in an isolated execution environment. Bearing in mind the separated execution environments, all the communication between the node client and the runtime occurs through a limited and well-defined interface, allowing the necessary operations such as: - **Executing Transactions** - when a user submits a transaction to the client node, the node passes this transaction to the runtime through the defined API for its execution - **State Queries** - the client node can query the current state of the blockchain to retrieve information such as account balances and any other domain-specific data - **Consensus and Finality** - the client node coordinates consensus and finalization of the blocks, but it is the runtime's responsibility to determine the validity of new blocks, validate transactions, and ensure that the consensus rules are followed - **Event Notifications** - the runtime emits events while executing transactions that the client node can use to keep external users updated about specific actions or changes in the state --- END CONTENT --- Doc-Content: https://docs.tanssi.network/learn/framework/modules/ --- BEGIN CONTENT --- --- title: Network Modules for your Runtime description: Substrate is a modular blockchain development framework with an extensive set of ready-to-use components to bundle with custom logic into the network Runtime. icon: material-puzzle-outline categories: Custom-Runtime, Basics --- # Network Framework Modules {: #network-framework-modules } ## Introduction {: #introduction } The Substrate framework provides complete and ready-to-use implementations of the main functions a Tanssi network needs to work properly, including cryptography, consensus, governance, and so on. These implementations are fully customizable and could be replaced with custom logic if needed. When building the Runtime, which defines the state transition rules between two blocks applied to a set of transactions, the intended behavior and features of the blockchain need to be set by determining the rules of the state transition. To build the Runtime, Substrate provides many built-in modules (also known as pallets) that can be freely used as building blocks to compose and interact with any other custom-made modules, allowing teams to create unique behaviors according to the specific requirements of their Tanssi network. ![Built-in modules](/images/learn/framework/modules/modules-1.webp) ## Built-in Modules {: #built-in-modules } When designing and writing the rules of a Tanssi network, the available set of functional modules brings a solution to many of the coding requirements that would otherwise need to be built from scratch. Here is a list of some of the most popular modules: - **[Balances](https://paritytech.github.io/substrate/master/pallet_balances/index.html){target=\_blank}** - it provides functions for handling accounts and balances for the Tanssi network native currency - **[Assets](https://paritytech.github.io/substrate/master/pallet_assets/index.html){target=\_blank}** - it provides functions for handling any type of fungible tokens - **[NFTs](https://paritytech.github.io/substrate/master/pallet_nfts/index.html){target=\_blank}** - it provides functions for dealing with non-fungible tokens - **[Democracy](https://paritytech.github.io/substrate/master/pallet_democracy/index.html){target=\_blank}** - it provides functions to manage and administer general stakeholder voting - **[Multisig](https://paritytech.github.io/substrate/master/pallet_multisig/index.html){target=\_blank}** - it provides functions for multi-signature dispatch - **[Recovery](https://paritytech.github.io/substrate/master/pallet_recovery/index.html){target=\_blank}** - it provides functions to allow users to regain access to their accounts when the private key is lost. This works by granting other accounts the right to sign transactions on behalf of the lost account (note that it is necessary to have previously chosen the authorized accounts) - **[Staking](https://paritytech.github.io/substrate/master/pallet_staking/index.html){target=\_blank}** - it provides functions to administer staked tokens, support rewarding, slashing, depositing, withdrawing, and so on In addition to those previously listed, other modules like [identity](https://paritytech.github.io/substrate/master/pallet_identity/index.html){target=\_blank}, [smart contracts](https://paritytech.github.io/substrate/master/pallet_contracts/index.html){target=\_blank}, [vesting](https://paritytech.github.io/substrate/master/pallet_vesting/index.html){target=\_blank}, and many others that are freely available can speed up the development of the Tanssi network and, consequently, the time to market. !!! note The framework also includes other modules that provide core protocol functionality, such as consensus and low-level data encoding. ## Custom-Made Modules {: #custom-modules } Developers creating new modules enjoy complete freedom to express any desired behavior in the core logic of the blockchain, like exposing new transactions, storing sensible information, and validating and enforcing business logic. As explained in the [Architecture](/learn/framework/architecture/#client-runtime-communication){target=\_blank} article, a module needs to be able to communicate with the core client by exposing and integrating with a very specific API that allows the runtime to expose transactions, access storage, and code and decode information stored on-chain. It also needs to include many other required wiring codes that make the module work in the node. To improve developer experience when writing modules, Substrate relies heavily on [Rust macros](https://doc.rust-lang.org/book/ch19-06-macros.html){target=\_blank}. Macros are special instructions that automatically expand to Rust code just before compile-time, allowing modules to keep up to seven times the amount of code out of sight of the developers. This allows developers to focus on the specific functional requirements when writing modules instead of dealing with technicalities and the necessary scaffolding code. All modules in Substrate, including custom-made ones, implement these attribute macros, of which the first three are mandatory: - **`#[frame_support::pallet]`** - this attribute is the entry point that marks the module as usable in the runtime - **`#[pallet::pallet]`** - applied to a structure that is used to retrieve module information easily - **`#[pallet::config]`** - is a required attribute to define the configuration for the data types of the module - **`#[pallet::call]`** - this macro is used to define functions that will be exposed as transactions, allowing them to be dispatched to the runtime. It is here that the developers add their custom transactions and logic - **`#[pallet::error]`** - as transactions may not be successful (insufficient funds, as an error example), and for security reasons, a custom module can never end up throwing an exception, all the possible errors are to be identified and listed in an enum to be returned upon an unsuccessful execution - **`#[pallet::event]`** - events can be defined and used as a means to provide more information to the user - **`#[pallet::storage]`** - this macro is used to define elements that will be persisted in storage. As resources are scarce in a blockchain, it should be used wisely to store only sensible information All these macros act as attributes that must be applied to the code just above Rust modules, functions, structures, enums, types, etc., allowing the module to be built and added to the runtime, which, in time, will expose the custom logic to the outer world, as exposed in the following section. ### Custom Module Example { #custom-module-example } As an example of a custom module, the following code (not intended for production use) showcases the use of the previously mentioned macros by presenting a simple lottery with minimal functionality, exposing two transactions: - **buy_ticket** - this transaction verifies that the user signing the request has not already bought a ticket and has enough funds to pay for it. If everything is fine, the module transfers the ticket price to a special account and registers the user as a participant for the prize - **award_prize** - this transaction generates a random number to pick the winner from the list of participants. The winner gets the total amount of the funds transferred to the module's special account ```rust #![cfg_attr(not(feature = "std"), no_std)] /// Learn more about FRAME and the core library of Substrate FRAME pallets: /// pub use pallet::*; #[frame_support::pallet(dev_mode)] pub mod pallet { use super::*; use frame_support::pallet_prelude::{*, ValueQuery, OptionQuery}; use frame_system::pallet_prelude::*; use scale_info::prelude::vec::Vec; use frame_support:: { sp_runtime::traits::AccountIdConversion, traits:: { Currency, ExistenceRequirement, Randomness }, PalletId, }; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; #[pallet::pallet] pub struct Pallet(_); /// Configure the module by specifying the parameters and types on which it depends. #[pallet::config] pub trait Config: frame_system::Config { // Event definition type RuntimeEvent: From> + IsType<::RuntimeEvent>; // Currency type Currency: Currency; // Randomness type MyRandomness: Randomness>; // Ticket cost #[pallet::constant] type TicketCost: Get>; // Maximum number of participants #[pallet::constant] type MaxParticipants: Get; // Module Id #[pallet::constant] type PalletId: Get; } // The pallet's runtime storage items. #[pallet::storage] #[pallet::getter(fn get_participants)] pub(super) type Participants = StorageValue< _, BoundedVec, OptionQuery >; #[pallet::storage] #[pallet::getter(fn get_nonce)] pub(super) type Nonce = StorageValue< _, u64, ValueQuery >; // Pallets use events to inform users when important changes are made. // https://docs.substrate.io/main-docs/build/events-errors/ #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { /// Event emitted when a ticket is bought TicketBought { who: T::AccountId }, /// Event emitted when the prize is awarded PrizeAwarded { winner: T::AccountId }, /// Event emitted when the prize is to be awarded, but there are no participants ThereAreNoParticipants, } // Errors inform users that something went wrong #[pallet::error] pub enum Error { NotEnoughCurrency, AccountAlreadyParticipating, CanNotAddParticipant, } #[pallet::call] impl Pallet { #[pallet::call_index(0)] #[pallet::weight(0)] pub fn buy_ticket(origin: OriginFor) -> DispatchResult { // 1. Validates the origin signature let buyer = ensure_signed(origin)?; // 2. Checks that the user has enough balance to afford the ticket price ensure!( T::Currency::free_balance(&buyer) >= T::TicketCost::get(), Error::::NotEnoughCurrency ); // 3. Checks that the user is not already participating if let Some(participants) = Self::get_participants() { ensure!( !participants.contains(&buyer), Error::::AccountAlreadyParticipating ); } // 4. Adds the user as a new participant for the prize match Self::get_participants() { Some(mut participants) => { ensure!( participants.try_push(buyer.clone()).is_ok(), Error::::CanNotAddParticipant ); Participants::::set(Some(participants)); }, None => { let mut participants = BoundedVec::new(); ensure!( participants.try_push(buyer.clone()).is_ok(), Error::::CanNotAddParticipant ); Participants::::set(Some(participants)); } }; // 5. Transfers the ticket cost to the module's account // to be hold until transferred to the winner T::Currency::transfer( &buyer, &Self::get_pallet_account(), T::TicketCost::get(), ExistenceRequirement::KeepAlive)?; // 6. Notify the event Self::deposit_event(Event::TicketBought { who: buyer }); Ok(()) } #[pallet::call_index(1)] #[pallet::weight(0)] pub fn award_prize(origin: OriginFor) -> DispatchResult { // 1. Validates the origin signature let _who = ensure_root(origin)?; match Self::get_participants() { Some(participants) => { // 2. Gets a random number from the randomness module let nonce = Self::get_and_increment_nonce(); let (random_seed, _) = T::MyRandomness::random(&nonce); let random_number = ::decode(&mut random_seed.as_ref()) .expect("secure hashes should always be bigger than u32; qed"); // 3. Selects the winner from the participants lit let winner_index = random_number as usize % participants.len(); let winner = participants.as_slice().get(winner_index).unwrap(); // 4. Transfers the total prize to the winner's account let prize = T::Currency::free_balance(&Self::get_pallet_account()); T::Currency::transfer( &Self::get_pallet_account(), &winner, prize, ExistenceRequirement::AllowDeath)?; // 5. Resets the participants list, and gets ready for another lottery round Participants::::kill(); // 6. Notify the event Self::deposit_event(Event::PrizeAwarded { winner: winner.clone() } ); }, None => { // Notify the event (No participants) Self::deposit_event(Event::ThereAreNoParticipants); } }; Ok(()) } } impl Pallet { fn get_pallet_account() -> T::AccountId { T::PalletId::get().into_account_truncating() } fn get_and_increment_nonce() -> Vec { let nonce = Nonce::::get(); Nonce::::put(nonce.wrapping_add(1)); nonce.encode() } } } ``` For more information about the step-by-step process of creating a custom-made module to the runtime, please refer to the [Adding a Custom-Made Module](/builders/build/customize/adding-custom-made-module/){target=\_blank} in the Builder's section. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/learn/framework/overview/ --- BEGIN CONTENT --- --- title: Network Development Framework Overview description: Substrate is a blockchain development framework built in Rust Programming Language that streamlines and speeds up the process of developing new networks. icon: octicons-home-24 categories: Basics --- # Network Development Framework Overview {: #network-dev-framework-overview } ## Introduction {: #introduction } Building a network from scratch is a very complex task that requires deep knowledge in a wide range of areas, including (but not limited to): - **Consensus Algorithms** - consensus ensures that all participants in the blockchain network agree on the validity of transactions. Some popular consensus mechanisms include Proof of Work (PoW) and Proof of Stake (PoS) - **Cryptography** - cryptography plays a crucial role in securing the blockchain. You'll need cryptographic algorithms for tasks like creating digital signatures, verifying transactions, and encrypting data - **Distributed Network** - a network architecture to enable nodes to communicate, validate transactions, and synchronize the blockchain data is key to maintaining a shared ledger in a decentralized network - **Data Structures** - besides the list of blocks, where each block contains a set of transactions along with a reference to the previous block, an optimized and performant strategy to store the state of the network is needed - **Governance** - if the network is designed to be permissionless, a voting mechanism is important in order to keep it evolving and reflecting the community will - **Upgradeability** - it is necessary to clearly define how to upgrade, how modifications are implemented, and how conflicts are resolved within the network Fortunately, there’s no need to build these blockchain components from scratch, thanks to an excellent open-source framework called [Substrate](https://docs.polkadot.com/develop/parachains/intro-polkadot-sdk/){target=\_blank}. Tanssi itself is built with this framework, leveraging its comprehensive base implementations, modularity, and flexibility to achieve a high level of customization. ## Substrate Framework {: #substrate-framework} Substrate is an extremely performant, flexible, modular, and highly customizable framework for building blockchains. This framework is the foundation and engine powering many projects across the Web3 ecosystem, including the Tanssi network itself and the networks deployed through Tanssi. Many of its great features, such as performance, ease of use, and modularity, result from the programming language chosen for its development. This is where the [Rust Programming Language](#rust-programming-language) shines: It is fast, portable, and provides a wonderful model to handle memory, among other reasons detailed in the [next section](#rust-programming-language). When developing a network, Substrate represents a great head start by providing a ready-to-use set of implementations of the main building blocks a project needs: - **Consensus Algorithms** - there are multiple built-in consensus engines, such as Aura (Proof of Authority), Babe (Proof of Stake), and Grandpa (block finality), but due to the high degree of customization Substrate offers, teams can always choose to develop their specific consensus to adapt to the use case needs, as the Moonbeam team did with the [Nimbus Parachain Consensus Framework](https://docs.moonbeam.network/learn/features/consensus){target=\_blank} - **Runtime Modules** - many built-in modules (explained in detail in the [modules](/learn/framework/modules/){target=\_blank} section) can be selected and configured into your network, such as accounts, balances, staking, governance, identity, and more - **Networking** - built-in protocols and libraries for establishing connections, propagating transactions and blocks, synchronizing the blockchain state, and managing network interactions - **Storage** - built-in storage mechanisms for efficient data storage and retrieval - **Transaction Queue** - built-in transaction queue system that manages transaction validation, prioritization, and inclusion in blocks, ensuring the consistency and integrity of the network's state - **RPC APIs** - Substrate provides Remote Procedure Call (RPC) APIs that enable external applications to interact with the network by querying blockchain data, submitting transactions, and accessing various functionalities exposed by the runtime Every feature Substrate offers can be used as-is, extended, customized, or replaced to meet the specific requirements of the use case of the network. Substrate streamlines and speeds up the process of developing new networks. When used in conjunction with Tanssi, which helps in handling the infrastructure and overseeing the deployment, the task of launching a new network becomes significantly simpler! ## Rust Programming Language {: #rust-programming-language} [Rust](https://www.rust-lang.org){target=\_blank} is a programming language that has unique features that have made it the most loved language for the seventh consecutive year, according to [Stack Overflow's annual developer survey](https://survey.stackoverflow.co/2022#section-most-loved-dreaded-and-wanted-programming-scripting-and-markup-languages){target=blank}. In addition to providing a great experience for developers, Rust excels in many areas: - **Memory safety** - Rust compiler enforces strict compile-time checks to prevent common programming errors such as null pointer dereferences, buffer overflows, and data races. Additionally, memory is managed through a novel system of ownership (checked by the compiler), which eliminates the necessity for a garbage collector - **Performance** - Rust achieves performance comparable to that of C and C++ by providing low-level control over system resources and minimizing runtime overhead. It has a zero-cost abstraction principle, similar to "what you don't use, you don't pay for" from C++, meaning that abstractions have no extra overhead - **Concurrency** - Rust has built-in features that make it easy to write concurrent and parallel code without introducing data races. It provides lightweight threads (tasks) and a powerful ownership model that ensures the safe sharing of data between threads - **Expressive and safe abstractions** - Rust offers a rich set of modern language features, such as pattern matching, algebraic data types, closures, and type inference, allowing developers to write and read expressive and concise code. The Rust compiler enforces the strong type system, preventing many runtime errors at compile-time - **Cross-platform compatibility** - Rust is designed to work well on a variety of platforms and architectures. It supports major operating systems like Windows, macOS, and Linux, as well as embedded systems and WebAssembly. This versatility allows developers to write code that can be deployed across different environments - **Growing ecosystem** - Rust has a rapidly growing ecosystem with a vibrant community and a rich collection of libraries and tools. The official package manager, Cargo, simplifies dependency management, building, and testing - **Interoperability** - Rust provides seamless interoperability with existing codebases written in C and C++. It has a Foreign Function Interface (FFI) that allows Rust code to interface with code written in other languages, enabling developers to gradually introduce Rust into existing projects, like the Linux kernel --- END CONTENT --- Doc-Content: https://docs.tanssi.network/learn/framework/xcm/ --- BEGIN CONTENT --- --- title: Native Cross-Chain Communication description: Tanssi networks benefit from XCM, a native cross-chain communication language, which allows fast and secure bridging guaranteed by Polkadot's relay chain. categories: Basics --- # Native Cross-Chain Communication ## Introduction {: #introduction } All Tanssi-powered networks have an inherent capability to communicate and interoperate with any other network in the ecosystem. This native cross-chain communication feature is possible thanks to the unique infrastructure the networks are built on top of, leveraging the Cross-Consensus Message format (XCM for short), which facilitates communication between different consensus systems. XCM is a messaging language designed to be generic. It doesn't make any assumptions about the destination chain and can communicate different intentions between sovereign consensus systems. An XCM message is a program holding one or more instructions that will be relayed for execution to the destination chain. By itself, each XCM instruction is meaningless, but the combination of a specific set of instructions can result in a desired action when the XCM message is executed in the destination chain. In this article, we cover the basic concepts of the native cross-chain communication mechanism that allows fast and secure bridging within the ecosystem. ## Design Principles {: #design-principles } Conceived with an abstract mindset, XCM is not designed to comply with a specific use case or specific destination network setup, thus minimizing the coupling effect. Its core design principles are: - **Asynchronous** - similar to sending a postcard -but way faster- the sender will keep performing its duties as usual, without blocking itself or awaiting a response from the destination - **Absolute** - messages are guaranteed to be delivered to the intended destination, in order and in a timely fashion - **Asymmetric** - messages sent have no response counterpart. Any return values, if required, must be sent back from the destination to the sender with another message - **Agnostic** - there are no assumptions whatsoever about the configuration or properties of two communicating networks. Networks might differ in every aspect, except the ability to understand XCM. E.g., one chain could be EVM-compatible and not the other, one chain could be a DeFi network and the other a gaming network, and so on ## Fees {: #fees } A user executing a transaction on a network must pay the fees derived from computational effort associated with the task, and cross-chain execution is no exception to this rule. In cross-chain communication, a message requires execution on at least two different chains, and the user needs to pay for the fees associated with the computational effort made by every chain involved. Besides the execution-related costs, Tanssi networks include a default [delivery fee](https://paritytech.github.io/polkadot-sdk/master/polkadot_runtime_common/xcm_sender/struct.ExponentialPrice.html){target=\_blank} to prevent XCM spamming. For example, if a user on network A wants to call a smart contract on network B, the user must have enough funds to pay for the message delivery and include instructions in the XCM message to provide an asset that network B accepts as payment for its services to cover the associated fees. Once such an asset is provided, the execution can now be bought on the destination chain. !!! note Since networks are sovereign, they get to decide which tokens are valid for paying their XCM execution fees. E.g., if network B accepts network A tokens for fee payments, any user on network A can pay for an XCM message destined for network B using only network A tokens. ## Common Use Cases {: #common-use-cases } Many use cases can be addressed by benefiting from the common ground and versatility XCM provides. Two of the most recurrent ones are asset transfers and remote execution. ### Asset Transfers {: #asset-transfer } Moving digital assets from one network to another is essential for creating a more dynamic, efficient, and interconnected blockchain ecosystem. The native cross-chain capability allows two main strategies to transfer assets from one chain to another: - **Teleport** - teleporting an asset is a simple and efficient mechanism, but it has a major caveat: it requires trust between the parties. In essence, when network A wants to send X amount of assets to network B, it burns X amount of assets and sends a message to network B instructing them to mint exactly X amount of assets, preserving the overall asset balance and concluding the teleport action. In this process, network A trusts network B not to mint more tokens than what was transferred, and network B trusts network A to burn the tokens that were transferred - **Reserve transfer** - A reserve transfer involves the **reserve chain** of an asset, which is the chain where the asset is native (e.g., [Moonbeam](https://moonbeam.network/){target=\_blank} is the reserve chain for the GLMR token). Also, non-reserve networks hold a *sovereign account* on the reserve chain, a keyless account managed by the respective network governor. Thus, when reserve network A wants to send X amount of an asset to non-reserve network B, it locally transfers the assets to network's B sovereign account and, in the same atomic action, it sends an XCM message to network B with instructions to mint X amount of a derivative form of the transferred asset. On the other way around, if non-reserve network B wants to send X amount of an asset to reserve network A, then the steps are: network B burns the derived form of the asset locally and sends an XCM message to network A, with instructions to transfer the assets from network B's sovereign account to network's A destination account. Even if the non-reserve network mints derived tokens in excess (or doesn't burn tokens when transferring), these tokens will have no real value because they are not backed one-to-one in the reserve chain The associated fees for executing transfers are typically deducted from the transferred amount, so the recipient receives the intended amount minus the fees. ### Remote Execution {: #remote-execution } The native interoperability XCM provides allows a network to send a message to another triggering some action. For example, If the destination chain is EVM-compatible, network A can call a smart contract deployed on network B. As mentioned in the [fees section](#fees), to get any on-chain request executed it is necessary to cover its associated fees. On XCM, remote execution can be bought with two steps: 1. Reserve some assets using the `WithdrawAsset` XCM instruction, which takes funds from the call origin and puts them in a holding register 2. Pay for the on-chain execution, using the `BuyExecution` XCM instruction, which uses the previously withdrawn assets !!! note When a network sends an XCM message, its default source on the receiving end is the origin network's Sovereign account. The sender network can add an XCM instruction called `DescendOrigin` to the message, changing the origin account to match the signing user's account, ensuring execution occurs on behalf of the same entity initiating the XCM message on the source chain, and avoiding a potentially unsafe scenario. Finally, the execution takes place on the destination chain, calling a smart contract or any other transaction using the XCM instruction called `Transact`. The general flow for remote execution is represented in the following diagram: ![Remote Execution Flow](/images/learn/framework/xcm/xcm-1.webp) ## Establishing Cross-Chain Communication {: #channel-registration } Before two chains can communicate, a messaging channel must be established. Channels are unidirectional, which means that separate channels are needed to send messages from chain A to chain B and B to A. For chain A to communicate with chain B, chain A must send an open channel transaction to the relay chain requesting a channel be opened with chain B. Chain B must then accept the request by sending a corresponding XCM message to the relay chain. Only when both chains agree is the channel opened in the next epoch. The same process is required to establish a channel from chain B to chain A. It is important to note that a channel between a network and the relay chain is automatically opened upon network registration and onboarding. ![XCM Channel Registration Overview](/images/learn/framework/xcm/xcm-2.webp) Once the channel is established, cross-chain messages can be sent between networks. For asset transfers, assets will also need to be registered before being transferred. !!! note XCM is a versioned, ever-evolving language. When two communicating networks use different XCM versions, they must use the latest version supported by the less upgraded side. To find out the latest XCM version a network can work with, other networks can query it and subscribe for updates whenever this changes. ## Message Destinations {: #message-destinations } To compose meaningful messages in a multichain environment it is necessary to have a precise yet abstract way of referencing resources located in different consensus systems. A concept called *multilocation* is used to serve this purpose and target a specific chain or any of its inner elements, such as an account, an asset, or a smart contract. XCM's destination elements are organized in a hierarchical architecture, where elements are contained within other components. For example, a smart contract is an element contained within a network, and the same can be said for an account or an ERC20 asset. Networks are contained by the relay chain, which plays a crucial role in the cross-chain messaging process, relaying messages from one network to another. Multilocations are not a universal resource locator. They refer to elements from the sender's perspective and are composed of two components: `parents` and `interior`. Parents is a property that indicates if the route must "move up" in the hierarchy, i.e., from a network to the relay chain. Interior is a list of junctions that define how to locate the destination. Here are some examples of multilocations: - **Network A references a smart contract in network B** - from the point of view of network A, to reach a smart contract in network B it is necessary to move up in the hierarchy (to the relay chain) and then descend to network B to, once there, reference the smart contract's address. The multilocation is therefore defined with a `parents` value set to `1`, which moves up, and two junctions, one defining which network should receive the message, and the other defining the H160 address of the smart contract that will be called ![Smart Contract Multilocation Example](/images/learn/framework/xcm/xcm-3.webp) - **Network A references an account in the relay chain** - from the point of view of network A, to reference an account in the relay chain, it is necessary to move up and then reference the account. The multilocation is defined with a `parents` value set to `1`, which moves up to the relay chain, and one junction that references the substrate type destination address ![Account Multilocation Example](/images/learn/framework/xcm/xcm-4.webp) --- END CONTENT --- Doc-Content: https://docs.tanssi.network/learn/tanssi/account-types/ --- BEGIN CONTENT --- --- title: Accounts in the Tanssi Protocol description: Overview of the cryptographic keys essential for the Tanssi protocol, detailing the account types used and their general functions. icon: octicons-key-24 categories: Basics --- # Accounts in the Tanssi Protocol ## Introduction {: #introduction } Blockchain technology relies on [public-private](https://en.wikipedia.org/wiki/Public-key_cryptography){target=\_blank} key cryptography for secure asset ownership and transaction verification. Private keys authorize transactions, while public keys serve as addresses for verification. Due to the Tanssi protocol's hybrid [Substrate](/learn/framework/overview/#substrate-framework){target=\_blank} and Ethereum nature, understanding the different account types is crucial for users and operators. ## Account Types in the Tanssi Protocol {: #key-types-in-tanssi-protocol } | **Account Type** | **Underlying Algorithm** | **Primary Use in Tanssi** | | --- | --- | --- | | [Sr25519](https://wiki.polkadot.network/learn/learn-cryptography/){target=_blank} | Schnorr signatures on the Ristretto group | Default signature scheme for Substrate-based transactions and operator identity. | | [Ed25519](https://wiki.polkadot.network/learn/learn-cryptography/){target=_blank} | EdDSA using Curve25519 | Used for specific consensus roles (e.g., block production, finality) within the Substrate framework. | | [ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm){target=_blank} | Elliptic Curve Digital Signature Algorithm | Receiving rewards through the Ethereum-based Symbiotic protocol for operators. | ## Identity and Operations { : #identity-and-operations } Tanssi, built with the Substrate framework, utilizes distinct cryptographic schemes for different functions, primarily _Sr25519_ and _Ed25519_. These account types are crucial for interacting with the protocol's Substrate components by signing transactions. **Sr25519 (Schnorrkel/Ristretto x25519)** - is the primary account type used for most user-facing operations within Tanssi. Its strengths lie in security and efficiency. **Sr25519 accounts serve as your on-chain identity, used for holding tokens, participating in governance, paying transaction fees, and other general interactions with the network.** When you create a wallet to interact with Tanssi as a regular user, you will create and use an Sr25519 account. **Ed25519 (Edwards-curve Digital Signature Algorithm)** - while Sr25519 handles general identity and transactions, Ed25519 is specifically leveraged for its high performance in cryptographic signing, making it ideal for consensus-related operations. **Within Tanssi, Ed25519 accounts are used by node operators for critical consensus mechanisms, such as block production and finality.** Regular users will typically not create or directly use an Ed25519 account. However, these accounts are fundamental for the security and operation of the network, managed by those running nodes. Node operators on Tanssi require a Substrate account to record their activities, including operators who secure the network and sequencers who produce blocks. This account also tracks rewards, with session keys mapped to it for enhanced security. ## Security and Rewards on Ethereum { : #security-and-rewards-on-ethereum } The Elliptic Curve Digital Signature Algorithm (ECDSA) is fundamental to Ethereum and is used by Tanssi to integrate with the Ethereum network via Symbiotic. This partnership leverages Ethereum's security for Tanssi-powered networks. Tanssi operators need an ECDSA account to receive rewards distributed on Ethereum, likely through the Symbiotic protocol. The necessity of both Substrate and ECDSA accounts highlights Tanssi's hybrid design, where operations are Substrate-based, and security and rewards are linked to Ethereum. ## Account Mappings in Tanssi { : #account-mappings-in-tanssi} ### Internal Key Binding (_Sr25519_ and _Ed25519_) Within Tanssi's Substrate-based protocol, an operator’s primary _Sr25519_ identity links to specific _Ed25519_ keys used for consensus tasks (like block production). Operators create this binding with an on-chain transaction. This transaction maps their internal public keys ("session keys") with the stash account. This on-chain registration ensures the network correctly attributes all actions from the session keys to the operator's primary identity. ### Cross-Ecosystem Reward Mapping (_Sr25519_ and _ECDSA_) For rewards on Ethereum (e.g., via [Symbiotic](/learn/tanssi/external-security-providers/symbiotic/){target=\_blank}), an operator's Tanssi _Sr25519_ identity maps to an Ethereum _ECDSA_ address. Operators inform both accounts, which are then linked through the Tanssi middleware. This trusted link ensures that rewards from the operator's node work on the Tanssi network are routed to the operator's designated Ethereum account. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/learn/tanssi/external-security-providers/symbiotic/ --- BEGIN CONTENT --- --- title: Ethereum with Symbiotic description: Tanssi's design allows developers to choose and connect to the Symbiotic restaking protocol, benefiting from Ethereum-grade security right from the start. icon: octicons-shield-check-24 categories: Basics --- # Ethereum with Symbiotic {: #ethereum-symbiotic } ## Introduction {: #introduction } The Tanssi protocol takes care of critical infrastructural components, making it easy for developers to launch their networks in a few minutes. In addition to block production, data retrievability, and integrations with essential tools such as wallets, RPC endpoints, block explorers, and others, another major task to tackle is providing security to the network. Tanssi is designed to offer developers a shared security model, alleviating them from having to source enough economic security or negotiating with operators to run nodes opting-in for their networks. By deploying networks through Tanssi, and by choosing [Symbiotic](https://symbiotic.fi/){target=\_blank} as a security provider, developers benefit from Ethereum-grade security, tapping into billions of dollars in shared security from staked ETH. The following sections describe how the Symbiotic protocol works and how Tanssi networks can leverage it as their consensus mechanism. ## Ethereum-Grade Security with Symbiotic {: #symbiotic } [Symbiotic](https://symbiotic.fi/){target=\_blank} is a shared security protocol designed to be permissionless, multi-asset, and network-agnostic. It fosters capital efficiency by allowing users to extend the functionality of their staked assets to secure other networks while providing additional utility. The protocol provides a coordination layer for its main components and participants, aligning incentives among parties while minimizing execution layer risks by deploying non-upgradeable core contracts on Ethereum. The following diagram resumes all the components and actors participating in the protocol: ```mermaid flowchart TD %% Vaults subgraph subgraph Ethereum["Ethereum/Symbiotic"] slash[/Slashing Events/] Restakers -- Deposit Assets --> Vaults manager["Vault managers"] -- Manage --> Vaults Resolvers -- Decide On --> slash slash -- Executes On --> Vaults end %% Operators subgraph subgraph Operators direction BT operators["Operators (Validators)"] node_operators["Node Operators"] node_operators -- Run --> operators end %% Networks subgraph subgraph Networks direction BT developers["Developers"] networks["Decentralized Networks"] developers -- Launch --> networks end Vaults <--> Tanssi Tanssi <--> Operators Tanssi <--> Networks ``` Symbiotic's flexible design allows every party to decide on setups that best fit their use cases. For example, vaults can choose what forms of collateral they accept, operators can determine which networks they want to provide services to, and decentralized networks can customize their use case and define the level of security (which collaterals are accepted, for example) they need. The following sections describe the protocol's main components. ### Vaults {: #vaults } [Vaults](https://docs.symbiotic.fi/modules/vault/introduction){target=\_blank} are the Symbiotic protocol's economic backbone. They manage liquidity and deposits from restakers, connect operators and networks, and set up delegation strategies. Each vault is bound to a specific token that satisfies the [IERC20](https://github.com/ethereum/ercs/blob/master/ERCS/erc-20.md){target=\_blank} interface and is accepted as collateral. Internally, the funds within the vault are represented as shares, which provide a mechanism for tracking ownership and distributing rewards. However, the reward token may differ from the collateral token. A vault comprises three key modules, each serving a distinct function: the slasher, the delegator, and the accounting module. The implementation of these modules can vary depending on the vault manager's decisions. - **Slasher module** - implements the [slashing](#slashing-process) logic, which penalizes bad actors - **Delegator module** - defines how funds are delegated across operators and networks. Several [strategies](https://docs.symbiotic.fi/modules/vault/delegator){target=\_blank} are available, allowing the vault manager to select which operators and networks they want to work with - **Accounting module** - handles the vault's financial operations, including processing user deposits, managing withdrawal requests, tracking active balances and total supply, and implementing epoch-based accounting for withdrawals and slashing events. The accounting module's standard implementation is [ERC-4626](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/){target=\_blank}, which provides a vault with a shares system included Since the operators get delegated stake from the vault and could potentially get slashed, they must be approved by the vault managers beforehand. On a similar note, vault managers analyze and authorize each network the vault will secure, considering, for example, the rewards the network offers. Vault managers also designate [resolvers](https://docs.symbiotic.fi/modules/counterparties/resolvers){target=\_blank}, responsible for approving or vetoing [slashing events](https://docs.symbiotic.fi/modules/vault/slasher){target=\_blank} caused by operators on networks with [veto-slashing](https://docs.symbiotic.fi/modules/vault/slasher#veto-slashing){target=\_blank} support, like the Tanssi Network. ### Operators {: #operators } [Node operators](/node-operators/){target=\_blank} are entities or individuals responsible for running the [nodes (also known as operators or validators)](https://docs.symbiotic.fi/modules/counterparties/operators){target=\_blank}, which are the computational components validating the networks' transactions. They are responsible for the nodes' configuration, hardware setup, uptime, and performance. Node operators opt-in to provide services to networks, which must accept their request. Also, they opt-in to provide services in vaults, which must accept their request. Once an operator has been accepted by a vault and a network connected to that vault, the node can start providing validation services to that network, receiving rewards in exchange. ### Networks {: #networks } [Networks](https://docs.symbiotic.fi/modules/counterparties/networks){target=\_blank} are the actively validated services or networks. These application-specific blockchains can be a use case from a wide range of industries, such as Gaming, Defi, RWAs, and others, and are the platforms that, through dApps, the end users interact with. Since operators opt-in to provide services to networks and the vault managers must accept the networks, the developers are responsible for defining, controlling, and adapting their methodology for onboarding, rewarding, and slashing operators. !!! note Networks deployed through Tanssi don't need to work on the relation with vaults and operators since the Tanssi protocol deals with those complexities. ## Tanssi with Symbiotic {: #tanssi-symbiotic } Developers launching networks through Tanssi benefit from [block production services](/learn/tanssi/network-services/block-production/){target=\_blank}, data retrievability as a service, and the shared security model derived from every vault opting-in to support the Tanssi protocol. This eliminates the hurdle of dealing with infrastructural and security components developers would need to take on otherwise. Vault managers running vaults can apply to offer the restaked collaterals as economic security for the Tanssi Network. Since Tanssi networks run in a sandbox-like environment, and the Tanssi protocol manages all the networks-related responsibilities, vault managers only need to analyze and opt-in to the Tanssi protocol, regardless of the quality and the quantity of networks that are running through the Tanssi protocol at any given moment. Operators opting-in to provide services to the Tanssi protocol (provided that they participate in a vault that supports the Tanssi protocol) have the benefit of running the same setup to provide block production and validation services to the Tanssi Network and, consequently, to every network deployed through Tanssi. This unique architecture facilitates all the tasks related to running and maintaining the operators since there are no changes in the setup when a new Tanssi network is launched or decommissioned. !!! note The Tanssi protocol effectively abstracts the details of the active set of networks away from vault managers and operators. Networks particularities don't require any additional setup from operators nor pose risks to vault assets. All things combined shape a functional and elegant ecosystem where developers can focus on creating and innovating. Tanssi handles the infrastructural components, guaranteeing liveness and performance, and Symbiotic provides the economic safeguards to ensure the validity of the operations. ```mermaid flowchart LR subgraph Symbiotic direction LR Operators Vaults end Symbiotic -- Validates/Secures --> tanssi["Tanssi Network"] tanssi -- Block Production Services--> Networks tanssi -- Security--> Networks tanssi -- Data Retrievability--> Networks class Symbiotic custom-container ``` ### Tanssi-Ethereum Communication {: #tanssi-ethereum-communication } It is important to learn how Tanssi and Ethereum exchange data to understand the mechanics of the protocol. They connect through a two-way bridge that lets them communicate with each other. Each protocol has a specific job in making cross-chain operations possible. There are three key components between Symbiotic and Tanssi: ```mermaid flowchart LR Tanssi["Tanssi"] <--> Relayer Relayer <--> Gateway Gateway["Gateway"] <--> Middleware Middleware <--> Symbiotic["Symbiotic"] class Tanssi tanssiNode; class Middleware middlewareNode; class Gateway gatewayNode; class Symbiotic symbioticNode; class Relayer relayerNode; ``` - **`Relayer`** - is the software that continuously monitors both blockchains and transmits messages. Enabling reliable bidirectional communication between Tanssi and Ethereum, serving as the connection layer that ensures messages are correctly delivered across networks - **`Gateway`** - operates on the Ethereum side of the bridge and serves three essential functions. It receives, verifies, and routes incoming messages from Tanssi to ensure they are correctly processed. The contract accepts outgoing messages destined for the Tanssi network, preparing them for relay. Finally, it handles higher-level application functionalities, most notably token transfers between the two networks, providing a secure interface for cross-chain asset movement - **`Middleware`** - is Tanssi's implementation for handling network events and operations. It is the critical link between the `Gateway` and Tanssi's core protocol The `Middleware` plays a central role in network coordination between Tanssi and Symbiotic. It distributes rewards to operators and vaults based on their network security and performance contributions. The contract sorts operators by stake to create a merit-based ranking system for their selection and transmits the list of sorted operator keys to Tanssi for assignment. Additionally, it facilitates operator registration processes and handles the reward and slashing protocols that maintain network incentive alignment. #### From Ethereum to Tanssi {: #from-ethereum-tanssi } The `Middleware` transmits operator set information to Tanssi for session assignment through the bridge. It sends details about active operators for each epoch, ordering them by their total stake aggregated across vaults. Tanssi then uses this information to assign operators for upcoming sessions, ensuring that the most economically aligned ones secure the network. This mechanism creates a stake-weighted operator selection process where economic security on Ethereum translates to operational security on Tanssi. #### From Tanssi to Ethereum {: #from-tanssi-ethereum } Tanssi sends operational data back to Ethereum through the same communication channel. This message includes reward information that enables proper distribution to stakeholders based on network performance. The network also transmits slashing event data when operators fail to perform correctly or violate protocol rules, allowing the protocol to apply penalties. Tanssi can also request new tokens to be created on Ethereum and register tokens, making managing assets between both networks easy. ### Rewards {: #rewards } Well-behaved operators and restakers are rewarded for their participation with TANSSI tokens. The reward process consists of two main phases: [Reward Distribution Phase](#reward-distribution-phase) and [Reward Claiming Phase](#reward-claiming-phase). #### Reward Distribution Phase {: #reward-distribution-phase } The reward distribution phase calculates and allocates rewards through five key steps involving operators, restakers, and smart contracts. The steps are: 1. **Reward Calculation** - Tanssi calculates rewards based on the activity of operators and stakers and then creates a [Merkle root](https://en.wikipedia.org/wiki/Merkle_tree){target=\_blank}. This Merkle root is a cryptographic fingerprint that summarizes the reward allocations, indicating who receives what. Stakers are rewarded according to their stake in each vault 2. **Reward Data Sent via XCM** - reward allocation data is sent using [XCM](https://wiki.polkadot.network/learn/learn-xcm/){target=\_blank} (Cross-Consensus Messaging), a standardized protocol for blockchain communication. [Snowbridge](https://docs.snowbridge.network/){target=\_blank} acts as a trustless bridge between Tanssi and Ethereum 3. **Ethereum Message Reception** - once the message is relayed to the `Gateway` contract, this contract serves as Tanssi's authorized entry point on Ethereum for the Snowbridge bridge 4. **Message Processing and Validation** - the `Gateway` forwards the data to the [`Middleware`](https://github.com/moondance-labs/tanssi-symbiotic/blob/main/src/contracts/middleware/Middleware.sol){target=\_blank}, which is responsible for various tasks, including passing the information to the `OperatorReward` contract 5. **Reward Storage and Distribution** - this is the final destination for the data. The [`OperatorRewards`](https://github.com/moondance-labs/tanssi-symbiotic/blob/main/src/contracts/rewarder/ODefaultOperatorRewards.sol){target=\_blank} contract stores the Merkle tree of the reward allocations and handles the transfer of reward tokens when a claim is made ```mermaid %%{init: {'sequence': {'mirrorActors': false}}}%% sequenceDiagram participant Tanssi Network participant Snowbridge (XCM) participant Gateway participant Middleware participant OperatorRewards Tanssi Network->>Tanssi Network: 1. Calculate rewards and generate Merkle root Tanssi Network->>Snowbridge (XCM): 2. Reward data sent via XCM (Merkle root + data) Snowbridge (XCM)->>Gateway: 3. Relay message and sent to Ethereum Gateway ->>Middleware: 4. Message processing and validation Middleware->>OperatorRewards: 5. Reward storage and distribution ``` #### Reward Claiming Phase {: #reward-claiming-phase } In the reward-claiming phase, operators and stakers can claim rewards based on their participation in the network. Tanssi determines the share distribution for operators and stakers, currently setting it at 20% for operators and 80% for stakers. 1. **Operator Reward Claim** - operators can claim their share by calling the `OperatorRewards` contract by using a cryptographic receipt that verifies their entitlement 2. **Token Release** - the operator call triggers the token release, and the `OperatorRewards` sends the established amount to the operator 3. **Token Distribution to Stakers** - the remaining rewards are forwarded to the `StakerRewards` contract for further claiming of the staker 4. **Staker Allocation** - the remaining 80% of the rewards are automatically directed to the [`StakerRewards`](https://github.com/moondance-labs/tanssi-symbiotic/blob/main/src/contracts/rewarder/ODefaultStakerRewards.sol){target=\_blank} contract, where stakers can claim rewards proportional to their stake in the vaults ```mermaid %%{init: {'sequence': {'mirrorActors': false}}}%% sequenceDiagram participant Operator participant OperatorRewards participant StakerRewards participant Stakers Operator->>OperatorRewards: 1. Operator reward claim OperatorRewards->>Operator: 2. Release rewards to the operator OperatorRewards->>StakerRewards: 3. Forward the remainder to StakerRewards Stakers->>StakerRewards: 4. Stakers claim individual rewards ``` ### Slashing {: #slashing } The Tanssi protocol implements slashing to penalize operators for misbehavior. When a slashing event is triggered, the authorities designated as resolvers by the vault managers can either accept or revert this action. The following actions can trigger slashing events: - Producing invalid blocks (e.g., blocks that include invalid transactions) - Invalid validation (e.g., double-signing or breaking protocol rules) - Downtime or unavailability - Consensus violations !!!note Slashing events can only be triggered by operators' misbehavior within the Tanssi Network. Even if Tanssi networks are faulty or malicious, they operate in a sandboxed environment and cannot cause slashing. #### Slashing Process {: #slashing-process } The slashing process follows a path similar to that of rewards. When an operator misbehaves, the Tanssi Network sends a slashing request message to the trustless bridge (Snowbridge). The message passes through the `Gateway` and into the `Middleware` where the slashing method gets called. The slashing method receives a unique identifier for the operator's identity, the severity of the slash as a percentage of the operator's assigned stake in each vault, and the time context within which the offense occurred. The slashing process consists of the following steps: 1. **Slash Reported** - Tanssi sends the slash request to the `Middleware` with the parameters `operatorKey`, `percentage`, and `epoch` 2. **Operator Validation** - the `Middleware` validates the operator's identity and checks if the operator is subject to slashing 3. **Retrieve Active Vaults** - the `Middleware` iterates through all active vaults during the offense epoch, skipping any inactive vaults 4. **Retrieve Operator Stake** - for each active vault, the `Middleware` retrieves the stake of the misbehaving operator 5. **Calculate Slash Amount** - the `Middleware` calculates the slashing amount by applying the slashed percentage to the operator's stake in each vault 6. **Slashing** - depending on the vault's slashing implementation, there are two possible routes - **Instant Slashing** - if the vault uses instant slashing, the stake is immediately reduced - **Veto Slashing** - if the vault uses veto slashing, the `Middleware` requests the slashing from a resolver. A time-limited veto window is created (e.g., 7 days) The slashing is canceled if the resolver vetoes the request within the time window. Otherwise, the slashing penalty is executed if no veto occurs within the time window This process ensures that each vault's slashing is handled independently, preventing cross-contamination, and offers both instant and time-delayed slashing with dispute resolution mechanisms. ```mermaid %%{init: {'sequence': {'mirrorActors': false}}}%% sequenceDiagram participant Network participant Middleware participant Vault participant Slasher Network->>Middleware: 1. Slash reported Middleware->>Middleware: 2. Operator validation loop Each Active Vault Middleware->>Vault: 3. Retrieve operator stake Vault-->>Middleware: 4. Retrieve vault stake Middleware->>Middleware: 5. Calculate slash amount alt Instant Slasher Middleware->>Slasher: 6.1 Slash else Veto Slasher Middleware->>Slasher: 6.2 Request slash opt If Not Vetoed Slasher->>Slasher: 6.2 Execute slash end end end ``` #### Burner {: #burner } The `Burner` contract is an extension responsible for handling actions that follow a [slashing event](#slashing-process), notably the burning of slashed collateral. Once a slash is executed, the `Slasher` contract calls the `Burner` to carry out these post-slashing tasks. Within the protocol, the `Burner` contract plays a crucial role in deciding what happens after slashing. While there are different ways to implement the burning process, the recommended approach is to burn the slashed assets. When a slash is executed, the `Burner` contract's `onSlash` function is activated. This function kicks off the process of burning the slashed assets. The vault manager chooses the specific implementation of the burning process during the vault's initialization phase, and once set, the vault manager cannot modify it. The exact design of the `Burner` contract may differ depending on the type of collateral asset involved. Below are some potential implementation options: - **Burning Tokens** - if the slashed collateral is a regular ERC-20 token, the `Burner` destroys those tokens, permanently removing them from circulation - **Unwrapping and Burning** - if the slashed tokens represent something like staked assets (e.g., liquid staking tokens) or liquidity provider (LP) tokens from a decentralized exchange (DEX), the `Burner` might convert them back into their original form before burning them - **Cross-Chain Operations** - if the tokens are tied to assets on another blockchain, the `Burner` could unwrap them on Ethereum and trigger the burn process on the original network - **Alternative Handling** - sometimes, burning isn't the best option. Instead, the `Burner` might redistribute the slashed assets to other operators, compensate affected users, or lock them in liquidity pools—whatever the system is designed to do Burning slashed collateral is important because it penalizes misbehaving operators and reduces the total supply of tokens, which can have deflationary effects. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/learn/tanssi/network-features/staking/ --- BEGIN CONTENT --- --- title: Staking for Block Production description: Learn how Tanssi implements a novel Staking mechanism to provide liveness via a decentralized and trustless set of sequencers to all Tanssi-powered networks. icon: material-hand-coin-outline categories: Basics --- # Tanssi Staking for Block Production {: #tanssi-staking } ## Introduction {: #introduction } One of Tanssi's core propositions is to simplify the infrastructure complexity for networks. A significant component is bootstrapping a decentralized set of sequencers, which Tanssi offers through its unique architecture and staking mechanics. Tanssi staking mechanics guarantee that the sequencers for Tanssi-powered networks are selected through a trustless and decentralized mechanism. They also incentivize the community to delegate to top-performing or engaged sequencers. This page covers the fundamental concepts of Tanssi's staking mechanics and how it secures a decentralized block production set that drives network liveness for Tanssi networks. ## Core Concepts {: #core-concepts } Tanssi's staking module mechanics were inspired by the concept of liquidity pool tokens (LP tokens) in traditional Automated-Market-Makers (AMMs) like Uniswap V2. Each sequencer has four liquidity pools through which delegators move as they perform different staking operations. In short, each liquidity pool represents a different state throughout the staking process: joining, staking through manual rewards, staking through auto-compound rewards, and leaving. Nevertheless, one core difference is that LP tokens in common AMMs are transferable while staking shares tokens are not. A delegator has four simple transactions to go through the different states (liquidity pools): delegate (for manual or auto-compound rewards), undelegate, swap, and execute pending operations. For example, users who want to stake through either rewards pool can use the delegate call and join the Joining Pool immediately. After a delay, users (or anyone else) can execute the pending operation and enter the initially set rewards pool. Once there, users can swap between reward pools as often as they like. Lastly, users in a rewards pool can use the undelegate call to go into the Leaving Pool and unstake their tokens (or anyone else's) executing the pending operation after a given delay. Liquidity pools have a set of shares that can be considered LP tokens in traditional AMMs. When users join a new liquidity pool, they are given several shares (LP tokens) that depend on the pool type, the number of tokens they staked, the total number of shares, and the total number of tokens staked in that pool. Rewards are assigned to a sequencer's Manual or Auto-Compound Reward Pools when Tanssi attests that the specific block production slot that sequencer was assigned to has been fulfilled, and the block was produced successfully. All rewards (for all pools) are stored in a protocol-owned account. Nevertheless, the protocol internally keeps track of the actual native tokens held by each pool. The core difference between staking through the Manual or Auto-Compound Rewards Pools is how rewards are distributed. In the Manual Rewards Pool, users have to claim any staking rewards they've accumulated manually. In contrast, in the Auto-Compound Rewards Pool, the rewards are automatically re-staked at each Tanssi block, where the protocol announces the sequencer for each block production assignment. The delegate and undelegate operations need to be sent by the delegator itself. They signal the intent of the action to be taken and ask the protocol to perform the necessary checks to allow the delegator to delegate or undelegate. Consequently, these actions can be executed only after a certain number of sessions, but anyone in the network can perform this second operation through the execute pending operation transaction. The following diagram summarizes the high-level flow of a delegator delegating and undelegating tokens to a sequencer. User actions are highlighted in cyan, while different pools are highlighted in coral. ![High-level overview of Tanssi Staking mechanics](/images/learn/tanssi/staking/staking-1.webp) ## Staking Parameters {: #staking-parameters } === "Tanssi MainNet" | Variable | Value | |:-------------:|:---------------------------------------------------------------------------------------------------------------------:| | Joining Delay | {{ networks.mainnet.staking.joining_delay_blocks }} blocks ({{ networks.mainnet.staking.joining_delay_hours }} hours) | | Leaving Delay | {{ networks.mainnet.staking.leaving_delay_blocks }} blocks ({{ networks.mainnet.staking.leaving_delay_hours }} hours) | === "Dancelight TestNet" | Variable | Value | |:-------------:|:---------------------------------------------------------------------------------------------------------------------------:| | Joining Delay | {{ networks.dancelight.staking.joining_delay_blocks }} blocks ({{ networks.dancelight.staking.joining_delay_hours }} hours) | | Leaving Delay | {{ networks.dancelight.staking.leaving_delay_blocks }} blocks ({{ networks.dancelight.staking.leaving_delay_hours }} hours) | ## Staking Pools {: #staking-pools} The following section goes through each of the liquidity pools that represent a step throughout the staking process. ### Joining Pool {: $joining-pool} When a user first delegates to start the staking process, it must state what staking rewards mechanism it wants: manual or auto-compound rewards (each being a separate pool). Once the joining transaction is executed, the user automatically enters the Joining Pool and is given shares of that pool directly correlated to the number of tokens being staked. This pool offers stability to the current set of sequencers by providing a delay between a delegator staking and receiving rewards. The delay is set to at least one entire session. As a practical example, Alice starts the staking process targeting the Manual Rewards Pool and enters the Joining Pool halfway through a session; she must wait until the end of the next session to execute her pending operation to start receiving staking rewards. Joining Pools for each sequencer have a one-to-one ratio of shares per token staked. Therefore, if Alice is staking 100 tokens, she will receive 100 shares (LP tokens) of the Joining Pool she entered. When her delegate pending operation is executed, the protocol consumes her shares of the Joining Pool in favor of native protocol tokens, which are immediately swapped to shares in either the Manual Rewards or Auto-Compound Rewards Pools. The following diagrams assumes a user is staking into the Manual Rewards Pool. ![High-level overview of the Joining Pool when Staking](/images/learn/tanssi/staking/staking-2.webp) ### Manual Rewards Pool {: #manual-rewards-pool} When a user joins the Manual Rewards Pool, the protocol destroys all Joining Pool shares they own in favor of the native protocol token. Next, in the same block, the protocol computes the amount of Manual Pool shares that can be minted with this amount based on the share's price. The price is calculated based on current pool conditions, that is, the number of native tokens and shares that exist: ```mathematica SharePrice [Tokens/Shares] = NumberOfTokensInPool / NumberOfSharesInPool ``` Shares don't have decimals. Consequently, any remaining native tokens when acquiring the pool's shares are refunded to the user. The share price is not impacted by users joining the pool, as the ratio is maintained. Once the user has Manual Rewards Pool shares, they earn staking rewards (that is, in the same session) that need to be claimed manually by the user delegating. In contrast to the Auto-Compound Rewards Pool, where reward distribution is done automatically to the specific pool, the distribution for the Manual Rewards Pools operates through a counter checkpoint rewards mechanism. This mechanism tracks the historical native token per share distribution rate assigned to you by the protocol for that particular Manual Reward Pool at a specific point in time. When Tanssi attests that a block was produced by a given sequencer, new rewards are assigned to that Manual Rewards Pool for users to claim, and the rewards counter increases. Therefore, rewards are reflected as the ratio of native tokens per share you receive as staking rewards, which is the difference between the current pool's rewards counter and your original rewards counter checkpoint. Consequently, the native tokens per share rewards counter plays a vital role in the protocol's calculation of the tokens the user is due when they claim their rewards. Once the rewards are calculated, the protocol sends them from the protocol-owned account to the user. Simultaneously, the user's rewards counter checkpoint is reset to the current one set by the pool current counter value. This reset is necessary to ensure the user's new rewards counter aligns and that the due rewards are zero. Similarly, when a user stakes or unstakes tokens, rewards are automatically claimed, and the user's checkpoint rewards counter is reset. Adding or removing a stake means that reward conditions for that specific amount differ from what the protocol has in storage. Consequently, the rewards counter checkpoint must be synced with the pool's rewards counter to ensure no imbalances. ![High-level overview of the Manual Rewards Pool when Staking](/images/learn/tanssi/staking/staking-3.webp) ### Auto-Compound Rewards Pool {: #autocompounded-rewards-pool} When a user joins the Auto-Compound Rewards Pool, the protocol destroys all Joining Pool shares they own in favor of the native protocol token. Next, in the same block, the protocol computes the amount of Auto-Compound shares that can be minted with this amount based on the share's price. The price is calculated based on current pool conditions, that is, the amount of native tokens and shares that exist: ```mathematica SharePrice [Tokens/Shares] = NumberOfTokensInPool / NumberOfSharesInPool ``` Shares don't have decimals. Consequently, any remaining native tokens when acquiring the pool's shares are refunded to the user. The share price is not impacted by users joining the pool, as the ratio is maintained. Once the user has Auto-Compound Rewards Pool shares, they earn staking rewards (that is, in the same session). In contrast to the Manual Rewards Pool, native token rewards in the Auto-Compound Rewards Pool are automatically assigned to the pool at each Tanssi block where the protocol attests the sequencer for each block production assignment in any Tanssi-powered network. Consequently, as the number of native tokens held in the pool increases but the number of shares stays constant, the share price increases (according to the formula). Therefore, if the users redeem their shares for native tokens, they will receive more native tokens per share than when they joined the pool. ![High-level overview of the Auto-Compound Rewards Pool when Staking](/images/learn/tanssi/staking/staking-4.webp) Native token rewards are automatically assigned as new stake into the Auto-Compound Rewards Pool, hence the auto-compounding nature of this specific staking pool mechanism. Nevertheless, when auto-compound staking rewards are assigned, they are not held in the user's reserved balance, as the protocol-owned account still has them. The increase in the delegator's stake is indirectly represented by the share price increase. However, in specific scenarios, a user might want to let the protocol know that they want that balance to be represented in their state as reserved balance, for example, for governance purposes. Consequently, the protocol offers a specific transaction any user can submit to update the reserve balance of any delegate. This call moves the auto-compound rewards for the specified user from the protocol-owned account to their reserve balance. This is also automatically executed by the protocol when a user removes liquidity from a Auto-Compound Rewards Pool. ### Leaving Pool {: #leaving-pool} When a user decides to exit their staking positions from a Manual or Auto-Compound Reward Pool, they have the power to initiate an undelegation. This process, similar to when they initially entered the Joining Pool, is a two-step journey. The user signs an intent to remove a specific delegation and patiently waits for at least one entire session before the operation can be executed by anyone. Upon executing the leaving transaction intent, the protocol exchanges shares of the specified pool for native tokens at the current pool price. For the Manual Rewards Pool, any unclaimed rewards are assigned to the user. Simultaneously, the protocol purchases Leaving Pool shares in a one-to-one ratio for the native tokens the user just received. This ensures that the user joins the Leaving Pool, acquiring shares that correspond to the number of native tokens they desire to unstake. After an entire session passes, any user can execute the pending operation. Then, the protocol swaps Leaving Pool shares for native protocol tokens at a one-to-one ratio. The primary purpose of the Leaving Pool is to provide a buffer for users leaving the staking mechanics. This buffer allows the implementation of slashing mechanisms to deter bad behavior. Slashing has not been implemented in Tanssi but could be implemented in the future. The following diagrams assumes a user is unstaking from the Manual Rewards Pool. ![High-level overview of the Leaving Pool when Staking](/images/learn/tanssi/staking/staking-5.webp) ### Swapping Between Rewards Pools {: #swap-rewards-pool} Tanssi's staking module allows users to swap their stake from one type of reward pool to another. Users can use this functionality to move partial or full amounts of the staked tokens in a specific pool. The main benefit is that users don't have to go through the Leaving Pool and the Joining Pool again to move their stake. First, all pending Manual Rewards Pool rewards are claimed at a protocol level, as liquidity is either added or removed. Therefore, the checkpoint rewards counter needs to be synced with the pool. Next, shares from the original pool are consumed and exchanged in favor of native protocol tokens at the current pool price. Then, shares of the new pool are attained at that pool's price. Lastly, any dust tokens remaining are automatically exchanged in favor of Leaving Pool shares. Note that all of the above is executed in the same block, and users don't have to wait for delays to earn rewards in the new pool. The dust in the Leaving Pool can be claimed after the required delays have passed. ![High-level overview of Swapping between Manual and Auto-Compounded Pools when Staking](/images/learn/tanssi/staking/staking-6.webp) --- END CONTENT --- Doc-Content: https://docs.tanssi.network/learn/tanssi/network-services/block-production/ --- BEGIN CONTENT --- --- title: Block Production Services description: Tanssi abstracts away infrastructure complexities, such as block production, allowing developers to launch decentralized networks with Ethereum-grade security. icon: octicons-container-24 categories: Basics --- # Block Production Services {: #block-production-services } ## Introduction {: #introduction } As presented in the [Overview](/learn/tanssi/overview/){target=\_blank} article, Tanssi is an infrastructure protocol that streamlines the deployment of decentralized networks with custom logic fitting a wide range of use cases, including DeFi, NFTs, Gaming, and any other use case development teams may want to address. Infrastructure poses a huge challenge for developers, requiring them to bootstrap sequencers, data preservers, and RPC endpoints, while also managing integrations, interoperability, and security. This demands valuable time and resources, diverting focus from what truly matters: delivering value to their users. Tanssi orchestrates resources, allowing developers to deploy decentralized networks (also known as actively validated services or AVSs) that are fully adaptable to any specific application or use case. In this analogy, the Tanssi network resembles [Kubernetes](https://kubernetes.io){target=\_blank} in its role as an orchestrator, managing resources to guarantee the liveness and performance of the networks. The protocol also tackles the security front by allowing networks to select and connect to external security providers (like [Symbiotic](/learn/tanssi/external-security-providers/symbiotic/){target=\_blank}), ensuring Ethereum-grade security right from the start. This article covers the necessary aspects to consider when building and deploying your own modular blockchain, along with the most relevant technical aspects of the Tanssi protocol. ## Block Production as a Service {: #block-production-as-a-service } The Tanssi protocol provides block production as a service, orchestrating a decentralized and trustless set of sequencers, ensuring the networks' liveness. To do so, the protocol bridges both ends: - **Node operators** - who run sequencers, offering their block production services to get rewards - **Developers** - who launch networks, which require sequencers The protocol assigns a subset of sequencers to provide services to each network, rotating them after a period of time. The sequencers can serve any Tanssi-powered network, regardless of the custom logic they implement. On the other hand, networks deployed through Tanssi can customize their runtime as much as they need to fit their use case and upgrade the logic at any moment in a forkless fashion without worrying about the sequencer's setup. The following diagram illustrates how Tanssi assigns two sequencers to each active network, selecting them from a decentralized set of sequencers. ```mermaid flowchart TB subgraph network1 [Network 1] s1bis[Sequencer 1] s2bis[Sequencer 2] end subgraph network2 [Network 2] s3bis[Sequencer 3] s4bis[Sequencer 4] end Tanssi[Tanssi Network
Orchestrator] subgraph sequencers [Sequencers Pool] direction LR s1[Sequencer 1] s2[Sequencer 2] s3[Sequencer 3] s4[Sequencer 4] sn[Sequencer N] s1 --- s2 --- s3 --- s4 --- sn end sequencers -- Managed by --> Tanssi Tanssi -- Assigns Sequencers --> network1 Tanssi -- Assigns Sequencers --> network2 ``` ### Sequencer Selection Process {: #sequencer-selection-process} At any given time, all Tanssi networks require a certain number of sequencers, depending on the number of active networks and the current block production configuration set in Tanssi. The configuration sets the maximum number of total sequencers in the set and the number of sequencers each network has to have assigned. === "Tanssi MainNet" | Variable | Value | |:--------------------------:|:----------------------------------------------------------------------------------:| | Max. # of Sequencers | {{ networks.mainnet.sequencers.configuration.max_block_producers }} | | # of Sequencers (Networks) | {{ networks.mainnet.sequencers.configuration.block_producer_per_container }} | === "Dancelight TestNet" | Variable | Value | |:--------------------------:|:----------------------------------------------------------------------------------:| | Max. # of Sequencers | {{ networks.dancelight.sequencers.configuration.max_block_producers }} | | # of Sequencers (Networks) | {{ networks.dancelight.sequencers.configuration.block_producer_per_container }} | Once the required number of sequencers for a given session is known, Tanssi uses two mechanisms to decide the set of sequencers distributed among all networks. The first mechanism is through the *Invunerables* module, which sets a list of fixed sequencers prioritized by the protocol and ensures block production stability in certain scenarios, such as TestNets. The second mechanism is through the [Tanssi staking module](/learn/tanssi/network-features/staking/){target=\_blank}. The module helps create a decentralized set of sequencers for all Tanssi networks by providing the protocol with a sorted list of sequencers by staked amount. Tanssi appends the sorted list by stake of sequencers to the invulnerable ones (if any), then takes from the list only the exact amount of sequencers needed, starting from the top, leaving out of the next session those sequencers that have less staked value, to finally begin the sequencer assignation process. ### Sequencers Assignment {: #block_producers-assignment } Once the sequencer set that will participate in the next session is known, Tanssi shuffles the list and assigns them to provide block production services to the active Tanssi networks. The assignment algorithm will start distributing the sequencers serving the networks by the registration date on a first-come, first-served basis. Once the assignment is made, it will be upheld for at least one session, representing a period measured in blocks with a constant set of sequencers. In Tanssi MainNet, the default session duration is set to {{ networks.mainnet.session.blocks }} blocks, which, with an average block time of six seconds, translates to (roughly) {{ networks.mainnet.session.display }} hours. Every new assignment works intentionally with a one-session delay, so the sequencers know in advance which one of the networks they are assigned to. Sequencers will start syncing the new network they'll have to serve in the next session with a special syncing mechanism called [warp sync](https://spec.polkadot.network/chap-sync#sect-sync-warp){target=\_blank}. Warp sync allows the sequencers to swiftly sync the new network without acting as an archive node. When a new session starts, the Tanssi protocol will put the queued assignment into effect. Sequencers will automatically change and start producing blocks in the new Tanssi network they've been assigned to while discarding the chain state from the previous assignment. Tanssi will also calculate the new assignment, considering changes in Tanssi networks that might have been activated or deactivated and sequencers that might have been added or removed from the pool or changed the total staked value. This new assignment will be queued for the next session. ![Sessions](/images/learn/tanssi/network-services/block-production/block-production-1.webp) ### The Role of the Tanssi Network {: #tanssi-newtwork } As previously discussed, the Tanssi protocol assigns sequencers to the Tanssi networks, and the result of this assignment is stored within the chain state. Besides running the network node, the sequencers also run the Tanssi one. Hence, by accessing the data stored in the finalized blocks of the Tanssi Network, they can learn their assignation for the session, and the Tanssi networks can confirm that a certain group of sequencers have been assigned to them. As the Tanssi networks produce blocks, those blocks need to be validated and finalized by an external security provider. Once an operator verifies a block, a small proof of validity is produced and stored in Tanssi, keeping track of the proofs for each block of each chain. This small representation of the proof of validity is called [candidate receipt](https://polkadot.com/blog/the-path-of-a-parachain-block/#candidate-receipts){target=\_blank} and is composed of a set of values, including the state root, which can be used to verify state proofs. Finally, Tanssi can verify that the author of a network block was the expected one and reward accordingly. The following diagram shows a simplified model of the data Tanssi stores in its internal state. For every active network (in this example, two), Tanssi stores the assigned sequencers, which are the only ones authorized to produce blocks on the network's behalf, proof of validity (candidate receipts) extended by the security provider's operators, the latest state root, and the latest sequencer. ![Tanssi's internal state](/images/learn/tanssi/network-services/block-production/block-production-2.webp) ### The Role of the Tanssi-Powered Network {: #network } As a sequencer assigned to a Tanssi-powered network includes built-in Tanssi node functionality, it is technically feasible to read the state from the Tanssi Network. Leveraging this ability to access the states, the current sequencer with the authority to produce a block will read the state of the latest block produced in the Tanssi chain. It will proceed to include this state in the block of the network, the current set of sequencers assigned to the network, and its public signature, allowing Tanssi to know who produced the block and reward the node operator. Once the block is filled with network transactions, it will be proposed as a candidate and handed over to the Tanssi chain, where the security provider's operators will ensure that the included state proofs match the state proofs from the latest state of Tanssi (preventing unauthorized block production) and that the transactions produced valid state transitions. Having verified the work of the sequencer, the operators will finalize the proposed block, including its candidate receipt in a Tanssi Network block. ![Tanssi-powered network block](/images/learn/tanssi/network-services/block-production/block-production-3.webp) ## Block Production Fees {: #block-production-fees } As presented in the [Introduction](#introduction), Tanssi is an infrastructure protocol that addresses the complexities and high costs associated with setting up and maintaining blockchain infrastructure, streamlining the deployment of networks. This protocol brings benefits for both participants: - **Networks** - teams can focus on the core logic of their product, the UX, and the UI without dealing with the challenges of infrastructure bootstrapping and its management - **Sequencers** - bearing with the responsibility of keeping their hardware and software configuration in optimal conditions, they are incentivized to execute transactions and produce blocks on behalf of the Tanssi networks [Block production as a service](#block-production-as-a-service) carries associated costs that must be covered by the networks that want to leverage Tanssi for such a purpose. The following sections cover the general aspects of those costs and associated service payments. ### Service Payments {: #service-payments } There are three main costs associated with block production as a service that any network must cover using Tanssi tokens to deploy successfully and get the block production services: - **Registration deposit** - the initial deposit that is locked from the account that signs the network registration transaction. It is a variable amount depending on the appchain's runtime size - **Sequencers assignment** - every time the Tanssi protocol assigns sequencers, which happens once per session, a fixed fee is charged. This fee gives networks the right to be assigned sequencers and discourages networks whose runtime logic fails to produce valid transactions or blocks - **Block production** - networks must pay for each block produced on their behalf. Since the protocol selects and assigns the sequencers on a per-session basis, networks must have enough funds to cover all the blocks to be produced in an entire session to be served The current configuration is set as follows: === "Tanssi MainNet" | Variable | Value | |:---------------------:|:---------------------------------------------------------------------------------------------------:| | Registration deposit | {{ networks.mainnet.costs.registration_deposit }} x 10-5 {{ networks.mainnet.token_symbol }} per appchain runtime byte | | Sequencers assignment | {{ networks.mainnet.costs.cost_per_assignment }} x 10-6 {{ networks.mainnet.token_symbol }} per session | | Block production | {{ networks.mainnet.costs.cost_per_block }} x 10-6 {{ networks.mainnet.token_symbol }} per block | === "Dancelight TestNet" | Variable | Value | |:---------------------:|:---------------------------------------------------------------------------------------------------:| | Registration deposit | {{ networks.dancelight.costs.registration_deposit }} x 10-5 {{ networks.dancelight.token_symbol }} per appchain runtime byte | | Sequencers assignment | {{ networks.dancelight.costs.cost_per_assignment }} x 10-6 {{ networks.dancelight.token_symbol }} per session | | Block production | {{ networks.dancelight.costs.cost_per_block }} x 10-6 {{ networks.dancelight.token_symbol }} per block | To ensure block production in the next session, the total balance must be at least enough to cover the sequencers assignment cost plus the cost to produce the {{ networks.mainnet.session.blocks }} blocks that comprise an entire session. !!! note Although the sequencers assignment and block production costs are currently fixed, as protocol development progresses, they might become dynamic, varying in response to the network's workload. ### Tipping {: #tipping } On some occasions, Tanssi might experience a high demand for its block production services that can not be met with the available resources. For example, if there are ten active networks for the next session and Tanssi can only serve eight, two networks will stall for the entire session duration. To deal with these high-workload periods, the Tanssi protocol implements a tipping mechanism that allows networks to compete for a higher priority over the rest. Similar to Ethereum-compatible networks, where a priority fee can be set to outbid competing transactions and obtain preferential execution treatment, the Tanssi networks will be served according to the priority given by the tips they offer. Following the previous example, if there are ten active networks for the next session and Tanssi can only serve eight, then only the eight highest bidding networks will get sequencers assigned. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/learn/tanssi/overview/ --- BEGIN CONTENT --- --- title: Overview description: Tanssi is an infrastructure protocol that simplifies the process of deploying decentralized appchains, allowing developers to focus on creating their product. icon: octicons-home-24 categories: Basics --- # What is Tanssi? {: #what-is-tanssi } Tanssi is a decentralized appchain infrastructure protocol that allows developers to launch their appchain in minutes. In other words, Tanssi reduces the six-to-twelve-month setup process typically required for any team to go live with a new chain to minutes. You can think of Tanssi as _AWS for appchains_. Instead of dealing with all the networking infrastructure yourself, Tanssi handles all the hurdles, allowing you to focus on building your application logic, growing your community, and other tasks essential to your product's success. Security is another significant obstacle that developers must deal with, taking on the responsibility of attracting staked assets to ensure consensus security and bootstrapping a validator set, which can be particularly challenging for projects in their early stages. All Tanssi-powered appchains benefit from Ethereum-grade security right from the start, and by leveraging Tanssi's decentralized design, appchains aren't exposed to single points of failure. Tanssi-powered appchains also benefit from a modular tech stack, providing ultimate control over the logic that powers the blockchain's runtime, offering an excellent way for projects to scale and build optimized solutions for their products. This complete control over the appchain's logic and governance mechanism suits perfectly a wide range of use cases, including DeFi Protocols, Real World Assets (RWA), Gaming Platforms, and others. ## The Problem with Appchains {: #the-problem-with-appchains } Developers looking to build decentralized appchains typically have to deal with the following problems: - **Complex Infrastructure Management**: Appchain deployments typically require handling numerous infrastructural components, including bootstrapping sequencers, operators (also known as validators), wallets, block explorers, oracles, indexers, RPC endpoints, and more. Properly managing these components are both time-consuming and resource-intensive. - **Weak & Inefficient Security**: Appchains commonly suffer from having a small set of operators or weak economic security. Early-stage projects often lack sufficient economic backing to support a robust consensus mechanism. Moreover, developers often have to pay for full blockchain capacity validation even when they might not have achieved product-market fit, and blocks might be close to empty. This essentially means that operators are being overpaid, and there is a significant opportunity cost, as those resources could be used elsewhere to develop the protocol. - **Cross-Chain and Interoperability**: Appchains inherently lack cross-chain capabilities, which prevents them from connecting to other blockchain ecosystems. Furthermore, developing interoperability solutions requires specialized expertise and meticulous implementation. - **Slow Time to Market**: The complexities of appchain infrastructure divert developers' focus from application logic, which is the key driver for intuitive interfaces and a seamless user experience, critical for adoption. ## What Tanssi Provides {: #what-tanssi-provides} Tanssi addresses the most common appchain pain points by: - **Sequencing as a Service**: Appchains built with Tanssi have their blocks produced by Tanssi's incentivized workers. Tanssi guarantees the appchain's liveness by orchestrating a decentralized set of sequencers. - **Economic Security Through External Providers**: Appchains deployed through Tanssi leverage security from a provider of choice (for example, [Symbiotic](https://symbiotic.fi/){target=\_blank} for Ethereum). The protocol is designed to finalize transactions deterministically in seconds through a decentralized set of operators. - **Tanssi/Ethereum Bridge**: Move liquidity to and from Ethereum using the [built-in bridge](/learn/tanssi/tanssi-ethereum-bridge/){target=\_blank} based on Snowbridge. - **Key Integrations**: Appchains built with Tanssi can access key infrastructural components alongside block production in a fully automated and standardized way. Tanssi-powered appchains come with built-in support for essential tools, including wallets, block explorers, indexers, RPC providers, and more, saving developers the effort of integrating these components. - **Modular Blockchain Framework**: Appchains built with Tanssi can use a modular blockchain framework called [Substrate](https://docs.polkadot.com/develop/parachains/intro-polkadot-sdk/){target=\_blank}, which enables developers to quickly and easily build optimized and customizable blockchains for any use case. Tanssi handles most infrastructural complexities, allowing developers to focus on their appchain's custom logic. In summary, appchains deployed through Tanssi are sovereign Layer 1 solutions designed to be highly modular and interconnected, with a focus on simplifying the deployment process and enabling customization of the appchain itself. This empowers developers to bring their blockchain applications to market faster, securely, and with greater potential for integration and interaction within the broader blockchain ecosystems. ### Key Aspects of Tanssi {: #tanssi-key-aspects } The following table summarizes the main benefits Tanssi brings to your project: | Aspect | The Tanssi Solution | |--------------------------|-----------------------------------------------------------------------------------------------------------------------------------| | Deployment Time | - Minutes to deploy
- Faster time to market | | Block production | - Sequencing as a service
- Decentralized set of sequencers by design | | Security | - Ethereum-grade security from the start | | Finality/Settlement | - Deterministic
- Finality in seconds | | Cost | - Registration bond + Pay-as-you-go model | | Customizability | - Choose the governance mechanism that best suits your project
- Modular framework
- Full runtime customizability
| | Integrations and tooling | - Essential tools available from the start | ## General Architecture of Tanssi & Tanssi-powered Appchains {: #tanssi-architecture } As previously discussed, appchains deployed through Tanssi are sovereign and customizable blockchains that, among other features, leverage sequencing as a service and inherit block finality from an external security provider. A high-level overview of the architecture is presented below, featuring [Symbiotic](https://symbiotic.fi/){target=\_blank} as the security provider. ![High-level overview of an appchain & Tanssi](/images/learn/tanssi/overview/overview-1.webp) The Tanssi protocol manages and orchestrates a decentralized set of sequencers assigned to provide block production services to Tanssi-powered appchains. The sequencers execute transactions and include them in blocks, which the security provider's operators then proceed to validate. Symbiotic's restaking protocol allows its operators to offer Ethereum-grade economic security. The mechanism of how this works is explained in two separate articles: [Block Production Services](/learn/tanssi/network-services/block-production/){target=\_blank} and [Ethereum with Symbiotic](/learn/tanssi/external-security-providers/symbiotic/){target=\_blank}. While the sequencers providing block production services are rotated and reassigned to a different appchain upon every session change, each appchain will have its own set of Data Preservers running full archive nodes, ensuring data availability. These Data Preservers will provide the RPC infrastructure for apps and users interacting with Tanssi-powered appchains. ![Data Preservers of an appchain & Tanssi](/images/learn/tanssi/overview/overview-2.webp) ## What's Next? {: #whats-next } - Head to the [Tanssi dApp](https://apps.tanssi.network){target=\_blank} and launch your appchain. - Interact with a live Tanssi-powered appchain: the [Tanssi Demo EVM appchain](/builders/tanssi-network/testnet/demo-evm-network/){target=\_blank}. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/learn/tanssi/tanssi-ethereum-bridge/ --- BEGIN CONTENT --- --- title: Tanssi-Ethereum Bridge description: Discover how Tanssi bridge enables secure, trustless cross-chain interoperability, facilitating asset and message transfers between Tanssi and Ethereum. icon: octicons-link-24 categories: Basics --- # Tanssi-Ethereum Bridge {: #tanssi-ethereum-bridge } ## Introduction {: #introduction } Traditional blockchains often create silos, limiting asset and functional interoperability. The Tanssi-Ethereum bridge overcomes these limitations by enabling seamless cross-chain operations that benefit both ecosystems. The bridge is more than an asset exchange. It’s a secure, standardized protocol for direct cross-chain interaction without centralized intermediaries. Its trustless design avoids the risks of central points of failure that many other bridges face. This article introduces the Tanssi-Ethereum bridge as a key interoperability layer between the two networks. You’ll learn how it works, including its architecture, operator management, economic model, slashing mechanisms, and asset transfers. You'll also learn about the consensus layers that secure communication ([BEEFY](https://docs.snowbridge.network/architecture/components#beefyclient){target=\_blank} on [Tanssi](https://docs.tanssi.network/learn/tanssi/){target=\_blank} and the [Ethereum Beacon Chain](https://ethereum.org/en/roadmap/beacon-chain/){target=\_blank}), and the roles of provers, verifiers, and relayers, giving you a clear view of how assets and messages move securely between Tanssi and Ethereum. ## Core Functions { : #core-functions } The bridge facilitates several critical operations between Tanssi and Ethereum: - **Operator Management** - maintains operator stake information on Ethereum via the [Symbiotic](/learn/tanssi/external-security-providers/symbiotic/#tanssi-symbiotic){target=\_blank} protocol, providing this data to Tanssi for selecting active, decentralized, and economically aligned operators each era - **Economic Operations** - distributes [rewards](/learn/tanssi/external-security-providers/symbiotic/#rewards){target=\_blank} from Tanssi to Ethereum stakers and operators - **Slashing** - processes [slashing requests](/learn/tanssi/external-security-providers/symbiotic/#slashing){target=\_blank} from Tanssi to Ethereum when operators violate protocol rules - **Asset Transfer** - enables bilateral, trustless asset transfers between Tanssi and Ethereum, enhancing liquidity. This interoperability expands the potential of decentralized applications and significantly enhances the liquidity and usability of blockchain assets. ## The Bridge Architecture { : #bridge-architecture } Understanding the bridge's consensus functionality requires examining its core components: provers, verifiers, and relayers. Provers generate cryptographic proofs, verifiers validate them, and relayers move data between chains. Provers include Tanssi's [BEEFY](https://docs.snowbridge.network/architecture/components#beefyclient){target=\_blank} module and Ethereum's Beacon Chain consensus. They produce consensus data transmitted by specialized relayers. Each chain runs a [light client](https://ethereum.org/en/developers/docs/nodes-and-clients/light-clients/){target=\_blank} of the other, acting as an on-chain verifier for data legitimacy. For instance, when Tanssi sends a message to Ethereum, it generates compact proofs of events or state changes based on its consensus. Ethereum's light client verifies these proofs before acting. This efficient method avoids processing the entire sending chain's state, relying instead on concise cryptographic proof verification. ### Tanssi to Ethereum Consensus { : #tanssi-ethereum-consensus } BEEFY (Bridge Efficiency Enabling Finality Yielder) is Tanssi's consensus protocol, which acts as a prover. It's designed for efficient, trustless bridging to chains like Ethereum that are not natively built for interoperability. ```mermaid sequenceDiagram %%{init: {'sequence': {'mirrorActors': false}}}%% participant Tanssi_Pallet as Tanssi
BEEFY Pallet (prover) participant Beefy_Relayer as Relayer
(Beefy) participant Eth_BeefyClient as Ethereum
BEEFY Client (verifier) Tanssi_Pallet->>Beefy_Relayer: Generate BEEFY Commitment activate Beefy_Relayer Beefy_Relayer->>Eth_BeefyClient: Submit commitment/proof deactivate Beefy_Relayer activate Eth_BeefyClient Eth_BeefyClient->>Eth_BeefyClient: Verify commitment deactivate Eth_BeefyClient ``` ### Ethereum to Tanssi Consensus { : #ethereum-tanssi-consensus } For Ethereum-to-Tanssi bridging, Ethereum's Beacon Chain consensus is the prover. It provides Tanssi's on-chain light client with proof of Ethereum's finalized state, including events or messages for Tanssi. ```mermaid sequenceDiagram %%{init: {'sequence': {'mirrorActors': false}}}%% participant Eth_BeaconCons as Ethereum
Beacon Chain Consensus(Prover) participant Beacon_Relayer as Relayer
(Beacon) participant Tanssi_EthClient as Tanssi
Ethereum Light Client (verifier) Eth_BeaconCons->>Beacon_Relayer: Beacon chain update (Header/Proof) activate Beacon_Relayer Beacon_Relayer->>Tanssi_EthClient: Submit update/proof deactivate Beacon_Relayer activate Tanssi_EthClient Tanssi_EthClient->>Tanssi_EthClient: Verify update/proof deactivate Tanssi_EthClient ``` From a messaging perspective, the bridge uses its consensus verification layer for secure cross-chain communication. Dedicated relayers transport messages: the Execution Relay for Ethereum to Tanssi, and the Tanssi Relay for Tanssi to Ethereum. Relayers are stateless and only submit proofs. They cannot forge messages or steal funds, as the consensus mechanism revalidates each proof on-chain. Multiple concurrent relayers improve responsiveness without centralizing power. Ethereum's `Gateway` contract is the central messaging point. It receives messages from Tanssi via relayers, validates them using consensus proofs, and executes operations like token minting/unlocking or smart contract calls. ### Ethereum to Tanssi Inbound Messages { : #ethereum-tanssi-messages } This section describes messages from Ethereum to Tanssi, using Ethereum's Beacon Chain consensus for proofs and an Execution Relay (or Beacon Relay). ```mermaid sequenceDiagram %%{init: {'sequence': {'mirrorActors': false}}}%% participant Eth_Gateway as Ethereum
Gateway Contract participant Exec_Relay as Relayer
(Execution Relay) participant Tanssi_InQueue as Tanssi
Inbound Queue Note over Eth_Gateway: Message Ready / Event Occurs Eth_Gateway->>Exec_Relay: Message + Proof activate Exec_Relay Exec_Relay->>Tanssi_InQueue: Submit Message/Proof deactivate Exec_Relay activate Tanssi_InQueue Tanssi_InQueue->>Tanssi_InQueue: Process Inbound Message deactivate Tanssi_InQueue ``` ### Tanssi to Ethereum Outbound Messages { : #tanssi-ethereum-messages } This section describes messages from Tanssi to Ethereum, using BEEFY consensus to prove Tanssi's state and a Tanssi Relay for transmission. ```mermaid sequenceDiagram %%{init: {'sequence': {'mirrorActors': false}}}%% participant Tanssi_OutQueue as Tanssi
Outbound Queue participant Para_Relay as Relayer
(Tanssi Relay) participant Eth_Gateway as Ethereum
Gateway Contract Note over Tanssi_OutQueue: Message Ready / Proof Committed Tanssi_OutQueue->>Para_Relay: Message + Proof activate Para_Relay Para_Relay->>Eth_Gateway: Submit Message/Proof deactivate Para_Relay activate Eth_Gateway Eth_Gateway->>Eth_Gateway: Process Outbound Message deactivate Eth_Gateway ``` The `Gateway` manages Ethereum's outbound communications. For cross-chain transfers, it logs an event, locks tokens if necessary, and packages data for relay to Tanssi. Tanssi uses two queues for efficient message processing. The `Outbound Queue` handles messages to Ethereum. It bundles them and adds a [Merkle root](https://en.wikipedia.org/wiki/Merkle_tree){target=\_blank} (cryptographic commitment) to each block header. This allows Ethereum's light client to verify message inclusion using consensus proofs efficiently. The `Inbound Queue` processes messages from Ethereum. It receives and verifies proofs of Ethereum events via Tanssi's on-chain Ethereum light client. Verified events become internal instructions in Tanssi. This layered, consensus-secured architecture ensures trustless cross-chain interactions. ## Token Transfers Flow {: #token-transfers-flow } This section explains how the bridge moves assets and messages. It involves locking/minting assets on one chain and a complementary action on the other, secured by verified proofs. The following describes the typical transfer sequences. 1. **Initiation (Source Chain)** - user initiates asset transfer 2. **Relay Proof** - off-chain relayers pick up the event and submit cryptographic proofs to the destination chain 3. **Verification (Destination Chain)** - on-chain light clients independently verify submitted proofs 4. **Execution** - upon successful verification, tokens are minted/unlocked on the destination chain ### Ethereum to Tanssi Transfer This section outlines asset movement from Ethereum to Tanssi (as derivative assets). 1. **Lock on Ethereum** - a user deposits assets into Ethereum's Bridge contract. The contract locks the tokens and emits a deposit event 2. **Relay Proof to Tanssi** - an off-chain relayer detects the finalized event, creates a proof package (including Ethereum block header and Merkle proof of the deposit), and submits it to the Tanssi Bridge's `Inbound Queue` 3. **Verify on Tanssi** - Tanssi Bridge's `EthereumClient` module (an on-chain light client) receives the proof from the `Inbound Queue`. It verifies the Ethereum block header's finality/validity and the Merkle proof's authenticity 4. **Mint on Tanssi** - upon successful verification by the `EthereumClient`, the `Inbound Queue` is notified and mints the corresponding asset on Tanssi ```mermaid sequenceDiagram %%{init: {'sequence': {'mirrorActors': false}}}%% participant User participant EBridge as Ethereum Bridge Contract participant Relayer participant TBP as Tanssi Bridge
(Inbound Queue + ETH Client) participant TAH as Tanssi User->>EBridge: 1. Deposit Asset activate EBridge Note over EBridge: Lock Tokens & Emit Event deactivate EBridge Relayer->>Relayer: Observe Ethereum Event Relayer->>TBP: 2. Submit Header + Merkle Proof activate TBP Note over TBP: Receive Proof (Inbound Queue) TBP->>TBP: 3. Verify Proof (EthereumClient Pallet) TBP->>TAH: Send Mint Request deactivate TBP activate TAH TAH->>TAH: 4. Mint Asset TAH-->>User: (Asset appears in Recipient Account) deactivate TAH ``` ### Tanssi to Ethereum Transfer This flow describes the reverse process, moving assets from Tanssi to Ethereum. 1. **Initiate and Commit on Tanssi** - user initiates a transfer on Tanssi. A message with transfer details goes to the Bridge's `Outbound Queue`. The queue processes it, bundles the payload, and commits its Merkle root to the Tanssi block header, representing all outgoing messages in that block 2. **Relay Proof to Ethereum** - an off-chain relayer monitors Tanssi for finalized blocks with `Outbound Queue` Merkle roots. It retrieves proofs: a BEEFY commitment (signed statement of finalized Tanssi block headers) and a Merkle proof of the user's transfer payload under the committed root 3. **Submit Commitment in Ethereum** - the relayer submits the BEEFY commitment and Merkle proof to Ethereum's `Gateway` contract 4. **Verify on Ethereum** - Ethereum's Beefy Client contract (Tanssi's on-chain light client) receives the BEEFY commitment from the `Gateway` and verifies its validity (including signatures) 5. **Validate Payload** - after commitment verification, the `Gateway` validates the Merkle proof for the user's payload 6. **Execute on Ethereum** - with both proofs verified, the `Gateway` contract executes the action, usually releasing locked assets via the main Bridge contract to the recipient or executing a target contract call on Ethereum The following diagram illustrates the initiation and commitment phase of the asset transfer process on the Tanssi side. ```mermaid sequenceDiagram %%{init: {'sequence': {'mirrorActors': false}}}%% participant User participant TAH as Tanssi participant TBP as Tanssi Bridge
(Outbound Queue) participant Relayer User->>TAH: 1. Initiate Transfer & Deposit Asset activate TAH TAH->>TBP: Send message to Outbound Queue deactivate TAH activate TBP Note over TBP: Process message, Bundle, and
Commit Merkle Root to Tanssi Header deactivate TBP Relayer->>Relayer: 2. Observe Tanssi Header /
BEEFY Commitment & Get Proof Note over Relayer: Relayer is now ready to interact
with Ethereum based on observed data. ``` The subsequent diagram details the relay, verification, and execution steps on the Ethereum side of the asset transfer. ```mermaid sequenceDiagram %%{init: {'sequence': {'mirrorActors': false}}}%% participant Relayer participant EGateway as Ethereum Gateway Contract participant EBeefy as Ethereum Beefy Client Contract participant EBridge as Ethereum Bridge Contract participant User Relayer->>EGateway: 3. Submit BEEFY Commitment + Merkle Proof activate EGateway EGateway->>EBeefy: 4. Verify BEEFY Commitment activate EBeefy EBeefy-->>EGateway: Verification OK deactivate EBeefy EGateway->>EGateway: 5. Verify Merkle Proof for Payload Note over EGateway: Proof Validated EGateway->>EBridge: 6. Execute: Unlock Tokens / Call Target Contract activate EBridge Note over EBridge: Assets Transferred or
Target Call Executed EBridge-->>User: (Tokens Received / Call Executed) deactivate EBridge deactivate EGateway ``` --- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/account-management/identity/ --- BEGIN CONTENT --- --- title: Set an Account Identity description: Follow these instructions to establish an identity, including a display name so that you can be more easily recognizable on the Tanssi orchestrator chain. icon: octicons-person-24 categories: Basics, Appchain --- # Set Up an On-Chain Identity ## Introduction {: #introduction } The [Substrate](/learn/framework/overview/#substrate-framework){target=\_blank} Identity [module](/learn/framework/modules/){target=\_blank} is an out-of-the-box solution for adding personal information to your on-chain account. Establishing an identity makes it easier for your account to be recognized by others, as your display name will automatically populate when someone pastes your address into a field on the [developer portal](https://polkadot.js.org/apps/?rpc=wss://{{ networks.mainnet.dns_name }}#/accounts){target=\_blank}. The identity you configure goes beyond a simple display name. Personal information can include default fields such as your legal name, display name, website, Twitter handle, Discord, and Riot (now known as Element) name. You can also use custom fields to include any other relevant information. This guide will demonstrate setting up an identity with a display name and additional parameters, enhancing your visibility and recognizability. ## General Definitions {: #general-definitions } To store your information on-chain, you must bond some funds, which will eventually be returned once the identity has been cleared. There are two categories of fields: default and custom. A basic deposit amount is reserved upon identity creation, and a storage deposit is required for each additional byte of data stored on-chain. - **Default fields include** - your legal name, display name, website, Twitter handle, Discord, Riot (now known as Element) name - **Custom fields include** - any other relevant information - **Subaccounts** - You can link subaccounts underneath a primary account. As an example, a sequencer service that's running multiple different sequencer nodes can establish subaccounts to demonstrate an official link between the nodes === "Tanssi MainNet" | Variable | Definition | Value | |:---------------------:|:--------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------:| | Basic deposit | The amount held on deposit for setting an identity | {{ networks.mainnet.identity.basic_deposit }} {{ networks.mainnet.token_symbol }} | | Deposit per byte | The amount held on deposit per byte of on-chain storage used setting an identity | {{ networks.mainnet.identity.per_byte_deposit }} {{ networks.mainnet.token_symbol }} | | Max additional fields | Maximum number of additional fields that may be stored in an ID | {{ networks.mainnet.identity.max_fields }} | | Max subaccounts | Maximum number of subaccounts that can be defined under an account identity | {{ networks.mainnet.identity.max_subaccounts }} | === "Dancelight TestNet" | Variable | Definition | Value | |:---------------------:|:--------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------:| | Basic deposit | The amount held on deposit for setting an identity | {{ networks.dancelight.identity.basic_deposit }} {{ networks.dancelight.token_symbol }} | | Deposit per byte | The amount held on deposit per byte of on-chain storage used setting an identity | {{ networks.dancelight.identity.per_byte_deposit }} {{ networks.dancelight.token_symbol }} | | Max additional fields | Maximum number of additional fields that may be stored in an ID | {{ networks.dancelight.identity.max_fields }} | | Max subaccounts | Maximum number of subaccounts that can be defined under an account identity | {{ networks.dancelight.identity.max_subaccounts }} | ## Checking Prerequisites { : #checking-prerequisites } To follow along with this guide, you will need the following: === "Tanssi MainNet" - The [developer portal](https://polkadot.js.org/apps/?rpc=wss://{{ networks.mainnet.dns_name }}#/accounts){target=\_blank} open and connected to Tanssi MainNet. - At least one account funded with `{{ networks.mainnet.token_symbol }}` tokens. === "Dancelight TestNet" - The [developer portal](https://polkadot.js.org/apps/?rpc=wss://{{ networks.dancelight.dns_name }}#/accounts){target=\_blank} open and connected to [Dancelight](/builders/tanssi-network/testnet/dancelight/){target=\_blank}. - At least one account funded with `{{ networks.dancelight.token_symbol }}` tokens. If you need help importing your accounts into the developer portal, please check out the [Connecting to the developer portal](/builders/toolkit/substrate-api/wallets/talisman/#connecting-to-polkadotjs){target=\_blank} guide. ## Get Started {: #get-started } Depending on the information to be included, there are a couple of different ways to set and clear an identity using the developer portal. If you intend to register your identity using only the default fields, you can follow the instructions for [Managing an Identity via the Accounts](#manage-via-accounts) page. **This is the recommended way to set and manage your identity**. If you want to add custom fields beyond the default fields, follow the instructions for [Managing an Identity via the Extrinsics](#manage-via-extrinsics) page. !!! note Please note that using the **Accounts** page on the developer portal is recommended to manage your identity as it provides an easy-to-use interface that enforces character limits. If you use the **Extrinsics** page, please be aware that your input for each field (i.e., name, email, etc.) must be 32 characters or less; otherwise, your information will be cut off. ## Manage an Identity via Accounts {: #manage-via-accounts } ### Set an Identity {: #set-identity-accounts } To get started with setting an identity using the Accounts page, head to the [**Accounts** tab](https://polkadot.js.org/apps/?rpc=wss://{{ networks.mainnet.dns_name }}#/accounts){target=\_blank} of the developer portal. You should already have an account connected, so you can click on your account name to verify and note your balances. After you send the transaction to set an identity, the deposit(s) you submitted will be moved from your transferable balance to your reserved balance. ![Starting account balances](/images/builders/account-management/identity/identity-1.webp) To set your identity, you'll need to: 1. Click on the three vertical dots next to the account you would like to set an identity for 2. A menu will pop up. Click **Set on-chain identity** ![Set on-chain identity](/images/builders/account-management/identity/identity-2.webp) Next, the menu to register and set your identity will pop up, and you can start filling in your information. You are not required to enter information for every single field; you can choose to fill in just one field or all of them; it's up to you. For this example: 1. Set your display name 2. Click on the **include field** toggle for email and then enter in your email 3. Click on the **include field** toggle for web and then enter in your website URL 4. Click on the **include field** toggle for Twitter and then enter in your Twitter handle 5. Review the prior data fields and click **Set Identity** ![Set your identity](/images/builders/account-management/identity/identity-3.webp) You will then be prompted to sign the transaction. If everything looks good, sign it. You should see status notifications pop up in the top right-hand corner. Once the transaction has been confirmed, you can click on your account name again, and the panel will slide out on the right side of the page. Your balances will have changed, and you'll also see your new identity information. ![Updated account balances](/images/builders/account-management/identity/identity-4.webp) If the identity information matches what you entered, you've successfully set an identity! Once you clear your identity, the deposit in your reserved balance will get transferred back to your transferable balance. If you need to change your identity, you can go through the process of setting your identity again. Please note that you must ensure all fields are re-entered, even if only one field needs to be changed, or they will be overwritten. You will not need to pay another deposit unless custom fields are used, but you will need to pay gas fees. ## Manage an Identity via Extrinsics {: #manage-via-extrinsics } ### Set an Identity {: #set-identity-extrinsics } To register an identity using the extrinsics page, navigate to the [**Extrinsics** page](https://polkadot.js.org/apps/?rpc=wss://{{ networks.mainnet.dns_name }}#/extrinsics){target=\_blank} of the developer portal. Please ensure your input does not exceed 32 characters for each identity field. To complete your identity, take the following steps: 1. Select your account 2. Select identity from the **submit the following extrinsic** dropdown 3. Then select the **setIdentity(info)** function 4. Select **Raw** as the data format to enter your **Display Name** 5. Enter the data for **Display** in the selected format 6. Select **Raw** as the data format to enter your web address 7. Enter your website URL in the selected format 8. Select **Raw** as the data format to enter your email 9. Enter your email address in the selected format 10. Select **Raw** as the data format to enter your Twitter handle 11. Enter your Twitter in the selected format. Enter the username only, starting with the `@` symbol 12. Review the prepared fields and press **Submit Transaction** ![Set on-chain identity](/images/builders/account-management/identity/identity-5.webp) Optionally, if you would like to enter custom fields, take the following steps: 1. Scroll to the top and click on **Add item** 2. Two fields will appear: the first for the field name and the second for the value. Select **Raw** as the data format to enter the field name 3. Enter the field name in the specified format 4. Select **Raw** as the data format to enter the custom value 5. Enter the custom value in the specified format ![Add custom fields](/images/builders/account-management/identity/identity-6.webp) Finally, once all of your identity information has been added, you can scroll to the bottom of the page and click **Submit Transaction**. You will then be prompted to sign the transaction. Remember, an additional deposit is required for each additional custom field. If everything looks good, sign the transaction. You should see status notifications pop up in the top right-hand corner confirming the transaction. If successful, you've set an identity! Congratulations! To ensure everything went through and your identity information looks good, you can verify your identity. ### Confirm an Identity {: #confirm-identity-extrinsics } To verify the addition of your identity information, you can click on the **Developer** tab and then navigate to [**Chain state**](https://polkadot.js.org/apps/?rpc=wss://{{ networks.mainnet.dns_name }}#/chainstate){target=\_blank}. On the **Chain State** page, make sure **Storage** is selected. Then you can start to request your identity information: 1. Set **selected state query** to **identity** 2. Select the **identityOf(AccountId)** function 3. Select your account 4. Click the **+** button to get your identity information ![Request identity information](/images/builders/account-management/identity/identity-7.webp) You can see now that you've successfully set an identity! Once you clear your identity, the deposit in your reserved balance will get transferred back to your transferable balance. If you need to change your identity, you can go through the process of setting your identity again. Please note that you must ensure all fields are re-entered, even if only one field needs to be changed, or they will be overwritten. You will not need to pay another deposit unless custom fields are used, but you will need to pay gas fees. ## Clear an Identity {: #confirm-identity-extrinsics } To clear your identity, take the following steps from **Extrinsics** tab of the developer portal: 1. Select your account from the **using the selected account** dropdown 2. Select **identity** from the **submit the following extrinsic** dropdown 3. Then select the **clearIdentity()** function 4. Click **Submit Transaction** ![Clear an identity](/images/builders/account-management/identity/identity-8.webp) You will then be prompted to sign the transaction. If everything looks good, sign it. You should see status notifications in the top right-hand corner confirming the transaction. To confirm that your identity information has been successfully removed, revisit the steps outlined in the [Confirm an Identity section](#confirm-identity-extrinsics). This time, instead of displaying your identity details, the response should indicate **none**, confirming that no identity information is currently linked to your account. Additionally, when you check your balances, you will find that the deposit initially made for setting your identity has been credited back to your transferable balance. This completes the process of clearing your identity. ![Clear an identity confirmation](/images/builders/account-management/identity/identity-9.webp) --- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/account-management/proxy-accounts/ --- BEGIN CONTENT --- --- title: Set Up and Manage Proxy Accounts description: Follow these step-by-step instructions to learn how proxies work and how to create, view, update, and remove proxy accounts from primary (proxied) accounts. icon: octicons-shield-lock-24 categories: Basics, Appchain --- # Proxy Accounts ## Introduction {: #introduction } Proxy accounts can be set up to perform a limited number of actions on behalf of primary accounts and are helpful for keeping the underlying accounts safe. Your proxy account can act as a "hot wallet" to interact with the network on behalf of your "cold wallet" account. For added safety, you can regularly rotate the proxy account. Proxy accounts can also help you implement the principle of least privilege for access control. For example, if you have multiple team members, you can give them the minimum level of access required to carry out their duties via a specific type of proxy account. This tutorial will walk you through configuring a proxy account on Dancelight, the Tanssi TestNet, specifically for balance transfers. Then, it will demonstrate performing a balance transfer using the newly created proxy. ## Checking Prerequisites {: #checking-prerequisites } To follow along with this tutorial, you will need to have: - [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=wss://{{ networks.dancelight.dns_name }}#/accounts){target=\_blank} open and connected to [Dancelight](/builders/tanssi-network/testnet/dancelight/){target=\_blank}. - Create or have two accounts accessible on the developer portal. - At least one of the accounts will need to be funded with `{{ networks.dancelight.token_symbol }}` tokens. If you need help importing your accounts into Polkadot.js Apps, please check out the [Connecting to Polkadot.js](/builders/toolkit/substrate-api/wallets/talisman/#connecting-to-polkadotjs){target=\_blank} guide. ## General Definitions {: #general-definitions } When setting up a proxy account, a bond for the proxy is taken out of your free balance and moved to your reserved balance. The bond is required as adding a proxy requires on-chain storage space, and it is recalculated for each proxy you add or remove. The bond is returned to your free balance after all proxies are removed from your account. The deposit is calculated based on a deposit base and a deposit factor: - **Deposit base** - the amount to be reserved for an account to have a proxy list. - **Deposit factor** - the additional amount to be reserved for every proxy the primary account has. The equation for calculating the deposit is: ```text deposit base + deposit factor * number of proxies ``` You can find each of the relevant variables below. === "Tanssi MainNet" | Variable | Value | |:--------------:|:--------------------------------------------------------------------------------:| | Deposit base | {{ networks.mainnet.proxy.deposit_base }} {{ networks.mainnet.token_symbol }} | | Deposit factor | {{ networks.mainnet.proxy.deposit_factor }} {{ networks.mainnet.token_symbol }} | | Max proxies | {{ networks.mainnet.proxy.max_proxies }} proxies | === "Dancelight TestNet" | Variable | Value | |:--------------:|:--------------------------------------------------------------------------------------:| | Deposit base | {{ networks.dancelight.proxy.deposit_base }} {{ networks.dancelight.token_symbol }} | | Deposit factor | {{ networks.dancelight.proxy.deposit_factor }} {{ networks.dancelight.token_symbol }} | | Max proxies | {{ networks.dancelight.proxy.max_proxies }} proxies | ## Proxy Types {: #proxy-types } When creating a proxy account, you must choose a type of proxy that will define how the proxy can be used. The available options are: - **`Any`** - allows the proxy account to use any function supported by the proxy pallet. There is no filtering of calls. - **`NonTransfer`** - this type of proxy account is allowed to submit any type of transaction with the exception of balance transfers. - **`Balances`** - allows the proxy account to only make transactions related to sending funds. - **`Governance`** - allows the proxy account to only make transactions related to the governance pallet, such as voting or creating democracy proposals. Note, governance is not yet enabled on Tanssi. You can create governance proxy accounts but they will not be able to take any actions until governance is enabled. - **`Registrar`** - allows the proxy account to only make transactions related to the registrar pallet. - **`SudoRegistrar`** - allows the proxy account to only make transactions related to the registrar pallet that need to be called by Sudo. - **`CancelProxy`** - allows the proxy account to reject and remove any announced proxy calls. - **`Staking`** - allows the proxy account to perform staking-related transactions, such as sequencer and `session()` functions. - **`SessionKeyManagement`** - allows the proxy account to make key management related transactions included in the session pallet. For this guide, you will be setting up a proxy account using the balances proxy type. Since this type enables the proxy to spend funds on behalf of the primary account, you should exercise caution and only provide access to accounts you trust. The proxy will have access to transfer all of the funds within the primary account, and if not trusted, the proxy could drain the primary account. Ensure that you maintain oversight of your proxy accounts and remove any proxies that are no longer needed. ## Creating a Proxy Account {: #creating-a-proxy-account } There are a couple of ways you can create proxy accounts in [Polkadot.js Apps](https://polkadot.js.org/apps/?rpc=wss://{{ networks.dancelight.dns_name }}#/accounts){target=\_blank}, either from the **Extrinsics** page or the **Accounts** page. However, to create a time-delayed proxy, you will need to use the **Extrinsics** page. A time delay provides an additional layer of security to proxies by specifying a delay period based on the number of blocks. This will prevent the proxy account from executing a transaction until the delay period ends. The delay allows time for the primary account that controls the proxy to review pending transactions, potentially for malicious actions, and cancel if necessary before execution. The following demo will showcase configuring a Balances proxy, which allows for transferring funds, making it perfect for demonstration purposes. After configuring your Balances proxy you can try transferring funds from the primary account via proxy. To get started creating your proxy account, head to the **Developer** tab and select [**Extrinsics**](https://polkadot.js.org/apps/?rpc=wss://{{ networks.dancelight.dns_name }}#/extrinsics){target=\_blank} from the dropdown. Next, you will need to take the following steps: 1. Select the primary account. 2. From the **submit the following extrinsic** dropdown, select **proxy**. 3. Choose the **addProxy** extrinsic. 4. Choose **Id** from the **AccountIdLookupOf** dropdown. 5. Select the **delegate** account for the proxy. 6. From the **proxyType** dropdown, choose **Balances**. 7. Optionally, you can add a time delay using a specified number of blocks to add an additional layer of security for the primary account to review the pending transaction. 8. Click **Submit Transaction**. ![Add a proxy account from the Extrinsics page of Polkadot.js Apps.](/images/builders/account-management/proxy/proxy-1.webp) You will then be prompted to authorize and sign the transaction. Click **Sign and Submit** to create the proxy relationship. Once the transaction has been successfully submitted, you will receive some notifications confirming the transaction. As previously mentioned, you can also create a proxy from the **Accounts** page. To do so, navigate to the **Accounts** page and take the following steps: 1. Select the three vertical dots next to the primary account. 2. Select **Add proxy**. ![Select the Add proxy menu item from the Accounts page of Polkadot.js Apps.](/images/builders/account-management/proxy/proxy-2.webp) !!! note If the account already has a proxy, **Manage proxies** will be displayed as an option instead of **Add proxy**. A pop-up will appear and you can enter in the required information, such as the proxied/primary account, the proxy account, and type of proxy to create a proxy account. First click **Add Proxy**. ![Add a proxy account from the Accounts page of Polkadot.js Apps](/images/builders/account-management/proxy/proxy-3.webp) Then, take the following steps: 1. Select the account you would like to set as a proxy. 2. Select the proxy type. 3. Click **Submit** and sign the transaction. ![Add the details of the proxy account, including the proxy account and type.](/images/builders/account-management/proxy/proxy-4.webp) In the next section, you will learn how to verify that your proxy account was set up successfully. ## Verifying Your Proxy Account {: #verifying-your-proxy-account } You can verify that your proxy account has been successfully set up in a couple of ways: either through the **Accounts** page or via the **Chain state** page. To check your proxy accounts from the [**Chain state** page](https://polkadot.js.org/apps/?rpc=wss://{{ networks.dancelight.dns_name }}#/chainstate){target=\_blank}, you can take the following steps: 1. From the **selected state query** dropdown, select **proxy**. 2. Choose the **proxies** extrinsic. 3. Select your primary/proxied account. 4. Click on the **+** button to send the query. ![Verify your proxy accounts via the Extrinsics page of Polkadot.js Apps.](/images/builders/account-management/proxy/proxy-5.webp) The result will appear on the page showing you information about all of your proxies, including the delegate/proxy account address, the proxy type, the delay period if one was specified, and the total bond amount for all of your proxies in Planck. You can also check your proxy accounts from the **Accounts** page. To do so, navigate to the **Accounts** page, and there should be a Proxy symbol next to the primary account. Hover over the icon and click on **Manage proxies** to review your proxies. ![Hover over the proxy icon to manage your proxies via the Accounts page of Polkadot.js Apps.](/images/builders/account-management/proxy/proxy-6.webp) A pop-up will appear where you can see an overview of all of your proxy accounts. ![Review your proxy accounts.](/images/builders/account-management/proxy/proxy-7.webp) ## Executing a Proxy Transaction {: #executing-a-proxy-transaction } Now that you have created a proxy account and verified that it was successfully set up, you can execute a transaction using the proxy account on behalf of the primary account. To execute a transaction, you can navigate back to the [**Extrinsics** page](https://polkadot.js.org/apps/?rpc=wss://{{ networks.dancelight.dns_name }}#/extrinsics){target=\_blank} and take the following steps: 1. Select the proxy account to submit the transaction from the **using the select account** dropdown. 2. From the **submit the following extrinsic** menu, select **proxy**. 3. Choose the **proxy** extrinsic. 4. Choose **Id** from the **AccountIdLookupOf** dropdown. 5. Select the primary account from the **real** dropdown. 6. Select the **balances** call. 7. Choose the **transferKeepAlive** extrinsic. 8. Choose **Id** from the **AccountIdLookupOf** dropdown. 9. In the **dest** field, enter the address you would like to send funds to. 10. In the **value** field, enter the amount of {{ networks.dancelight.token_symbol }} tokens to send. For this example, you can send `2` {{ networks.dancelight.token_symbol }} tokens. 11. Click **Submit Transaction**. ![Execute a proxy transaction from the Extrinsics page of Polkadot.js Apps.](/images/builders/account-management/proxy/proxy-8.webp) A pop-up will appear for you to authorize and sign the transaction. Enter your password for the proxy account and click **Sign and Submit**. If the transaction successfully went through, you should see a couple of notification pop-ups. If you head over to the **Accounts** page, you'll see that your primary account balance has decreased. If you check the account balance where you sent the funds, you'll notice the balance there has increased. ![Check balance on the accounts page of Polkadot.js Apps](/images/builders/account-management/proxy/proxy-9.webp) That's it! You've successfully executed a transaction using a proxy account on behalf of your primary account. ## Removing a Proxy Account {: #removing-a-proxy-account } Similarly to adding a proxy account, there are a couple of ways that you can remove a proxy account, either from the **Extrinsics** page or the **Accounts** page. Regardless of which page you use, you can elect to remove a single proxy account or all proxies associated with your primary account. To remove a proxy from the [**Extrinsics** page](https://polkadot.js.org/apps/?rpc=wss://{{ networks.dancelight.dns_name }}#/extrinsics){target=\_blank}, you can take the following steps: 1. From the **using the selected account** dropdown, select your primary account. 2. Then select **proxy**. 3. Choose **removeProxy** to remove a single proxy or **removeProxies** to remove all associated proxies. 4. Choose **Id** from the **AccountIdLookupOf** dropdown. 5. If removing a single proxy, enter the proxy account to remove in the **delegate** field. 6. Select the **proxyType** to remove, in this case choose **Balances**. 7. Optionally, select a delay period in block numbers. 8. Click **Submit Transaction**. ![Remove a proxy account from the Extrinsics page of Polkadot.js Apps](/images/builders/account-management/proxy/proxy-10.webp) A pop-up will appear asking you to authorize and sign the transaction. You can sign and send the transaction from the primary or proxy account, but the call to remove the proxy must be sent from the primary account. Enter your password and click **Sign and Submit**. To check that the proxy or proxy accounts have been removed, follow the steps in the [Verifying your Proxy Account](#verifying-your-proxy-account) section. As previously mentioned, you can also remove a proxy from the **Accounts** page. To do so, on the **Accounts** page, select the three vertical dots next to the primary account and select **Manage Proxies**. ![Click on the Manage Proxies button to review and manage your proxy accounts.](/images/builders/account-management/proxy/proxy-11.webp) A pop-up will appear showing an overview of your proxy accounts. To remove all proxies, you can click on **Clear all**, then you will automatically be prompted to enter your password and submit the transaction. To remove a single proxy, take the following steps: 1. Click the **X** button next to the proxy to remove 2. Press **Submit** ![Remove a proxy account from the Accounts page of Polkadot.js Apps.](/images/builders/account-management/proxy/proxy-12.webp) On the transaction confirmation screen, take the following steps: 1. Ensure that you do not use a proxy for this call (as this example is a balances proxy, the call to remove the proxy needs to come from the primary account rather than the proxy account). 2. Enter your password for the respective account. 3. Press **Sign and Submit**. ![Remove a proxy account from the Accounts page of Polkadot.js Apps, confirmation](/images/builders/account-management/proxy/proxy-13.webp) Once the transaction has successfully been submitted, you can review your current proxies, or if you removed all proxies, you will notice the proxy icon is no longer being displayed next to the primary account. And that's it! You've successfully created a proxy, reviewed all proxy accounts associated with your primary account, executed a proxy transaction, and removed a proxy account!
The information presented herein has been provided by third parties and is made available solely for general information purposes. Tanssi does not endorse any project listed and described on the Tanssi Doc Website (https://docs.tanssi.network/). Tanssi Foundation does not warrant the accuracy, completeness or usefulness of this information. Any reliance you place on such information is strictly at your own risk. Tanssi Foundation disclaims all liability and responsibility arising from any reliance placed on this information by you or by anyone who may be informed of any of its contents. All statements and/or opinions expressed in these materials are solely the responsibility of the person or entity providing those materials and do not necessarily represent the opinion of Tanssi Foundation. The information should not be construed as professional or financial advice of any kind. Advice from a suitably qualified professional should always be sought in relation to any particular matter or circumstance. The information herein may link to or integrate with other websites operated or content provided by third parties, and such other websites may link to this website. Tanssi Foundation has no control over any such other websites or their content and will have no liability arising out of or related to such websites or their content. The existence of any such link does not constitute an endorsement of such websites, the content of the websites, or the operators of the websites. These links are being provided to you only as a convenience and you release and hold Tanssi Foundation harmless from any and all liability arising from your use of this information or the information provided by any third-party website or service.
--- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/build/templates/overview/ --- BEGIN CONTENT --- --- title: Requirements and Features of Templates description: Explore the foundational setup and key features included in each Tanssi template, designed to streamline the building and deployment of Tanssi networks. icon: octicons-home-24 categories: Basics, Appchain --- # Templates Overview {: #templates-overview } ## Introduction {: #introduction } Networks deployed through Tanssi are fully customizable blockchains benefiting from a shared set of sequencers and the security of a provider of their choice. The templates presented in this article implement the necessary functionalities and configurations to support the Tanssi protocol, making development easier. ## Base Setup to Support the Tanssi Protocol {: #base-setup-supporting-tanssi } Tanssi networks must implement the following modules to support the protocol and benefit safely from Tanssi's block production as a service: - **Author Noting** - registers the set of sequencers assigned to the network by Tanssi - **Author Inherent** - allows the sequencer authoring the block to include its identity to get validated and rewarded If you don't include these modules in the Tanssi network's runtime, there won't be a method to confirm that the blocks are being generated by trustworthy sequencers designated by the Tanssi orchestrator. This could create a vulnerability for malicious actors to exploit and compromise the network. For more information about Tanssi's block production as a service please refer to the [Block Production Services](/learn/tanssi/network-services/block-production/){target=\_blank} article. Besides block production, there are other essential aspects for any network covered in the templates, such as: - **Consensus** - networks have the necessary functionality to allow the sequencers to produce blocks, gossip and validate them, and coordinate with the security provider to get notified about the block's finality - **Networks Interoperability** - handles the ingestion and dispatch of incoming downward and lateral messages, allowing a Tanssi network to communicate and interoperate with the other chains within the ecosystem - **Runtime Upgrades** - a runtime upgrade in a Tanssi network must be informed to the security provider's operators to allow them to check on the blocks produced by the sequencers of the Tanssi networks ## Included Modules {: #included-modules } Besides the necessary modules to support the operation of a Tanssi network, many other modules provide functional behavior that the users can interact with. These are some of the functional modules exposing a behavior to the users that are included in the templates and ready to use: - **[Balances](https://paritytech.github.io/substrate/master/pallet_balances/index.html){target=\_blank}** - the Balances module provides functions for handling accounts and balances for the Tanssi network native currency - **[Utility](https://paritytech.github.io/polkadot-sdk/master/pallet_utility/index.html){target=\_blank}** - the Utility module provides functions to execute multiple calls in a single dispatch. Besides batching transactions, this module also allows the execution of a call from an alternative signed origin - **[Proxy](https://paritytech.github.io/polkadot-sdk/master/pallet_proxy/index.html){target=\_blank}** - the Proxy module provides functions to delegate to other accounts (proxies) the permission to dispatch calls from a proxied origin - **[Maintenance Mode](https://github.com/moondance-labs/moonkit/blob/tanssi-polkadot-v1.3.0/pallets/maintenance-mode/src/lib.rs){target=\_blank}** - the Maintenance Mode module allows the Tanssi network to be set to a mode where it doesn't execute balance/asset transfers or other transactions. This could be useful when upgrading the runtime in an emergency, when executing large storage migrations, or when a security vulnerability is discovered - **[Tx Pause](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/tx-pause/src/lib.rs){target=\_blank}** - the Tx Pause module allows a valid origin (typically Root) to pause (and unpause) an entire module or a single transaction. A paused transaction (or all the transactions included in a paused module) will fail when called until it is unpaused. This module provides a higher degree of granularity compared to maintenance mode, making it particularly useful when a faulty or vulnerable transaction is identified in the runtime - **[Multisig](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/multisig/src/lib.rs){target=\_blank}** - the Multisig module enables transaction dispatches that require -typically- more than one signature. A multisig transaction defines a set of authorized accounts and a threshold for its approval, requiring consensus among multiple parties ## Start Building {: #getting-started } To start building on top of the provided templates, be it the [baseline Tanssi network template](/builders/build/templates/substrate/){target=\_blank} or the [baseline EVM (Ethereum Virtual Machine) template](/builders/build/templates/evm/){target=\_blank}, the recommended approach is to fork the [Tanssi repository](https://github.com/moondance-labs/tanssi){target=\_blank} and start adding [built-in modules](/builders/build/customize/adding-built-in-module/){target=\_blank} or [custom-made modules](/builders/build/customize/adding-custom-made-module/){target=\_blank} on top of the [latest release](https://github.com/moondance-labs/tanssi/releases/latest){target=\_blank} tag. This approach comes with some advantages, such as: - Building on top of the latest and stable release - Get the Tanssi protocol already configured and included in the template runtime - Keep your fork up-to-date by syncing with the Tanssi upstream repository - Run the included tests, ensuring that block production on your Tanssi network works as intended - Run a complete local environment with the included [Zombienet](https://paritytech.github.io/zombienet){target=\_blank} configuration If the templates already cover your use case needs, or after building and testing your chain, you can continue with the [Deploy Your Network via the Tanssi DApp](/builders/deploy/dapp/){target=\_blank} article to know how to use the Tanssi dApp to register and get your chain up and running. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/interoperability/built-in-bridge/ --- BEGIN CONTENT --- --- title: Using the Built-In Tanssi Bridge description: Learn how to use the built-in Tanssi bridge that connects Tanssi and Ethereum to convert TANSSI tokens between their native form and ERC-20 and vice versa. icon: octicons-arrow-switch-24 categories: Basics --- # Using the Built-In Tanssi Bridge ## Introduction {: #introduction } The Tanssi protocol orchestrates infrastructure components, allowing developers to launch their customized appchains in minutes and providing them with out-of-the-box Ethereum-grade economic security. To make the whole process easy for developers, a [top-of-class architecture](/learn/tanssi/overview/#tanssi-architecture){target=\_blank} was designed and implemented. The [TANSSI token](/builders/tanssi-network/tanssi-token/){target=\_blank} is the engine that enables the integration of different infrastructural components with [external security providers](/learn/tanssi/external-security-providers/symbiotic/){target=\_blank} and aligns incentives across various actors, including token holders, node operators, and appchain builders. To serve different use cases, the token has two versions: the Tanssi network's native currency, TANSSI (Substrate), and its ERC-20 version, on Ethereum. Users can convert from one version to the other of the token using a [Tanssi built-in trustless bridge](/learn/tanssi/tanssi-ethereum-bridge/){target=\_blank}. In this guide, you'll learn how to move your assets from Tanssi to Ethereum and vice versa through a secure and user-friendly web interface available at the [Tanssi dApp](https://apps.tanssi.network/bridge){target=\_blank}, making cross-chain transfers accessible for everyone. ## Prerequisites {: #prerequisites } Before using the Tanssi bridge, ensure you have: For bridging from Tanssi to Ethereum: - A [Substrate-compatible wallet](/builders/toolkit/substrate-api/wallets/){target=\_blank}, such as [Talisman](/builders/toolkit/substrate-api/wallets/talisman/){target=\_blank}. - TANSSI (Substrate) balance to transfer and pay the bridging fees. - The Ethereum-type destination account. For bridging from Ethereum to Tanssi: - An [Ethereum-compatible wallet](/builders/toolkit/ethereum-api/wallets/){target=\_blank}, such as [MetaMask](/builders/toolkit/ethereum-api/wallets/metamask/){target=\_blank}. - TANSSI (ERC-20) balance to transfer. - ETH balance to pay the bridging fees. - The Substrate-type destination account. ## Bridging TANSSI Tokens to Ethereum {: #bridge-to-ethereum } If you want to convert your TANSSI (Substrate) tokens to TANSSI (ERC-20) on Ethereum, head to the Tanssi dApp, open the [bridge section](https://apps.tanssi.network/bridge){target=\_blank}, and then follow these steps: 1. Select **Mainnet** from the **From** dropdown. 2. Click on **Connect Wallet**. A pop-up will appear, allowing you to select your preferred Substrate wallet and choose the corresponding account. ![Select Tanssi Network and Connect the Wallet](/images/builders/interoperability/built-in-bridge/built-in-bridge-1.webp) Now, with your wallet connected: 1. Select the destination account from the **Select recipient address** dropdown, or choose the **Enter a custom address** item and enter the account where you want to receive the ERC-20 tokens manually. 2. Enter the amount to bridge in the **Balance** field. The estimated bridge and transaction fees will be displayed along with the amount the destination account will receive. 3. Click on **Send** and sign the transaction. ![Execute the Transaction](/images/builders/interoperability/built-in-bridge/built-in-bridge-2.webp) And that's it! Your tokens will be bridged when the next session starts. You can see how much time remains in the current session in the progress bar. !!! note - You can easily add the TANSSI ERC-20 contract address to your wallet by clicking the **+** icon shown next to your balance. - Fees to convert your TANSSI (Substrate) tokens to TANSSI (ERC-20) might fluctuate over time and must be paid using TANSSI. ## Bridging ERC-20 TANSSI to Tanssi Network {: #bridge-to-tanssi } If you want to convert your TANSSI (ERC-20) tokens to TANSSI (Substrate) native on the Tanssi network, head to the Tanssi dApp, open the [bridge section](https://apps.tanssi.network/bridge){target=\_blank}, and then follow these steps: 1. Select **Ethereum** from the **From** dropdown. 2. Click on **Connect Wallet**, select your preferred Ethereum wallet, and choose the account. ![Select Ethereum and Connect the Wallet](/images/builders/interoperability/built-in-bridge/built-in-bridge-3.webp) Now, with your wallet connected: 1. Enter the Substrate destination account in the **Recipient** field. 2. Enter the amount to bridge in the **Balance** field. The estimated bridge and transaction fees will be displayed along with the amount the destination account will receive. 3. Click on **Send** and sign the transaction. ![Execute the Transaction](/images/builders/interoperability/built-in-bridge/built-in-bridge-4.webp) And that's it! Your tokens will be bridged when the next session starts. You can see how much time remains in the current session in the progress bar. !!! note Fees to convert your TANSSI (ERC-20) tokens to TANSSI (Substrate) native on the Tanssi network might fluctuate over time and must be paid using ETH. --- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/tanssi-network/tanssi-token/ --- BEGIN CONTENT --- --- title: TANSSI Token description: Learn about the two versions of the Tanssi token - the native Substrate token and the ERC-20 representation on Ethereum, and their utilities and use cases. icon: octicons-ruby-24 categories: Basics --- # TANSSI Token {: #tanssi-token } ## Introduction {: #introduction } The Tanssi network token is the utility token that powers the Tanssi protocol. Considering [Tanssi's architecture](/learn/tanssi/overview/#tanssi-architecture){target=\_blank}, the token exists in two distinct yet interconnected representations: native substrate and Ethereum ERC-20. The two versions can be bridged between each other through the [Tanssi-Ethereum bridge](/learn/tanssi/tanssi-ethereum-bridge/){target=\_blank}. In this guide, the token's utility and the differences between its two representations are covered, which is crucial for network operators, stakers, appchain managers, and general users who want to participate in the Tanssi ecosystem. ## Token Utility {: #token-utility } Tanssi is a decentralized infrastructure protocol that makes deploying appchains with custom logic easy. It allows developers to focus on the use case instead of diverting time and energy to manage the [numerous components required](/learn/tanssi/overview/#what-tanssi-provides){target=\_blank} for a network to run smoothly. Running a healthy decentralized protocol not only requires a robust governance mechanism to ensure that decisions are made transparently but also aligning incentives and coordinating among several ecosystem actors, including appchain developers, node operators, sequencer operators, data availability and RPC providers, as well as general users. The Tanssi token serves as the backbone, providing the economic mechanisms necessary to coordinate, incentivize proper behavior, and secure the entire ecosystem. It enables a verifiable and code-enforced protocol evolution through a fully on-chain decision-making process. The token has several utilities: - **On-chain governance**: token holders can use the token to propose and vote in governance decisions, such as software upgrades, how to spend treasury funds, change protocol rules, and more. - **Appchain deployment**: use the token to register and launch your appchain in minutes. - **Sequencing as a service payment**: use the token to keep your appchain live. - **Sequencing and operator services rewarding**: get tokens as rewards for your nodes' services. - **Staking on sequencers**: token holders can stake on sequencers, getting rewards with no risk of slashing. - **Staking on operators**: token holders can stake on operators, getting rewards for their validation services. - **Fees payment**: use the token to pay the fees for interacting with the Tanssi network. !!! note All transaction fees on Tanssi are paid using the token, with the full amount going directly to fund the protocol's treasury account. These funds can only be spent via governance. ## Token Representations {: #token-representations } The Tanssi network is built using the Substrate framework, leveraging its modular architecture and high performance. Therefore, the native token is of a Substrate type. The protocol's minting and burning mechanisms happen on the Tanssi network side, or, in other words, happen on the Substrate token representation. Additionally, the Tanssi protocol relies on [external security providers](/learn/tanssi/external-security-providers/){target=\_blank}, such as [Symbiotic](/learn/tanssi/external-security-providers/symbiotic/){target=\_blank}, to secure the ecosystem through restaked assets. This restaking mechanism is implemented on Ethereum; therefore, an ERC-20 version of the token also exists to cover user cases on the Ethereum side. Leveraging Tanssi's [built-in bridging capabilities](/learn/tanssi/tanssi-ethereum-bridge/){target=\_blank}, the token can be converted to (and from) the ERC-20 representation on Ethereum. When the token is bridged to Ethereum, the tokens are locked in the bridge's sovereign account, and a message is sent to the Ethereum contract to mint the equivalent amount in ERC-20. This lock-and-mint mechanism ensures the ERC-20 version is created through a trustless bridging mechanism, maintaining a 1:1 relationship with the native token. ```mermaid flowchart LR subgraph Tanssi_Network ["Tanssi Network"] Tanssi_Substrate["$TANSSI (Substrate)"] Tanssi_Substrate_Utility["✓ On-chain governance ✓ Appchain deployment ✓ Sequencers rewarding ✓ Staking on sequencers ✓ Fees payment "] Tanssi_Substrate --> Tanssi_Substrate_Utility end subgraph Ethereum_Network ["Ethereum"] Tanssi_ERC20["$TANSSI (ERC-20)"] Tanssi_ERC20_Utility["✓ Operator services rewarding ✓ Staking on operators
 
"] Tanssi_ERC20 --> Tanssi_ERC20_Utility end Bridge["Trustless Bridge"] Tanssi_Network <--> Bridge <--> Ethereum_Network %% Apply custom style to utility nodes classDef utility_style fill: transparent, stroke: transparent, text-align: start; class Tanssi_Substrate_Utility,Tanssi_ERC20_Utility utility_style; %% Make utility arrows transparent linkStyle 0 stroke:transparent,fill:transparent; linkStyle 1 stroke:transparent,fill:transparent; ``` ### Tanssi (Substrate) - Native Token {: #tanssi-substrate } The native Tanssi token exists on the Tanssi network as a Substrate-based asset and is the original form of the token that powers the core protocol operations. This token uses as [Sr25519 subtrate-type account](/learn/tanssi/account-types/#key-types-in-tanssi-protocol){target=\_blank}, so it requires a wallet such as [Talisman](/builders/toolkit/substrate-api/wallets/talisman/){target=\_blank} or any other [substrate-compatible wallet](/builders/toolkit/substrate-api/wallets/){target=\_blank}. !!! note The Tanssi (Substrate) native token has twelve (12) decimal places. ### Tanssi (ERC-20) - Ethereum Representation {: #tanssi-erc-20 } Tanssi's ERC-20 version is a standard Ethereum token that represents the native token on the Ethereum network. This version is created through the trustless bridging mechanism, utilizing a lock-and-mint strategy, thereby maintaining a 1:1 relationship with the native token. This token, like any other Ethereum asset, uses an [ECDSA account](/learn/tanssi/account-types/#key-types-in-tanssi-protocol){target=\_blank}, so it requires a wallet such as [Metamask](/builders/toolkit/ethereum-api/wallets/metamask/){target=\_blank} or any other [Ethereum-compatible wallet](/builders/toolkit/ethereum-api/wallets/){target=\_blank}. !!! note The Tanssi (ERC-20) has twelve (12) decimal places. ### Tanssi (Substrate) and Tanssi (ERC-20) Comparison {: #substrate-erc-20-comparison } To better understand the differences between the two token representations, the following table provides a summary of their main features: | **Feature** | **Tanssi (Substrate)** | **Tanssi (ERC-20)** | |------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **Network** | Tanssi Network | Ethereum MainNet | | **Token Standard** | Native Substrate asset | ERC-20 standard token | | **Decimal Places** | Twelve (12) decimals | Twelve (12) decimals | | **Account Type** | [Sr25519](https://wiki.polkadot.network/learn/learn-cryptography/#keypairs-and-signing){target=_blank} | [ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm){target=_blank} | | **Compatible Wallets** | [Talisman](/builders/toolkit/substrate-api/wallets/talisman/){target=\_blank}, [SubWallet](/builders/toolkit/substrate-api/wallets/subwallet/){target=\_blank}, and others | [MetaMask](/builders/toolkit/ethereum-api/wallets/metamask/){target=\_blank}, [Talisman](/builders/toolkit/ethereum-api/wallets/talisman/){target=\_blank}, and other Ethereum-compatible wallets | | **Primary Utilities** | - On-chain governance participation
- Appchain registration and deployment
- Sequencing services payment
- Transaction fees on Tanssi network
- Staking on sequencers
- Sequencer operation rewards | - Operator validation rewards
- Staking on operators | | **Staking Options** | Sequencer staking (for keeping appchain liveness) | Operator staking (for validating/securing the entire Tanssi ecosystem) | | **Bridge Conversion** | Can be bridged to ERC-20, paying fees in $TANSSI (Substrate) | Can be bridged to Substrate, paying fees in $ETH | --- END CONTENT --- ## Reference Concepts [shared: true] The following section contains reference material for Tanssi. It includes network endpoints, JSON RPC methods, and contract or token addresses. While it may not be required for all use cases, it offers a deeper technical layer for advanced development work. --- ## List of shared concept pages: ## Full content for shared concepts: Doc-Content: https://docs.tanssi.network/builders/tanssi-network/endpoints/ --- BEGIN CONTENT --- --- title: Network Endpoints description: Tanssi networks have two endpoints available for users to connect to, one for HTTPS and one for WSS. This page has the RPC endpoints you need to get started. icon: octicons-share-android-24 categories: Reference --- ## Network Endpoints Tanssi networks have two endpoints available for users to connect to: one for HTTPS and one for WSS. ## Tanssi MainNet The Tanssi Network MainNet HTTPS and WSS endpoints are as follows: === "HTTPS" ```text https://{{ networks.mainnet.dns_name }} ``` === "WSS" ```text wss://{{ networks.mainnet.dns_name }} ``` ## Dancelight The Tanssi TestNet HTTPS and WSS endpoints are as follows: === "HTTPS" ```text https://{{ networks.dancelight.dns_name }} ``` === "WSS" ```text wss://{{ networks.dancelight.dns_name }} ``` ### Demo EVM Network The demo EVM network HTTPS and WSS endpoints are as follows: === "HTTPS" ```text {{ networks.dancelight.demo_evm_rpc_url }} ``` === "WSS" ```text {{ networks.dancelight.demo_evm_rpc_wss_url }} ``` --- END CONTENT --- Doc-Content: https://docs.tanssi.network/builders/toolkit/ethereum-api/rpc/ --- BEGIN CONTENT --- --- title: JSON-RPC API Methods description: Learn about the supported JSON-RPC API methods for querying your Tanssi EVM network, including standard Ethereum methods and custom methods unique to Tanssi. icon: material-code-json categories: Reference --- # JSON-RPC API Methods ## Standard Ethereum JSON-RPC Methods {: #standard-rpc-methods } As Tanssi's EVM Compatibility is derived from [Frontier](https://github.com/polkadot-evm/frontier){target=\_blank} and closely modeled after Moonbeam's Ethereum compatibility, Tanssi nodes support a wide variety of standard supported Ethereum JSON-RPC methods. Nevertheless, not all Ethereum JSON-RPC methods are supported; some of those supported return default values (those related to Ethereum's PoW consensus mechanism in particular). This guide provides a comprehensive list of supported Ethereum JSON-RPC methods on Tanssi. Developers can quickly reference this list to understand the available functionality for interfacing with Tanssi EVM networks. The basic JSON-RPC methods from the Ethereum API supported by Tanssi are: - **[eth_protocolVersion](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_protocolversion){target=\_blank}** — returns `1` by default - **[eth_syncing](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_syncing){target=\_blank}** — returns an object with data about the sync status or `false` - **[eth_hashrate](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_hashrate){target=\_blank}** — returns `"0x0"` by default - **[eth_coinbase](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_coinbase){target=\_blank}** — returns the latest block author. Not necessarily a finalized block - **[eth_mining](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_mining){target=\_blank}** — returns `false` by default - **[eth_chainId](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_chainid){target=\_blank}** — returns the chain ID used for signing at the current block - **[eth_gasPrice](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gasprice){target=\_blank}** — returns the base fee per unit of gas used. This is currently the minimum gas price for each network - **[eth_accounts](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_accounts){target=\_blank}** — returns a list of addresses owned by the client - **[eth_blockNumber](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_blocknumber){target=\_blank}** — returns the highest available block number - **[eth_getBalance](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getbalance){target=\_blank}** — returns the balance of the given address - **[eth_getStorageAt](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getstorageat){target=\_blank}** — returns the content of the storage at a given address - **[eth_getBlockByHash](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbyhash){target=\_blank}** — returns information about the block of the given hash, including `baseFeePerGas` on post-London blocks - **[eth_getBlockByNumber](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbynumber){target=\_blank}** — returns information about the block specified by block number, including `baseFeePerGas` on post-London blocks - **[eth_getBlockReceipts](https://www.alchemy.com/docs/node/ethereum/ethereum-api-endpoints/eth-get-block-receipts){target=\_blank}** — returns all transaction receipts for a given block - **[eth_getTransactionCount](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactioncount){target=\_blank}** — returns the number of transactions sent from the given address (nonce) - **[eth_getBlockTransactionCountByHash](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblocktransactioncountbyhash){target=\_blank}** — returns the number of transactions in a block with a given block hash - **[eth_getBlockTransactionCountByNumber](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblocktransactioncountbynumber){target=\_blank}** — returns the number of transactions in a block with a given block number - **[eth_getUncleCountByBlockHash](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getunclecountbyblockhash){target=\_blank}** — returns `"0x0"` by default - **[eth_getUncleCountByBlockNumber](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getunclecountbyblocknumber){target=\_blank}** — returns `"0x0"` by default - **[eth_getCode](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getcode){target=\_blank}** — returns the code at the given address at the given block number - **[eth_sendTransaction](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sendtransaction){target=\_blank}** — creates a new message call transaction or a contract creation, if the data field contains code. Returns the transaction hash or the zero hash if the transaction is not yet available - **[eth_sendRawTransaction](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sendrawtransaction){target=\_blank}** — creates a new message call transaction or a contract creation for signed transactions. Returns the transaction hash or the zero hash if the transaction is not yet available - **[eth_call](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call){target=\_blank}** — executes a new message call immediately without creating a transaction on the blockchain, returning the value of the executed call - **[eth_estimateGas](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_estimategas){target=\_blank}** — returns an estimated amount of gas necessary for a given transaction to succeed. You can optionally specify a `gasPrice` or `maxFeePerGas` and `maxPriorityFeePerGas` - **[eth_feeHistory](https://www.alchemy.com/docs/node/ethereum/ethereum-api-endpoints/eth-fee-history){target=\_blank}** — returns `baseFeePerGas`, `gasUsedRatio`, `oldestBlock`, and `reward` for a specified range of up to 1024 blocks - **[eth_getTransactionByHash](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionbyhash){target=\_blank}** — returns the information about a transaction with a given hash. EIP-1559 transactions have `maxPriorityFeePerGas` and `maxFeePerGas` fields - **[eth_getTransactionByBlockHashAndIndex](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionbyblockhashandindex){target=\_blank}** — returns information about a transaction at a given block hash and a given index position. EIP-1559 transactions have `maxPriorityFeePerGas` and `maxFeePerGas` fields - **[eth_getTransactionByBlockNumberAndIndex](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionbyblocknumberandindex){target=\_blank}** — returns information about a transaction at a given block number and a given index position. EIP-1559 transactions have `maxPriorityFeePerGas` and `maxFeePerGas` fields - **[eth_getTransactionReceipt](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionreceipt){target=\_blank}** — returns the transaction receipt of a given transaction hash - **[eth_getUncleByBlockHashAndIndex](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getunclebyblockhashandindex){target=\_blank}** — returns `null` by default - **[eth_getUncleByBlockNumberAndIndex](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getunclebyblocknumberandindex){target=\_blank}** — returns `null` by default - **[eth_getLogs](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getlogs){target=\_blank}** — returns an array of all logs matching a given filter object - **[eth_newFilter](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_newfilter){target=\_blank}** — creates a filter object based on the input provided. Returns a filter ID - **[eth_newBlockFilter](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_newblockfilter){target=\_blank}** — creates a filter in the node to notify when a new block arrives. Returns a filter ID - **[eth_getFilterChanges](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getfilterchanges){target=\_blank}** — polling method for filters (see methods above). Returns an array of logs that occurred since the last poll - **[eth_getFilterLogs](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getfilterlogs){target=\_blank}** — returns an array of all the logs matching the filter with a given ID - **[eth_uninstallFilter](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_uninstallfilter){target=\_blank}** — uninstall a filter with a given ID. It should be used when polling is no longer needed. Filters timeout when they are not requested using `eth_getFilterChanges` after some time ## Custom JSON-RPC Methods {: #custom-json-rpc-methods } Tanssi nodes support two custom JSON-RPC endpoints: `frnt_isBlockFinalized` and `frnt_isTxFinalized`. Tanssi features deterministic finality (as opposed to probabilistic like Bitcoin's finality), which means that at any point of time, the answer to whether a block or transaction is finalized or not can be answered with a definitive yes or no. Tanssi has built these two custom endpoints to provide valuable functionality for checking the finality of on-chain events. ???+ function "frnt_isBlockFinalized - checks for the finality of the block given by its block hash" === "Parameters" - `block_hash` ++"string"++ - the hash of the block, accepts either Substrate-style or Ethereum-style block hash as its input === "Returns" ++"boolean"++ - `true` if the block is finalized, `false` if the block is not finalized or not found === "Example" ```bash curl -H "Content-Type: application/json" -X POST --data '{ "jsonrpc": "2.0", "id": "1", "method": "frnt_isBlockFinalized", "params": ["INSERT_BLOCK_HASH"] }' {{ networks.dancelight.demo_evm_rpc_url }} ``` ???+ function "frnt_isTxFinalized - checks for the finality of a transaction given its EVM transaction hash" === "Parameters" - `tx_hash` ++"string"++ - the EVM transaction hash of the transaction === "Returns" ++"boolean"++ - `true` if the transaction is finalized, `false` if the transaction is not finalized or not found === "Example" ```bash curl -H "Content-Type: application/json" -X POST --data '{ "jsonrpc": "2.0", "id": "1", "method": "frnt_isTxFinalized", "params": ["INSERT_TRANSACTION_HASH"] }' {{ networks.dancelight.demo_evm_rpc_url }} ``` --- END CONTENT ---