Skip to content

Commit c5465be

Browse files
Merge pull request tonkeeper#28 from tolya-yanot/main
Ton Core Team updates
2 parents d373fb0 + 5962103 commit c5465be

29 files changed

+5208
-1784
lines changed

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
node_modules
22
temp
3-
build
43
.idea
54
.env

Specification.md

+2-70
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Authentication:
4242

4343
Operations:
4444
* standard "send message" action (up to 255 messages at once),
45-
* enable/disable signature authentication,
45+
* enable/disable signature authentication (can be invoked only by extension),
4646
* install/remove extension.
4747

4848
Signed messages can be delivered both by external and internal messages.
@@ -111,77 +111,9 @@ When wallet contract is being deployed, original code hash is being used as the
111111
Library contract itself data and code are empty cells. That leads to the inability to change the library code, delete the contract, or withdraw funds from it.
112112
Therefore, any Wallet V5 user can top up the library contract balance if they are afraid that the library code of their wallet will be frozen.
113113

114-
## Wallet ID
115-
116-
Wallet ID disambiguates requests signed with the same public key to different wallet versions (V3/V4/V5) or wallets deployed on different chains.
117-
118-
For Wallet V5 we suggest using the following wallet ID:
119-
120-
```
121-
wallet_id$_ global_id:int32 wc:int8 version:(## 8) subwallet_number:(## 32) = WalletID;
122-
```
123-
124-
- `global_id` is a TON chain identifier. TON Mainnet `global_id = -239` and TON Testnet `global_id = -3`.
125-
- `wc` is a Workchain. -1 for Masterchain and 0 for Basechain.
126-
- `version`: current version of wallet v5 is `0`.
127-
- `subwallet_number` can be used to get multiple wallet contracts bound to the single keypair.
128-
129-
## Packed address
130-
131-
To make authorize extensions efficiently we compress 260-bit address (workchain + sha256 of stateinit) into a 256-bit integer:
132-
133-
```
134-
int addr = addr_hash ^ (wc + 1)
135-
```
136-
137-
Previously deployed wallet v4 was packing the address into a cell which costs ≈500 gas, while access to dictionary costs approximately `120*lg2(N)` in gas, that is serialization occupies more than half of the access cost for wallets with up to 16 extensions. This design makes packing cost around 50 gas and allows cutting the authentication cost 2-3x for reasonably sized wallets.
138-
139-
As of 2023 TON network consists of two workchains: -1 (master) and 0 (base). This means that the proposed address packing reduces second-preimage resistance of sha256 by 1 bit which we consider negligible. Even if the network is expanded with 254 more workchains in a distant future, our scheme would reduce security of extension authentication by only 8 bits down to 248 bits. Note that birthday attack is irrelevant in our setting as the user agent is not installing random extensions, although the security margin is plenty anyway (124 bits).
140-
141-
142-
143114
## TL-B definitions
144115

145-
Action types:
146-
147-
```tl-b
148-
// Standard actions from block.tlb:
149-
out_list_empty$_ = OutList 0;
150-
out_list$_ {n:#} prev:^(OutList n) action:OutAction = OutList (n + 1);
151-
action_send_msg#0ec3c86d mode:(## 8) out_msg:^(MessageRelaxed Any) = OutAction;
152-
153-
// Extended actions in W5:
154-
action_list_basic$0 {n:#} actions:^(OutList n) = ActionList n 0;
155-
action_list_extended$1 {m:#} {n:#} action:ExtendedAction prev:^(ActionList n m) = ActionList n (m+1);
156-
157-
action_add_ext#1c40db9f addr:MsgAddressInt = ExtendedAction;
158-
action_delete_ext#5eaef4a4 addr:MsgAddressInt = ExtendedAction;
159-
action_set_signature_auth_allowed#20cbb95a allowed:(## 1) = ExtendedAction;
160-
```
161-
162-
Authentication modes:
163-
164-
```tl-b
165-
signed_request$_ // 32 (opcode from outer)
166-
wallet_id: WalletID // 80
167-
valid_until: # // 32
168-
msg_seqno: # // 32
169-
inner: InnerRequest // 1 .. (1 + 32 + 256) + ^Cell
170-
signature: bits512 // 512
171-
= SignedRequest; // Total: 688 .. 976 + ^Cell
172-
173-
internal_signed#73696e74 signed:SignedRequest = InternalMsgBody;
174-
internal_extension#6578746e inner:InnerRequest = InternalMsgBody;
175-
external_signed#7369676e signed:SignedRequest = ExternalMsgBody;
176-
177-
actions$_ {m:#} {n:#} actions:(ActionList n m) = InnerRequest;
178-
```
179-
180-
Contract state:
181-
```tl-b
182-
wallet_id$_ global_id:# wc:int8 version:(## 8) subwallet_number:# = WalletID;
183-
contract_state$_ seqno:int33 wallet_id:WalletID public_key:(## 256) extensions_dict:(HashmapE 256 int8) = ContractState;
184-
```
116+
See `types.tlb`.
185117

186118
## Source code
187119

build/library-deployer.compiled.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"hash":"7b886902938fda7f8ee72fe31ee250744bf82489579c0b8e502105a49cb72e2a","hashBase64":"e4hpApOP2n+O5y/jHuJQdEv4JIlXnAuOUCEFpJy3Lio=","hex":"b5ee9c72410106010030000114ff00f4a413f4bcf2c80b0102012002050202d1030400053c006000193b511cbec1b232483ec13b55200006f2f0014136d496"}

build/wallet_v5.compiled.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"hash":"20834b7b72b112147e1b2fb457b84e74d1a30f04f737d4f62a668e9552d2b72f","hashBase64":"IINLe3KxEhR+Gy+0V7hOdNGjDwT3N9T2KmaOlVLSty8=","hex":"b5ee9c7241021401000281000114ff00f4a413f4bcf2c80b01020120020d020148030402dcd020d749c120915b8f6320d70b1f2082106578746ebd21821073696e74bdb0925f03e082106578746eba8eb48020d72101d074d721fa4030fa44f828fa443058bd915be0ed44d0810141d721f4058307f40e6fa1319130e18040d721707fdb3ce03120d749810280b99130e070e2100f020120050c020120060902016e07080019adce76a2684020eb90eb85ffc00019af1df6a2684010eb90eb858fc00201480a0b0017b325fb51341c75c875c2c7e00011b262fb513435c280200019be5f0f6a2684080a0eb90fa02c0102f20e011e20d70b1f82107369676ebaf2e08a7f0f01e68ef0eda2edfb218308d722028308d723208020d721d31fd31fd31fed44d0d200d31f20d31fd3ffd70a000af90140ccf9109a28945f0adb31e1f2c087df02b35007b0f2d0845125baf2e0855036baf2e086f823bbf2d0882292f800de01a47fc8ca00cb1f01cf16c9ed542092f80fde70db3cd81003f6eda2edfb02f404216e926c218e4c0221d73930709421c700b38e2d01d72820761e436c20d749c008f2e09320d74ac002f2e09320d71d06c712c2005230b0f2d089d74cd7393001a4e86c128407bbf2e093d74ac000f2e093ed55e2d20001c000915be0ebd72c08142091709601d72c081c12e25210b1e30f20d74a111213009601fa4001fa44f828fa443058baf2e091ed44d0810141d718f405049d7fc8ca0040048307f453f2e08b8e14038307f45bf2e08c22d70a00216e01b3b0f2d090e2c85003cf1612f400c9ed54007230d72c08248e2d21f2e092d200ed44d0d2005113baf2d08f54503091319c01810140d721d70a00f2e08ee2c8ca0058cf16c9ed5493f2c08de20010935bdb31e1d74cd0b4d6c35e"}

contracts/imports/stdlib.fc

+26-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
;; Standard library for funC
22
;;
33

4+
{-
5+
This file is part of TON FunC Standard Library.
6+
7+
FunC Standard Library is free software: you can redistribute it and/or modify
8+
it under the terms of the GNU Lesser General Public License as published by
9+
the Free Software Foundation, either version 2 of the License, or
10+
(at your option) any later version.
11+
12+
FunC Standard Library is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
GNU Lesser General Public License for more details.
16+
17+
-}
18+
419
{-
520
# Tuple manipulation primitives
621
The names and the types are mostly self-explaining.
@@ -26,7 +41,7 @@ forall X -> tuple cons(X head, tuple tail) asm "CONS";
2641
forall X -> (X, tuple) uncons(tuple list) asm "UNCONS";
2742

2843
;;; Extracts the tail and the head of lisp-style list.
29-
forall X -> (tuple, X) list_next(tuple list) asm( -> 1 0) "UNCONS";
44+
forall X -> (tuple, X) list_next(tuple list) asm(-> 1 0) "UNCONS";
3045

3146
;;; Returns the head of lisp-style list.
3247
forall X -> X car(tuple list) asm "CAR";
@@ -244,11 +259,9 @@ cont bless(slice s) impure asm "BLESS";
244259
() commit() impure asm "COMMIT";
245260

246261
;;; Not implemented
247-
;;() buy_gas(int gram) impure asm "BUYGAS";
248-
249262
;;; Computes the amount of gas that can be bought for `amount` nanoTONs,
250263
;;; and sets `gl` accordingly in the same way as [set_gas_limit].
251-
() buy_gas(int amount) impure asm "BUYGAS";
264+
;;() buy_gas(int amount) impure asm "BUYGAS";
252265

253266
;;; Computes the minimum of two integers [x] and [y].
254267
int min(int x, int y) asm "MIN";
@@ -285,12 +298,12 @@ slice begin_parse(cell c) asm "CTOS";
285298
() end_parse(slice s) impure asm "ENDS";
286299

287300
;;; Loads the first reference from the slice.
288-
(slice, cell) load_ref(slice s) asm( -> 1 0) "LDREF";
301+
(slice, cell) load_ref(slice s) asm(-> 1 0) "LDREF";
289302

290303
;;; Preloads the first reference from the slice.
291304
cell preload_ref(slice s) asm "PLDREF";
292305

293-
{- Functions below are commented because are implemented on compilator level for optimisation -}
306+
{- Functions below are commented because are implemented on compilator level for optimisation -}
294307

295308
;;; Loads a signed [len]-bit integer from a slice [s].
296309
;; (slice, int) ~load_int(slice s, int len) asm(s len -> 1 0) "LDIX";
@@ -311,8 +324,8 @@ cell preload_ref(slice s) asm "PLDREF";
311324
;; slice preload_bits(slice s, int len) asm "PLDSLICEX";
312325

313326
;;; Loads serialized amount of TonCoins (any unsigned integer up to `2^128 - 1`).
314-
(slice, int) load_grams(slice s) asm( -> 1 0) "LDGRAMS";
315-
(slice, int) load_coins(slice s) asm( -> 1 0) "LDGRAMS";
327+
(slice, int) load_grams(slice s) asm(-> 1 0) "LDGRAMS";
328+
(slice, int) load_coins(slice s) asm(-> 1 0) "LDVARUINT16";
316329

317330
;;; Returns all but the first `0 ≤ len ≤ 1023` bits of `slice` [s].
318331
slice skip_bits(slice s, int len) asm "SDSKIPFIRST";
@@ -330,7 +343,7 @@ slice slice_last(slice s, int len) asm "SDCUTLAST";
330343

331344
;;; Loads a dictionary `D` (HashMapE) from `slice` [s].
332345
;;; (returns `null` if `nothing` constructor is used).
333-
(slice, cell) load_dict(slice s) asm( -> 1 0) "LDDICT";
346+
(slice, cell) load_dict(slice s) asm(-> 1 0) "LDDICT";
334347

335348
;;; Preloads a dictionary `D` from `slice` [s].
336349
cell preload_dict(slice s) asm "PLDDICT";
@@ -342,7 +355,7 @@ slice skip_dict(slice s) asm "SKIPDICT";
342355
;;; In other words loads 1 bit and if it is true
343356
;;; loads first ref and return it with slice remainder
344357
;;; otherwise returns `null` and slice remainder
345-
(slice, cell) load_maybe_ref(slice s) asm( -> 1 0) "LDOPTREF";
358+
(slice, cell) load_maybe_ref(slice s) asm(-> 1 0) "LDOPTREF";
346359

347360
;;; Preloads (Maybe ^Cell) from `slice` [s].
348361
cell preload_maybe_ref(slice s) asm "PLDOPTREF";
@@ -434,7 +447,7 @@ builder store_slice(builder b, slice s) asm "STSLICER";
434447
;;;
435448
;;; Store amounts of TonCoins to the builder as VarUInteger 16
436449
builder store_grams(builder b, int x) asm "STGRAMS";
437-
builder store_coins(builder b, int x) asm "STGRAMS";
450+
builder store_coins(builder b, int x) asm "STVARUINT16";
438451

439452
;;; Stores dictionary `D` represented by `cell` [c] or `null` into `builder` [b].
440453
;;; In other words, stores a `1`-bit and a reference to [c] if [c] is not `null` and `0`-bit otherwise.
@@ -485,7 +498,7 @@ builder store_maybe_ref(builder b, cell c) asm(c b) "STOPTREF";
485498

486499
;;; Loads from slice [s] the only prefix that is a valid `MsgAddress`,
487500
;;; and returns both this prefix `s'` and the remainder `s''` of [s] as slices.
488-
(slice, slice) load_msg_addr(slice s) asm( -> 1 0) "LDMSGADDR";
501+
(slice, slice) load_msg_addr(slice s) asm(-> 1 0) "LDMSGADDR";
489502

490503
;;; Decomposes slice [s] containing a valid `MsgAddress` into a `tuple t` with separate fields of this `MsgAddress`.
491504
;;; If [s] is not a valid `MsgAddress`, a cell deserialization exception is thrown.
@@ -618,8 +631,6 @@ int get_seed() impure asm "RANDSEED";
618631
() randomize_lt() impure asm "LTIME" "ADDRAND";
619632

620633
;;; Checks whether the data parts of two slices coinside
621-
int equal_slice_bits(slice a, slice b) asm "SDEQ";
622-
int equal_slices(slice a, slice b) asm "SDEQ";
623-
634+
int equal_slices_bits(slice a, slice b) asm "SDEQ";
624635
;;; Concatenates two builders
625636
builder store_builder(builder to, builder from) asm "STBR";

0 commit comments

Comments
 (0)