From 9ea1ad0de87a68f43093027c73526732e5b578ac Mon Sep 17 00:00:00 2001
From: Antonoff <35700168+memearchivarius@users.noreply.github.com>
Date: Wed, 29 Jan 2025 12:50:21 +0300
Subject: [PATCH] MD Corrections & Op-code list transfer
Moving known op-codes to Message management, md formatting.
---
.../contracts-specs/wallet-contracts.md | 318 ++++++++----------
.../message-management/internal-messages.md | 144 +++++---
2 files changed, 246 insertions(+), 216 deletions(-)
diff --git a/docs/v3/documentation/smart-contracts/contracts-specs/wallet-contracts.md b/docs/v3/documentation/smart-contracts/contracts-specs/wallet-contracts.md
index 5c2bb8fa2b..aa5678fab9 100644
--- a/docs/v3/documentation/smart-contracts/contracts-specs/wallet-contracts.md
+++ b/docs/v3/documentation/smart-contracts/contracts-specs/wallet-contracts.md
@@ -9,9 +9,10 @@ In this article, we’ll explore the various versions and modifications of TON w
:::info
Before we start, there are some terms and concepts that you should be familiar with to fully understand the article:
- - [Message management](/v3/documentation/smart-contracts/message-management/messages-and-transactions), because this is the main functionality of the wallets.
- - [FunC language](/v3/documentation/smart-contracts/func/overview), because we will heavily rely on implementations made using it.
-:::
+
+- [Message management](/v3/documentation/smart-contracts/message-management/messages-and-transactions), because this is the main functionality of the wallets.
+- [FunC language](/v3/documentation/smart-contracts/func/overview), because we will heavily rely on implementations made using it.
+ :::
## Common concept
@@ -22,8 +23,7 @@ So the question is: what functionality do they provide and how it differs betwee
You can consider each wallet version as a smart-contract implementation providing a standard external interface, allowing different external clients to interact with the wallets in the same way. You can find these implementations in FunC and Fift languages in the main TON monorepo:
- * [ton/crypto/smartcont/](https://github.com/ton-blockchain/ton/blob/master/crypto/smartcont/)
-
+- [ton/crypto/smartcont/](https://github.com/ton-blockchain/ton/blob/master/crypto/smartcont/)
## Basic wallets
@@ -32,25 +32,29 @@ You can consider each wallet version as a smart-contract implementation providin
This is the simplest one. It only allows you to send four transactions at a time and doesn't check anything besides your signature and seqno.
Wallet source code:
- * [ton/crypto/smartcont/wallet-code.fif](https://github.com/ton-blockchain/ton/blob/master/crypto/smartcont/new-wallet.fif)
+
+- [ton/crypto/smartcont/wallet-code.fif](https://github.com/ton-blockchain/ton/blob/master/crypto/smartcont/new-wallet.fif)
This version isn’t even used in regular apps because it has some major issues:
- - No easy way to retrieve the seqno and public key from the contract.
- - No `valid_until` check, so you can't be sure that the transaction won't be confirmed too late.
+
+- No easy way to retrieve the seqno and public key from the contract.
+- No `valid_until` check, so you can't be sure that the transaction won't be confirmed too late.
The first issue was fixed in `V1R2` and `V1R3`. The `R` stands for "revision". Usually, revisions are just small updates that only add get methods; you can find all of those in the changes history of `new-wallet.fif`. Hereinafter, we will consider only the latest revisions.
Nevertheless, because each subsequent version inherits the functionality of the previous one, we should still stick to it, as this will help us with later versions.
#### Persistent memory layout
- - seqno: 32-bit long sequence number.
- - public-key: 256-bit long public key.
+
+- seqno: 32-bit long sequence number.
+- public-key: 256-bit long public key.
#### External message body layout
+
1. Data:
- - signature: 512-bit long ed25519 signature.
- - msg-seqno: 32-bit long sequence number.
- - (0-4)mode: up to four 8-bit long integer's defining sending mode for each message.
+ - signature: 512-bit long ed25519 signature.
+ - msg-seqno: 32-bit long sequence number.
+ - (0-4)mode: up to four 8-bit long integer's defining sending mode for each message.
2. Up to 4 references to cells containing messages.
As you can see, the main functionality of the wallet is to provide a safe way to communicate with the TON blockchain from the outside world. The `seqno` mechanism protects against replay attacks, and the `Ed25519 signature` provides authorized access to wallet functionality. We will not dwell in detail on each of these mechanisms, as they are described in detail in the [external message](/v3/documentation/smart-contracts/message-management/external-messages) documentation page and are quite common among smart contracts receiving external messages. The payload data consists of up to 4 references to cells and the corresponding number of modes, which will be directly transferred to the [send_raw_message(cell msg, int mode)](/v3/documentation/smart-contracts/func/docs/stdlib#send_raw_message) method.
@@ -60,36 +64,39 @@ Note that the wallet doesn't provide any validation for internal messages you se
:::
#### Exit codes
-| Exit code | Description |
-|----------------|-------------------------------------------------------------------|
-| 0x21 | `seqno` check failed, reply protection accured |
-| 0x22 | `Ed25519 signature` check failed |
-| 0x0 | Standard successful execution exit code. |
+
+| Exit code | Description |
+| --------- | ---------------------------------------------- |
+| 0x21 | `seqno` check failed, reply protection accured |
+| 0x22 | `Ed25519 signature` check failed |
+| 0x0 | Standard successful execution exit code. |
:::info
Note that [TVM](/v3/documentation/tvm/tvm-overview) has [standart exit codes](/v3/documentation/tvm/tvm-exit-codes) (`0x0` - is one of them), so you can get one of them too, if you run out of [gas](https://docs.ton.org/develop/smart-contracts/fees), for example, you will get `0xD` code.
:::
#### Get methods
+
1. int seqno() returns current stored seqno.
2. int get_public_key returns current stored public key.
### Wallet V2
Wallet source code:
-
- * [ton/crypto/smartcont/wallet-code.fc](https://github.com/ton-blockchain/ton/blob/master/crypto/smartcont/wallet-code.fc)
+
+- [ton/crypto/smartcont/wallet-code.fc](https://github.com/ton-blockchain/ton/blob/master/crypto/smartcont/wallet-code.fc)
This version introduces the `valid_until` parameter, which is used to set a time limit for a transaction in case you don't want it to be confirmed too late. This version also does not have the get-method for the public key, which was added in `V2R2`.
All differences compared to the previous version are a consequence of adding the `valid_until` functionality. A new exit code was added: `0x23`, marking the failure of the valid_until check. Additionally, a new UNIX-time field has been added to the external message body layout, setting the time limit for the transaction. All get methods remain the same.
#### External message body layout
+
1. Data:
- - signature: 512-bit long ed25519 signature.
- - msg-seqno: 32-bit long sequence number.
- - valid-until: 32-bit long Unix-time integer.
- - (0-4)mode: up to four 8-bit long integer's defining sending mode for each message.
+ - signature: 512-bit long ed25519 signature.
+ - msg-seqno: 32-bit long sequence number.
+ - valid-until: 32-bit long Unix-time integer.
+ - (0-4)mode: up to four 8-bit long integer's defining sending mode for each message.
2. Up to 4 references to cells containing messages.
### Wallet V3
@@ -97,39 +104,44 @@ All differences compared to the previous version are a consequence of adding the
This version introduces the `subwallet_id` parameter, which allows you to create multiple wallets using the same public key (so you can have only one seed phrase and multiple wallets). As before, `V3R2` only adds the get-method for the public key.
Wallet source code:
- * [ton/crypto/smartcont/wallet3-code.fc](https://github.com/ton-blockchain/ton/blob/master/crypto/smartcont/wallet3-code.fc)
+
+- [ton/crypto/smartcont/wallet3-code.fc](https://github.com/ton-blockchain/ton/blob/master/crypto/smartcont/wallet3-code.fc)
Essentially, `subwallet_id` is just a number added to the contract state when it’s deployed. Since the contract address in TON is a hash of its state and code, the wallet address will change with a different `subwallet_id`. This version is the most widely used right now. It covers most use cases and remains clean, simple, and mostly the same as previous versions. All get methods remain the same.
#### Persistent Memory Layout
+
- seqno: 32-bit sequence number.
- subwallet: 32-bit subwallet ID.
- public-key: 256-bit public key.
#### External Message Layout
+
1. Data:
- - signature: 512-bit ed25519 signature.
- - subwallet-id: 32-bit subwallet ID.
- - msg-seqno: 32-bit sequence number.
- - valid-until: 32-bit UNIX time integer.
- - (0-4)mode: Up to four 8-bit integers defining the sending mode for each message.
+ - signature: 512-bit ed25519 signature.
+ - subwallet-id: 32-bit subwallet ID.
+ - msg-seqno: 32-bit sequence number.
+ - valid-until: 32-bit UNIX time integer.
+ - (0-4)mode: Up to four 8-bit integers defining the sending mode for each message.
2. Up to 4 references to cells containing messages.
#### Exit Codes
-| Exit Code | Description |
-|----------------|--------------------------------------------------------------------------|
-| 0x23 | `valid_until` check failed; transaction confirmation attempted too late |
-| 0x23 | `Ed25519 signature` check failed |
-| 0x21 | `seqno` check failed; reply protection triggered |
-| 0x22 | `subwallet-id` does not match the stored one |
-| 0x0 | Standard successful execution exit code. |
+
+| Exit Code | Description |
+| --------- | ----------------------------------------------------------------------- |
+| 0x23 | `valid_until` check failed; transaction confirmation attempted too late |
+| 0x23 | `Ed25519 signature` check failed |
+| 0x21 | `seqno` check failed; reply protection triggered |
+| 0x22 | `subwallet-id` does not match the stored one |
+| 0x0 | Standard successful execution exit code. |
### Wallet V4
This version retains all the functionality of the previous versions but also introduces something very powerful: `plugins`.
Wallet source code:
- * [ton-blockchain/wallet-contract](https://github.com/ton-blockchain/wallet-contract)
+
+- [ton-blockchain/wallet-contract](https://github.com/ton-blockchain/wallet-contract)
This feature allows developers to implement complex logic that works in tandem with a user's wallet. For example, a DApp may require a user to pay a small amount of coins every day to use certain features. In this case, the user would need to install the plugin on their wallet by signing a transaction. The plugin would then send coins to the destination address daily when requested by an external message.
@@ -138,10 +150,11 @@ This feature allows developers to implement complex logic that works in tandem w
Plugins are essentially other smart contracts on TON that developers are free to implement as they wish. In relation to the wallet, they are simply addresses of smart contracts stored in a [dictionary](/v3/documentation/smart-contracts/func/docs/dictionaries) in the wallet's persistent memory. These plugins are allowed to request funds and remove themselves from the "allowed list" by sending internal messages to the wallet.
#### Persistent memory layout
- - seqno: 32-bit long sequence number.
- - subwallet-id: 32-bit long subwallet-id.
- - public-key: 256-bit long public key.
- - plugins: dictionary containing plugins(may be empty)
+
+- seqno: 32-bit long sequence number.
+- subwallet-id: 32-bit long subwallet-id.
+- public-key: 256-bit long public key.
+- plugins: dictionary containing plugins(may be empty)
#### Receiving internal messages
@@ -149,52 +162,57 @@ All previous versions of wallets had a straightforward implementation for receiv
- op-code?: 32-bit long operation code. This is an optional field; any message containing less than 32 bits in the message body, an incorrect op-code, or a sender address that isn't registered as a plugin will be considered as simple transfer, similar to previous wallet versions.
- query-id: 64-bit long integer. This field has no effect on the smart contract's behavior; it is used to track chains of messages between contracts.
+
1. op-code = 0x706c7567, request funds operation code.
- - toncoins: VARUINT16 amount of requested toncoins.
- - extra_currencies: Dictionary containing the amount of requested extra currencies (may be empty).
+ - toncoins: VARUINT16 amount of requested toncoins.
+ - extra_currencies: Dictionary containing the amount of requested extra currencies (may be empty).
2. op-code = 0x64737472, request removal of plugin-sender from the "allowed list".
#### External message body layout
- - signature: 512-bit long ed25519 signature.
- - subwallet-id: 32-bit long subwallet ID.
- - valid-until: 32-bit long Unix-time integer.
- - msg-seqno: 32-bit long sequence integer.
- - op-code: 32-bit long operation code.
+- signature: 512-bit long ed25519 signature.
+- subwallet-id: 32-bit long subwallet ID.
+- valid-until: 32-bit long Unix-time integer.
+- msg-seqno: 32-bit long sequence integer.
+- op-code: 32-bit long operation code.
+
1. op-code = 0x0, simple send.
- - (0-4)mode: up to four 8-bit long integer's defining sending mode for each message.
- - (0-4)messages:Up to four references to cells containing messages.
-2. op-code = 0x1, deploy and install plugin.
- - workchain: 8-bit long integer.
- - balance: VARUINT16 toncoins amount of initial balance.
- - state-init: Cell reference containing plugin initial state.
- - body: Cell reference containing body.
+ - (0-4)mode: up to four 8-bit long integer's defining sending mode for each message.
+ - (0-4)messages:Up to four references to cells containing messages.
+2. op-code = 0x1, deploy and install plugin.
+ - workchain: 8-bit long integer.
+ - balance: VARUINT16 toncoins amount of initial balance.
+ - state-init: Cell reference containing plugin initial state.
+ - body: Cell reference containing body.
3. op-code = 0x2/0x3, install plugin/remove plugin.
- - wc_n_address: 8-bit long workchain_id + 256-bit long plugin address.
- - balance: VARUINT16 toncoins amount of initial balance.
- - query-id: 64-bit long integer.
+ - wc_n_address: 8-bit long workchain_id + 256-bit long plugin address.
+ - balance: VARUINT16 toncoins amount of initial balance.
+ - query-id: 64-bit long integer.
As you can see, the fourth version still provides standard functionality through the `0x0` op-code, similar to previous versions. The `0x2` and `0x3` operations allow manipulation of the plugins dictionary. Note that in the case of `0x2`, you need to deploy the plugin with that address yourself. In contrast, the `0x1` op-code also handles the deployment process with the state_init field.
:::tip
If `state_init` doesn't make much sense from its name, take a look at the following references:
- * [addresses-in-ton-blockchain](/v3/documentation/smart-contracts/addresses#workchain-id-and-account-id)
- * [send-a-deploy-message](/v3/documentation/smart-contracts/func/cookbook#how-to-send-a-deploy-message-with-stateinit-only-with-stateinit-and-body)
- * [internal-message-layout](/v3/documentation/smart-contracts/message-management/sending-messages#message-layout)
-:::
+
+- [addresses-in-ton-blockchain](/v3/documentation/smart-contracts/addresses#workchain-id-and-account-id)
+- [send-a-deploy-message](/v3/documentation/smart-contracts/func/cookbook#how-to-send-a-deploy-message-with-stateinit-only-with-stateinit-and-body)
+- [internal-message-layout](/v3/documentation/smart-contracts/message-management/sending-messages#message-layout)
+ :::
#### Exit Codes
-| Exit Code | Description |
-|----------------|------------------------------------------------------------------------------|
-| 0x24 | `valid_until` check failed, transaction confirmation attempted too late |
-| 0x23 | `Ed25519 signature` check failed |
-| 0x21 | `seqno` check failed, reply protection triggered |
-| 0x22 | `subwallet-id` does not match the stored one |
-| 0x27 | Plugins dictionary manipulation failed (0x1-0x3 recv_external op-codes) |
-| 0x50 | Not enough funds for the funds request |
-| 0x0 | Standard successful execution exit code. |
+
+| Exit Code | Description |
+| --------- | ----------------------------------------------------------------------- |
+| 0x24 | `valid_until` check failed, transaction confirmation attempted too late |
+| 0x23 | `Ed25519 signature` check failed |
+| 0x21 | `seqno` check failed, reply protection triggered |
+| 0x22 | `subwallet-id` does not match the stored one |
+| 0x27 | Plugins dictionary manipulation failed (0x1-0x3 recv_external op-codes) |
+| 0x50 | Not enough funds for the funds request |
+| 0x0 | Standard successful execution exit code. |
#### Get methods
+
1. int seqno() returns current stored seqno.
2. int get_public_key() returns current stored public key.
3. int get_subwallet_id() returns current subwallet ID.
@@ -206,8 +224,8 @@ If `state_init` doesn't make much sense from its name, take a look at the follow
It is the most modern wallet version at the moment, developed by the Tonkeeper team, aimed at replacing V4 and allowing arbitrary extensions.