Больше года назад стало известно о планах мессенджера Telegram выпустить собственную децентрализованную сеть Telegram Open Network. Тогда стал доступен объемный технический документ, который, предположительно, был написан Николаем Дуровым и описывал структуру будущей сети. Для тех, кто пропустил — рекомендую ознакомиться с моим пересказом этого документа (часть 1, часть 2; третья часть, увы, всё ещё пылится в черновиках).


С тех пор никаких значимых новостей о статусе разработки TON не было, пока пару дней назад (в одном из неофициальных каналов) не появилась ссылка на страницу https://test.ton.org/download.html, где размещены:


? ton-test-liteclient-full.tar.xz — исходники лёгкого клиента для тестовой сети TON;
? ton-lite-client-test1.config.json — конфигурационный файл для подключения к тестовой сети;
? README — информация о сборке и запуске клиента;
? HOWTO — пошаговая инструкция о создании смарт-контракта с помощью клиента;
? ton.pdf — обновлённый документ (от 2 марта 2019 г.) с техническим обзором сети TON;
? tvm.pdf — техническое описание TVM (TON Virtual Machine, виртуальной машины TON);
? tblkch.pdf — техническое описание блокчейна TON;
? fiftbase.pdf — описание нового языка Fift, предназначенного для создания смарт-контрактов в TON.


Повторюсь, официальных подтверждений страницы и всех этих документов со стороны Телеграма не было, но объем этих материалов делает их достаточно правдоподобными. Запуск опубликованного клиента совершайте на свой страх и риск.


Сборка тестового клиента


Для начала попробуем собрать и запустить тестовый клиент — благо, README подробно описывает этот несложный процесс. Я буду это делать на примере macOS 10.14.5, за успешность сборки на других системах ручаться не могу.


  1. Скачиваем и распаковываем архив с исходниками. Важно скачивать последнюю версию, так как обратная совместимость на данном этапе не гарантируется.


  2. Убеждаемся, что в системе установлены последние версии make, cmake (версии 3.0.2 или выше), OpenSSL (включая заголовочные файлы C), g++ или clang. Мне ничего доустанавливать не пришлось, всё собралось сразу.


  3. Предположим, исходники распакованы в папку ~/lite-client. Отдельно от неё создаём пустую папку для собранного проекта (например, ~/liteclient-build), и из неё (cd ~/liteclient-build) вызываем команды:


    cmake ~/lite-client
    cmake --build . --target test-lite-client

    Успешная сборка клиента

    Для сборки интерпретатора языка Fift для смарт-контрактов (о нём ниже), также вызываем


    cmake --build . --target fift

  4. Скачиваем актуальный конфигурационный файл для подключения к тестовой сети и кладём его в папку с собранным клиентом.


  5. Готово, можно запустить клиент:


    ./test-lite-client -C ton-lite-client-test1.config.json


Если всё сделано правильно, то вы должны увидеть что-то такое:


Запуск клиента


Доступных команд, как видим, немного:


? help — вывести этот список команд;
? quit — выйти;
? time — показать текущее время на сервере;
? status — показать состояние подключения и локальной БД;
? last — обновить состояние блокчейна (загрузить последний блок). Эту команду важно выполнять перед любыми запросами, чтобы быть уверенным, что вы видите именно актуальное состояние сети.
? sendfile <filename> — загрузить локальный файл в сеть TON. Так происходит взаимодействие с сетью — в том числе, например, создание новых смарт-контрактов и запросы на перевод средств между аккаунтами;
? getaccount <address> — показать текущее (на момент выполнения команды last) состояние аккаунта с указанным адресом;
? privkey <filename> — загрузить приватный ключ из локального файла.


Если при запуске клиента передать ему папку с помощью опции -D, то он будет складывать в неё последний блок мастерчейна:


./test-lite-client -C ton-lite-client-test1.config.json -D ~/ton-db-dir

Теперь можем перейти к более интересным вещам — изучить язык Fift, попробовать скомпилировать смарт-контракт (например, создать тестовый кошелёк), загрузить его в сеть и попробовать перевод средств между аккаунтами.


Язык Fift


Из документа fiftbase.pdf можно узнать, что для создания смарт-контрактов команда Telegram создала новый стековый язык Fift (видимо, от числительного fifth, по аналогии с Forth — языком, с которым у Fift много общего).


Документ достаточно объемный, на 87 страниц, и я не стану подробно пересказывать его содержание в рамках этой статьи (как минимум, потому что сам не закончил его чтение :). Остановлюсь на основных моментах и приведу пару примеров кода на этом языке.


На базовом уровне, синтаксис Фифта достаточно прост: его код состоит из слов, как правило, разделённых пробелами или переводами строк (частный случай: некоторые слова не требуют разделителя после себя). Любое слово — это регистро-зависимая последовательность символов, которой соответствует некоторое определение (грубо говоря, то, что интерпретатор должен сделать, когда встречает это слово). Если определения слова нет, интерпретатор пытается распарсить его как число и положить на стек. Кстати, числа тут — внезапно — 257-битные целые, а дробных нет совсем — точнее, они сразу превращаются в пару целых, образующих числитель и знаменатель рациональной дроби.


Слова, как правило, взаимодействуют со значениями, лежащими на верхушке стека. Отдельный тип слов — префиксный — использует не стек, а последующие за ними символы из исходного файла. Например, так реализованы строковые литералы — символ «кавычка» (") является префиксным словом, которое ищет следующую (закрывающую) кавычку, и помещает строку между ними на стек. Подобным же образом ведут себя однострочные (//) и многострочные (/*) комментарии.


На этом почти всё внутреннее устройство языка заканчивается. Всё остальное (включая управляющие конструкции) определено как слова (либо внутренние, такие как арифметические операции и определение новых слов; либо определённые в «стандартной библиотеке» Fift.fif, которая лежит в папке crypto/fift в исходниках).


Простой пример программы на Fift:


{ dup =: x dup * =: y } : setxy
3 setxy x . y . x y + .
7 setxy x . y . x y + .

В первой строчке определяется новое слово setxy (обратите внимание на префикс {, который создает блок до закрывающего } и префикс :, который собственно определяет слово). setxy берёт число с вершины стека, определяет (или переопределяет) его как глобальную константу x, а квадрат этого числа — как константу y (учитывая, что значения констант можно переопределять, я бы скорее назвал их переменными, но я следую именованию в языке).


В следующих двух строчках на стек кладётся число, вызывается setxy, затем выводятся значения констант x, y (для вывода используется слово .), обе константы помещаются на стек, суммируются и результат тоже выводится. В результате мы увидим:


3 9 12 ok
7 49 56 ok

(Строчку «ok» выводит интерпретатор, когда заканчивает обрабатывать текущую строку в интерактивном режиме ввода)


Ну и полноценный пример кода:


"Asm.fif" include

-1 constant wc  // create a wallet in workchain -1 (masterchain)

// Create new simple wallet
<{  SETCP0 DUP IFNOTRET INC 32 THROWIF  // return if recv_internal, fail unless recv_external
    512 INT LDSLICEX DUP 32 PLDU   // sign cs cnt
    c4 PUSHCTR CTOS 32 LDU 256 LDU ENDS  // sign cs cnt cnt' pubk
    s1 s2 XCPU            // sign cs cnt pubk cnt' cnt
    EQUAL 33 THROWIFNOT   // ( seqno mismatch? )
    s2 PUSH HASHSU        // sign cs cnt pubk hash
    s0 s4 s4 XC2PU        // pubk cs cnt hash sign pubk
    CHKSIGNU              // pubk cs cnt ?
    34 THROWIFNOT         // signature mismatch
    ACCEPT
    SWAP 32 LDU NIP 
    DUP SREFS IF:<{
      8 LDU LDREF         // pubk cnt mode msg cs
      s0 s2 XCHG SENDRAWMSG  // pubk cnt cs ; ( message sent )
    }>
    ENDS
    INC NEWC 32 STU 256 STU ENDC c4 POPCTR
}>c
// code
<b 0 32 u, 
   newkeypair swap dup constant wallet_pk 
   "new-wallet.pk" B>file
   B, 
b> // data
// no libraries
<b b{00110} s, rot ref, swap ref, b>  // create StateInit
dup ."StateInit: " <s csr. cr
dup hash dup constant wallet_addr
."new wallet address = " wc . .": " dup x. cr
wc over 7 smca>$ type cr
256 u>B "new-wallet.addr" B>file
<b 0 32 u, b>
dup ."signing message: " <s csr. cr
dup hash wallet_pk ed25519_sign_uint rot
<b b{1000100} s, wc 8 i, wallet_addr 256 u, b{000010} s, swap <s s, b{0} s, swap B, swap <s s, b>
dup ."External message for initialization is " <s csr. cr
2 boc+>B dup Bx. cr
"new-wallet-query.boc" tuck B>file
."(Saved to file " type .")" cr

Этот страшновато выглядящий файл предназначен для создания смарт-контракта — он будет помещён в файл new-wallet-query.boc после выполнения. Обратите внимание, что тут используется ещё один, ассемблерный язык для TON Virtual Machine (на нём я не буду останавливаться подробно), инструкции которого и будут помещены в блокчейн.


Таким образом, ассемблер для TVM написан на Fift — исходники этого ассемблера находятся в файле crypto/fift/Asm.fif и подключаются в начале приведённого выше куска кода.


Что я могу сказать, видимо, Николай Дуров просто любит создавать новые языки программирования :)


Создание смарт-контракта и взаимодействие с TON


Итак, предположим, мы собрали клиент TON и интерпретатор Fift, как описано выше, и познакомились с языком. Как теперь создать смарт-контракт? Об этом рассказывается в файлике HOWTO, приложенном к исходникам.


Аккаунты в TON


Как я описывал в обзоре TON, эта сеть содержит больше одного блокчейна — есть один общий, т.н. «мастерчейн», а также произвольное количество дополнительных «воркчейнов», идентифицируемых 32-битным числом. Мастерчейн имеет идентификатор -1, кроме него так же может использоваться «базовый» воркчейн с идентификатором 0. У каждого воркчейна может быть своя конфигурация. Внутренне каждый воркчейн дробится на шардчейны, но это уже деталь реализации, которую необязательно держать в голове.


В пределах одного воркчейна хранится множество аккаунтов, у которых есть свои идентификаторы account_id. Для мастерчейна и нулевого воркчейна они имеют длину 256 бит. Таким образом, идентификатор аккаунта записывается, например, так:


-1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d

Это «сырой» формат: сначала идентификатор воркчейна, затем двоеточие, и идентификатор аккаунта в шестнадцатеричной записи.


Кроме того, есть укороченный формат — номер воркчейна и адрес аккаунта кодируются в бинарном виде, к ним дописывается контрольная сумма и всё это кодируется в Base64:


Ef+BVndbeTJeXWLnQtm5bDC2UVpc0vH2TF2ksZPAPwcODSkb

Зная этот формат записи, мы можем запросить текущее состояние какого-нибудь аккаунта через тестовый клиент с помощью команды


getaccount -1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d

Получим примерно такой ответ:


[ 3][t 2][1558746708.815218925][test-lite-client.cpp:631][!testnode]    requesting account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D
[ 3][t 2][1558746708.858564138][test-lite-client.cpp:652][!testnode]    got account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D with respect to blocks (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F and (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F
account state is (account
  addr:(addr_std
    anycast:nothing workchain_id:-1 address:x8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D)
  storage_stat:(storage_info
    used:(storage_used
      cells:(var_uint len:1 value:3)
      bits:(var_uint len:2 value:539)
      public_cells:(var_uint len:0 value:0)) last_paid:0
    due_payment:nothing)
  storage:(account_storage last_trans_lt:74208000003
    balance:(currencies
      grams:(nanograms
        amount:(var_uint len:7 value:999928362430000))
      other:(extra_currencies
        dict:hme_empty))
    state:(account_active
      (
        split_depth:nothing
        special:nothing
        code:(just
          value:(raw@^Cell 
            x{}
             x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54}
            ))
        data:(just
          value:(raw@^Cell 
            x{}
             x{0000000D}
            ))
        library:hme_empty))))
x{CFF8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D2068086C000000000000000451C90E00DC0E35B7DB5FB8C134_}
 x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54}
 x{0000000D}

Видим структуру, которая хранится в DHT указанного воркчейна. Например, в поле storage.balance находится текущий баланс аккаунта, в storage.state.code — код смарт-контракта, а в storage.state.data — его текущие данные. Обратите внимание, что хранилище данных TON — Cell, ячейки — является древовидным, у каждой ячейки могут быть как свои данные, так и дочерние ячейки. Это показано в виде отступов в последних строчках.


Сборка смарт-контракта


Теперь давайте создадим сами такую структуру (она называется BOC — bag of cells) с помощью языка Fift. К счастью, самостоятельно писать смарт-контракт не придётся — в папке crypto/block из архива с исходниками есть файл new-wallet.fif, который поможет создать нам новый кошелёк. Скопируем его в папку с собранным клиентом (~/liteclient-build, если вы действовали по инструкции выше). Его же содержимое я приводил выше в качестве примера кода на Fift.


Выполняем этот файл следующим образом:


./crypto/fift -I"<source-directory>/crypto/fift" new-wallet.fif

Здесь <source-directory> надо заменить на путь к распакованным исходникам (символ "~" тут, к сожалению, использовать нельзя, нужен полный путь). Вместо использования ключа -I можно определить переменную окружения FIFTPATH и поместить этот путь в неё.


Так как Fift мы запустили с именем файла new-wallet.fif, он выполнит его и завершится. Если имя файла опустить, то можно поиграть с интерпретатором в интерактивном режиме.


В консоль после выполнения должно вывестись что-то такое:


StateInit: x{34_}
 x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54}
 x{0000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B}

new wallet address = -1 : 4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2 
0f9PzVILj8yglrVn1zS-NSjtxr7QBfaTCp7JrBqnFPIR8nhZ
signing message: x{00000000}

External message for initialization is x{89FEE120E20C7E953E31546F64C23CD654002C1AA919ADD24DB12DDF85C6F3B58AE41198A28AD8DAF3B9588E7A629252BA3DB88F030D00BC1016110B2073359EAC3C13823C53245B65D056F2C070B940CDA09789585935C7ABA4D2AD4BED139281CFA1200000001_}
 x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54}
 x{0000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B}

B5EE9C724104030100000000D60002CF89FEE120E20C7E953E31546F64C23CD654002C1AA919ADD24DB12DDF85C6F3B58AE41198A28AD8DAF3B9588E7A629252BA3DB88F030D00BC1016110B2073359EAC3C13823C53245B65D056F2C070B940CDA09789585935C7ABA4D2AD4BED139281CFA1200000001001020084FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED5400480000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B6290698B
(Saved to file new-wallet-query.boc)

Это означает, что кошелёк с идентификатором -1:4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2 (или, что то же самое, 0f9PzVILj8yglrVn1zS-NSjtxr7QBfaTCp7JrBqnFPIR8nhZ) успешно создан. Соответствующий ему код окажется в файле new-wallet-query.boc, его адрес — в new-wallet.addr, а приватный ключ — в new-wallet.pk (будьте осторожны — повторный запуск скрипта перезапишет эти файлы).


Конечно, сеть TON про этот кошелёк ещё не знает, он хранится только в виде этих файлов. Теперь его нужно загрузить в сеть. Правда, проблема в том, что для создания смарт-контракта нужно заплатить комиссию, а баланс у вашего аккаунта пока нулевой.


В рабочем режиме эта проблема решится покупкой грамов на бирже (или переводом с другого кошелька). Ну а в нынешнем тестовом режиме заведён специальный смарт-контракт, у которого можно попросить до 20 грам просто так.


Формирование запроса к чужому смарт-контракту


Запрос к смарт-контракту, раздающему грамы налево и направо, делаем так. Во всё той же папке crypto/block находим файл testgiver.fif:


// "testgiver.addr" file>B 256 B>u@ 
0x8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d
dup constant wallet_addr ."Test giver address = " x. cr

0x4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2
constant dest_addr

-1 constant wc
0x00000011 constant seqno

1000000000 constant Gram
{ Gram swap */ } : Gram*/

6.666 Gram*/ constant amount

// b x --> b'  ( serializes a Gram amount )
{ -1 { 1+ 2dup 8 * ufits } until
  rot over 4 u, -rot 8 * u, } : Gram, 

// create a message (NB: 01b00.., b = bounce)
<b b{010000100} s, wc 8 i, dest_addr 256 u, amount Gram, 0 9 64 32 + + 1+ 1+ u, "GIFT" $, b>
<b seqno 32 u, 1 8 u, swap ref, b>
dup ."enveloping message: " <s csr. cr
<b b{1000100} s, wc 8 i, wallet_addr 256 u, 0 Gram, b{00} s,
   swap <s s, b>
dup ."resulting external message: " <s csr. cr
2 boc+>B dup Bx. cr
"wallet-query.boc" B>file

Его тоже сохраним в папку с собранным клиентом, но поправим пятую строчку — перед строчкой "constant dest_addr". Заменим её на адрес того кошелька, который вы создали до этого (полный, не сокращённый). "-1:" в начале писать не нужно, вместо этого в начале поставьте "0x".


Ещё можно поменять строку 6.666 Gram*/ constant amount — это сумма в грамах, которую вы запрашиваете (не больше 20). Даже если указываете целое число, оставьте десятичную точку.


Наконец, нужно поправить строку 0x00000011 constant seqno. Первое число тут — это текущий sequence number, который хранится в аккаунте, выдающем грамы. Откуда его взять? Как говорилось выше, запустите клиент и выполните:


last
getaccount -1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d

В самом конце в данных смарт-контракта будет


...
x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54}
 x{0000000D}

Число 0000000D (у вас оно будет больше) и есть sequence number, который надо подставить в testgiver.fif.


Всё, сохраняем файл и запускаем (./crypto/fift testgiver.fif). На выходе получим файл wallet-query.boc. Это и есть сформированное сообщение к чужому смарт-контракту — просьба «переведи столько-то грам на такой-то аккаунт».


С помощью клиента загружаем его в сеть:


> sendfile wallet-query.boc
[ 1][t 1][1558747399.456575155][test-lite-client.cpp:577][!testnode]    sending query from file wallet-query.boc
[ 3][t 2][1558747399.500236034][test-lite-client.cpp:587][!query]   external message status is 1

Если теперь вызвать last, а затем снова запросить статус аккаунта, у которого мы попросили грамы, то мы должны увидеть, что его sequence number увеличился на единичку — это значит, что он отправил деньги нашему аккаунту.


Остался последний шаг — загружаем код нашего кошелька (баланс его уже пополнен, но без кода смарт-контракта мы не сможем им управлять). Выполняем sendfile new-wallet-query.boc — и всё, у вас есть собственный кошелёк в сети TON (пусть и пока лишь тестовой).


Создание исходящих транзакций


Чтобы переводить деньги с баланса созданного аккаунта, есть файл crypto/block/wallet.fif, который тоже нужно поместить в папку с собранным клиентом.


Аналогично предыдущим шагам, в нём нужно поправить сумму, которую вы переводите, адрес получателя (dest_addr), и seqno вашего кошелька (он равен 1 после инициализации кошелька и увеличивается на 1 после каждой исходящей транзакции — вы сможете увидеть его, запросив состояние своего аккаунта). Для тестов можете использовать, например, мой кошелёк — 0x4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2.


При запуске (./crypto/fift wallet.fif) скрипт возьмёт адрес вашего кошелька (откуда вы переводите) и его приватный ключ из файлов new-wallet.addr и new-wallet.pk, а полученное сообщение запишет в new-wallet-query.boc.


Как и раньше, чтобы непосредственно выполнить транзакцию, вызываем sendfile new-wallet-query.boc в клиенте. После этого не забываем обновить состояние блокчейна (last) и проверяем, что баланс и seqno нашего кошелька изменились (getaccount <account_id>).


Описание аккаунта


Вот и всё, теперь мы умеем создавать смарт-контракты в TON и отправлять к ним запросы. Как видим, нынешней функциональности уже достаточно, чтобы, например, сделать более дружелюбный кошелёк c графическим интерфейсом (впрочем, ожидается, что он и так станет доступен как часть мессенджера).

Комментарии (89)


  1. scam
    27.05.2019 21:42
    +6

    Николай Дуров, перелогиньтесь


  1. vtools
    27.05.2019 22:14
    +8

    Простите, но глядя на язык Fift так и хочется спросить: а вы точно не забыли поставить тег «Ненормальное программирование»?


    1. mr_tron
      27.05.2019 23:12

      Я так понимаю fift это нечто максимально приближенное к ассемблеру их виртуальной машины. И в него можно транслировать другие языки. Потом наверняка выкатят что-то более высокоуровневое. Разрабатывать непосредствено на fift что-то серьёзное это конечно смерть.
      Впрочем возможно просто тот же Николай Дуров лично напишет 1000 контрактов, покрывающие 99.9% потребностей юзеров и потом ещё десяток эзотериков будут пилить нестандартные контракты под редкие нужды.


      1. JekaMas
        28.05.2019 02:01
        +1

        Тогда надо будет доверять этому чудесному автору контрактов. И будет проблема, что мало экспертов, способных проверять контракты на безопасность. А это второе правило криптографии — публичная проверка.


        1. mr_tron
          28.05.2019 13:58

          Мало экспертов способны проверить и самопально шифрование телеграма. Но тем не менее телеграм растёт а особых уязвимостей слышно не было. В отличии от всем доступно исходного кода кошельков парити или того смартконтракта дао для эфира.
          Я понимаю, что в общем случае конечно публичный аудит всеми кем только можно рулит, но у телеграма почему-то получается нормально и без этого. Я не одобряю, но де-факто может получиться юзабельно и безопасно.


          1. JekaMas
            28.05.2019 14:02

            А может и не получиться


          1. ReklatsMasters
            28.05.2019 16:00

            На заре вк оттуда свиснули пароли всех пользователей. Мой в том числе, который я нигде не светил. И было много разговоров, что пароли там хранились в plain text. А ещё вы помните код фронта вк во времена Дуровых? Это же тихий ужас был. Так что я бы не был так уверен в команде авторов.


            1. mr_tron
              28.05.2019 16:41

              Там и сейчас код телеграма страшен как смертный грех. ЧТо не мешает ему работать лучше всего что у меня есть из прикладного софта на компе.


            1. bodqhrohro
              29.05.2019 15:08

              А более свежие прецеденты есть? За десять лет можно и обезьяну научить безопасно разрабатывать, знаете ли :)


    1. AotD
      28.05.2019 10:33

      Ребятам нужен был «высокоуровневый» язык, чуть человечнее голого ассемблера для стековой машины. Писать транслятор какого-нибудь JS в ASM виртуальной машины — нужно много времени, опыта и компромиссов (привет «undefined is not a object» или проблемы с округлением чисел когда нужно перевести 0.1 условных BTC, которые на самом деле 0.100000001490116119384765625 согласно IEEE 754)

      Forth с точки зрения реализации интерпретатора прост как палка и пишется за пару вечеров. Чтобы начать под него писать нужно знать всего 2 вещи:
      1) Можно вводить в язык новые слова
      2) Положи на стек данные и запусти слово которое их прожуёт
      Всё!
      Взяли парадигму Forth, адаптировали для блокчейна, получили Fift. Да, это похоже на ненормальное программирование, равно как и Prolog, Haskel, Erlang или любой другой язык который не такой как <язык в парадигму которого я умею>, но они выполняют свою работу лучше в той или иной области.


      1. vtools
        28.05.2019 11:35

        По поводу использования стековой машины. Кто нибудь проводил исследования насколько они быстрые или медленные?
        Расскажу о своем опыте:
        В далеком 2002-2003 годах я решил создать свой аналог популярной тогда одной бухгалтерской платформы и там был интерпретируемый язык программирования. Как потом оказалось он был стековый. Но я об этом не знал и поэтому запилил как умел — прочел книгу по основам интерпретаторов и компиляторов, сделал интерпретацию байт-кода на основе switch/case. Оказалось в 17 раз быстрее оригинала. Видимо за счет лучшей встроенной оптимизации компилятора C/C++. Но сейчас это все равно очень медленно по сравнению с JIT компиляцией.

        P.S.
        Кстати, я не нашел слово JIT в указанной выше документации TON…


      1. gatoazul
        28.05.2019 13:33

        Непонятно только, почему нельзя было обойтись обычным Фортом.


        1. AotD
          28.05.2019 14:39

          Это да, вопрос =) Но опять же диалектов Форта наберется штук 5, конкретных реализаций той же работы с плавающей точкой ещё около десятка, всё это насколько я знаю в достаточно плачевном состоянии с точки зрения актуальности. Так что скорее всего взыграло «почему бы не написать всё с нуля»? =)
          image


      1. FForth
        28.05.2019 19:59

        Внезапно и BitCoin использует Форт подобный язык программирования.

        P.S. Для примера и в гиковском проекте TTL компьютера Gigatron (без микропроцессора)
        сделан системный язык GTL с элементами Форт дизайна


  1. lostmsu
    27.05.2019 22:18
    -3

    Всегда интересно смотреть как будут стричь невежд :)


  1. ne_kotin
    27.05.2019 23:35
    +5

    Всегда удивляла потребность архитектора (-ов?) Телеграма в велосипедах. Нужен шифрованный канал! TLS? Нет, он придуман не нами, у нас будет свой MTProto, со своим языком описания типов TL (различные тьмы IDL-ов, WSDL, OpenAPI, и иже с ними, наверное тоже недостаточно идеальны).

    Ладно, много чейнов вместо одного видимо должны ускорить процессинг транзакций.
    Но ёшкин кот. Ладно вы о пользователях не думаете — у них будет мимимишный кошелечек в тележеньке. Почему о разрабах то не подумать? Сделать язык синтаксически близким к JS (как Solidity), или к C — зачем?
    АдЪ!


    1. aleks_raiden
      27.05.2019 23:48
      +2

      В защиту выступлю — то, что представлено, это не конечный язык, это некоторый промежуточный ассемблер. Вот если показать IRL, но без C#, будет то же. Это ведь утечка тестовых данных. С другой стороны, этого как бы достаточно, чтобы другие команды писали компиляторы — у них ресурсов всегда больше, чем у кор-команды


    1. gudvinr
      28.05.2019 00:24
      -2

      Вы рассуждаете крайне предвзято, при этом исходя из предположения, что использование собственных разработок в TG — это потребность и рассуждая с точки зрения того, что есть сейчас. Совсем не учитывая ни иные предпосылки, ни какие-либо рациональные предположения.


      В некоторых статьях из блога ВК на хабре авторы упоминали использование TL схемы. Следовательно, можно предположить, что сам язык был разработан ещё в эти времена. Не факт, что именно в таком виде, как используется в TG, но тем не менее.


      Даже если это не так, вполне возможно, что именно такой формат описания подходит для ИХ задач лучше, чем любой существовавший в те дни, когда разрабатывался TG (или ВК, если это верная мысль). Различные тьмы могли либо не существовать, либо не удовлетворять требованиям плотности упаковки, скорости сериализации и т.д. Тем более, что ставить OpenAPI в один ряд с TL не совсем корректно.


      Точно так же, как и TLS сравнивать с MTProto довольно глупо. TLS — это протокол для всех, который возможно использовать для многих задач, и соответственно, это привносит ему некоторые недостатки в виде оверхеда, довольно медленного обмена ключами и прочим вещам, которые могли быть критичны (TLS 1.3 был примерно нигде в то время).


      MTProto — это узкоспециализированный протокол, который разрабатывался с определенной целью, чтобы удовлетворять определенным требованиям, и альтернатив, которые бы могли полностью покрыть возможности, вполне могло не существовать.


      Отмечу специально, что я не оправдываю решения идти путём изобретения подобных вещей (но и не считаю, что это удивительно, либо неправильно). Тем не менее, это не значит, что была необходимость сделать велосипед.


      Это ничем не хуже пути, по которому пошли разработчики WhatsApp, например, перекостылив ejabberd, сделав из XMPP дикого полу-текстового полу-бинарного монстра Франкенштейна.


      1. nuclight
        28.05.2019 00:38
        +2

        Вы рассуждаете крайне предвзято, при этом исходя из предположения, что использование собственных разработок в TG — это потребность и рассуждая с точки зрения того, что есть сейчас


        С достаточной уверенностью, даже с учетом тех лет, можно утверждать, что таки да, именно потребность — но в основном психологического свойства.

        Различные тьмы могли либо не существовать, либо не удовлетворять требованиям плотности упаковки, скорости сериализации и т.д. Тем более, что ставить OpenAPI в один ряд с TL не совсем корректно.


        Уже существовал как минимум Google Protobuffers. Не то что бы он мне нравился, но даже и с плотностью упаковки у него лучше, чем у TL. А уж эти костыли с флагами… вообще, о костылях в нём можно говорить много. Наконец, вот вроде бы это была попытка сделать нечто строго типизированное с целью проверок на ошибки, с закосом под типы в функциональных языках типа того же Haskell… и что? В схеме нет возможности ни указать, скажем, допустимые границы диапазона значений для целых, ни банальный enum, ни даже Vector<> из самой системы не выводится — все открытые реализации Telegram реализуют его вручную, сбоку.

        Что уж говорить о таких приятных плюшках имеющихся других языков описаний схем, как комментарии/документация (даже в JSON-схеме это есть). Впрочем, с документацией у этой команды всегда было плохо.

        Точно так же, как и TLS сравнивать с MTProto довольно глупо. TLS — это протокол для всех, который возможно использовать для многих задач, и соответственно, это привносит ему некоторые недостатки в виде оверхеда, довольно медленного обмена ключами и прочим вещам, которые могли быть критичны (TLS 1.3 был примерно нигде в то время).


        Единственное, с чем здесь можно согласиться — только скорость обмена ключами. Но это не требовало ни самодельного IGE, ни ряда других решений, на которые плевался умеющий в криптографию товарищ, который пытался реализовать протокол с нуля. Довеском отличная характеристика способностей этих «олимпиадников» — как всего через пару лет пришлось делать MTProto 2.0, потому что ВНЕЗАПНО оказалось, что использованный SHA-1 давно протух. Но нет, заранее изучить, что умные люди придумали, ЧСВ мешало, наверное.

        Это ничем не хуже пути, по которому пошли разработчики WhatsApp, например, перекостылив ejabberd, сделав из XMPP дикого полу-текстового полу-бинарного монстра Франкенштейна.


        Да у обоих вышло отвратно. Неизбежная проблема рынка — выходишь первый в нишу, возьмут любое говно.


        1. tyderh
          28.05.2019 03:10

          С достаточной уверенностью, даже с учетом тех лет, можно утверждать, что таки да, именно потребность — но в основном психологического свойства.

          Подтверждаю. Эти товарищи даже qt не смогли заюзать без того, чтобы забандлить его и обмазать сомнительными патчами.


          1. ebt
            28.05.2019 13:51

            Простите, не напомните, где именно команда tg использовала qt?


            1. mr_tron
              28.05.2019 14:04

              Десктопный клиент построен на qt внезапно.


      1. ne_kotin
        28.05.2019 00:57
        +1

        Видите ли… Когда ты решаешь прикладную задачу — очень глупо считать себя умнее окружающих.
        Практически все, что нужно для построения мессенджера — уже придумано и реализовано. Надо только собрать в кучку. Напомню, на дворе 2011 год, когда это все начиналось.

        Транспорт — да, TLS/DTLS, не надо выдумывать велосипеды. Криптографией там занимается не один десяток человек. Но нет, костылим свое, в итоге рукалицо, когда в исходниках находят, что облачный пароль хэшируется по SHA256.

        Структура данных и контракты вызовов? Вот честно, как по мне, так сопровождение вменяемой документации (а документацию в виде TL вменяемой не назовешь) плюс байндинги на нескольких популярных языках заняло бы сильно меньше времени, чем сопровождение единого языка описания и транспайлеров в нужный синтаксис.

        Нету требований и альтернатив, чтобы при проектировании мессенджера костылить эпическую инфраструктуру. Это просто мессенджер. Система асинхронного обмена текстом и кое-какими файлами.

        И даже то, что так делает WhatsApp — не оправдание.


    1. nuclight
      28.05.2019 00:26
      +1

      Да зачем? Можно же было взять, например, lua в качестве языка контрактов.

      А их TL и MTProto — отдельная пейсня, с кучей костылей даже внутри себя.


      1. Kabdim
        28.05.2019 15:44

        А что в луа уже появилась возможность перейти на 257битные целые числа как базовый тип? Когда я смотрел всё было грустно — double и ничего кроме double.


    1. tcapb1
      28.05.2019 00:53
      +2

      Можно также вспомнить KPHP, ещё времён Вконтакта, собственную версию PHP с обрезанным ООП. На более высоком уровне к счастью всё попроще. Например, API для ботов Телеграма на удивление простой и приятный для использования.


    1. nexmean
      28.05.2019 21:55
      -1

      к JS
      или к C

      Ужас какой


  1. aleks_raiden
    28.05.2019 00:02

    Пытаюсь собрать по инструкциям, на Debian.
    Получаю:

    /root/lite-client/crypto/../validator/interfaces/validator-full-id.h:4:29: fatal error: auto/tl/ton_api.h: No such file or directory
     #include "auto/tl/ton_api.h"
                                 ^
    compilation terminated.
    crypto/CMakeFiles/ton_block.dir/build.make:134: recipe for target 'crypto/CMakeFiles/ton_block.dir/block/mc-config.cpp.o' failed
    make[3]: *** [crypto/CMakeFiles/ton_block.dir/block/mc-config.cpp.o] Error 1
    CMakeFiles/Makefile2:3302: recipe for target 'crypto/CMakeFiles/ton_block.dir/all' failed
    make[2]: *** [crypto/CMakeFiles/ton_block.dir/all] Error 2
    CMakeFiles/Makefile2:101: recipe for target 'CMakeFiles/test-lite-client.dir/rule' failed
    make[1]: *** [CMakeFiles/test-lite-client.dir/rule] Error 2
    Makefile:162: recipe for target 'test-lite-client' failed
    make: *** [test-lite-client] Error 2
    


    1. ebt
      28.05.2019 02:58

      Компилятор не видит заголовочного файла ton_api.h, наверное, надо ему подсказать.


    1. deNULL Автор
      28.05.2019 03:13

      У меня файл "auto/tl/ton_api.h" сгенерировался на одном из предыдущих этапов сборки, вот этот кусок лога:


      Видимо, у вас на этапе tl_generate_common что-то пошло не так.


  1. JekaMas
    28.05.2019 00:06
    +3

    После solidity, wasm, vyper — этот вариант с Fifth… Даже не знаю, как выразить эмоции. Жуткий что ли.


    1. aleks_raiden
      28.05.2019 00:09

      Погодите, вы смешали все в кучу.
      — Солидити — да, скриптовый, компилируеться в регистровую VM
      — VASM — промежуточный абстрактный язык, в которой компилируеться все, дальше просто бекенд для llvm, минимум одна команда уже делает это.
      — Vyper — интересно, но пока на этапе концепции


      1. JekaMas
        28.05.2019 00:23

        Все три инструмента решают задачу написания смарт контрактов. Все три работают.


    1. Begetan
      28.05.2019 12:51
      +2

      Языки для написанаия смартконтрактов решают двк принципиально важные задачи.

      1. Хранение данных в блокчейне стоит дорого, невероятно дорого! Каждый байт комманд и данных кем то оплачивается.

      2. Виртуальные машины блокчейнов запускаются на тысячах нод в сети. Каждая из них выполняет код всех контрактов, для того что бы обеспечить независимую валидацию всей цепочки. Выполнение даже простейшего кода требует расхода огромного количество вычислительных ресурсов.

      Использование более эффективных языков одновременно снижает стоимость использования смарт-контрактов для коннечных пользователей и увеличивает производительность сети.

      Очень многие критикую блокчейн технологию имеено за высокую стоимость и низкую производительность, поэтому очередная попытка написать еще одну лучшую систему имеет хорошие шансы на успех.


      1. JekaMas
        28.05.2019 13:24

        От вида консенсуса и типов клиентов зависит. Может и на части нод исполняться. И да, невероятно дорого — вы уверены? 1k обойдется в 640k газа или 1.7 usd. Контракт живет долго, деплоить его каждый лень не надо.


        1. alan008
          28.05.2019 16:43

          Невероятно дорого с точки зрения задействованных ресурсов (вычислительного времени, электричества и т.п.), а не денег.


          1. JekaMas
            28.05.2019 17:09

            И что там невероятно дорогого? Мы ведь про хранение контрактов говорим.


            1. alan008
              28.05.2019 17:28

              То, что весь блокчейн хранится на каждом узле сети (при отсутствии шардинга).


              1. JekaMas
                28.05.2019 18:39

                Так. Ну хранится на каждой ноде с полным стейтом. Как из этого следует "невероятно дорого"?


              1. Homakov
                28.05.2019 22:27

                Блокчейн как цепочка блоков никем не должен храниться. Хранится стейт, который при правильных комиссиях маленький, в бтс это 3гб. То что «блокчейн должен всеми храниться» не более чем байка.


      1. Homakov
        28.05.2019 22:26

        Смарт апдейты решают проблему новой функциональности эффективнее — habr.com/ru/post/430734


  1. Homakov
    28.05.2019 01:52
    +2

    А в чем инновация если конкретно? Как воркчейны решают проблему масштабирования?


    1. deNULL Автор
      28.05.2019 01:56

      Воркчейны решают другую задачу: возможность иметь несколько независимых блокчейнов с разными конфигурациями.

      Проблема масштабирования решается следующим уровнем: дроблением воркчейнов на шардчейны. Каждый шардчейн ответственнен за хранения состояния своего диапазона аккаунтов (подобно шардированию в обычных БД).


      1. Homakov
        28.05.2019 10:02

        Ладно, и как они решают проблему компрометации одного шарда? Шард взломан и доставляет неверную информацию наверх и другим. Как правило все лайт клиенты полагаются на merkle пруфы, а шарды это те же лайт клиенты.


        1. dadon
          28.05.2019 13:52

          А что значит шард «взломан»? Ваш аккаунт находится в определенном шарде, транзакцию которую вы отправили проверит группа валидаторов, которая отвечает за ваш шард. Если транзакция не валидная, то валидаторы ее не включат в следующий блок. То что валидаторы могут быть malicious решается тем, что они потеряют свой stake если пропустят не валидную транзакцию


          1. Homakov
            28.05.2019 15:00

            Допустим шардом заведуют 4 валидатора из общих 100. Если из этих 4 трое взломаны, то они могут включить любую транзакцию и создать любого рода merkle proof. Тем самым привести к атаке на миллионы долларов. В то время как их стейк будет в 100 раз меньше, например.

            В этом концептуальная проблема защиты с помощью депозита — почти любую атаку можно сделать дороже чем депозит который сгорит.


            1. dadon
              28.05.2019 15:39

              Да со взломанными валидаторами это отдельная тема. Как минимум, как указали ниже — есть механизм отката постфактум. Допустим есть плохие валидаторы, если у другого участника сети есть доказательство, что подписали неверные транзакции, то плохие валидаторы теряют стейк, остальные валидаторы вносят правку — откатывают невалидные транзакции и те которые зависят от них, а тот кто указал на зловредных валидотров получает приз, часть от потерянного стейка


              1. Homakov
                28.05.2019 22:29

                Ну а атака то привела к 100 раз большему ущербу чем размер стейка. Задепозитили на 100 разных бирж по 100 тыщ долларов и слили через другие системы. Если финальность шарда нарушена, финальность всей системы нарушена так же. Либо создать аналог кредит лимитов и не доверять некому шарду на более чем какой то volume, но тогда система становится неюзабельной и медленной.


          1. genamodif
            28.05.2019 17:13

            А кто будет валидировать, что валидаторы пропускают не валидные транзакции?


            1. dadon
              28.05.2019 17:16

              В документации описана отдельная роль для этого — fisherman. По идее любой участник сети может этим заниматься


              1. Homakov
                28.05.2019 22:31

                Если А) с ним будут делиться блоками Б) у него есть достаточно инсентива чтобы годами пропускать через себя 1000 тпс в надежде на стейк. Очень сомнительная бизнес модель.


                1. lohmatij
                  28.05.2019 22:51

                  А человек которого «взломали» разве не заинтересован найти виновного как можно быстрее? Ему то видно как из кошелька деньги пропадут.


                  1. Homakov
                    28.05.2019 23:22

                    Не пропадут, там такой функции нет. Люди в такой раздутой системе поголовно лайт клиенты и ничего не верифицируют.


                    1. lohmatij
                      29.05.2019 02:03

                      Тогда в какой момент ты поймешь что деньги у тебя ушли? (Ну или не пришли, то бишь «ушли назад»)? Вот в тот момент ты начинаешь верификацию (которая может и в качестве сервиса предоставляться сторонними рыбаками).


      1. JekaMas
        28.05.2019 11:04

        А как происходит шардирование? Если в один шард попадет много malicious пользователей — это не скажется на чейне?


        1. WarFollowsMe
          28.05.2019 14:24

          Есть общая группа валидаторов, которые занимаются подтверждением блоков в мастерчейне. Для шардов раз в определенный промежуток времени псевдорендомно выбираются подгруппы из этой общей группы. Валидаторы из подгрупп выполняют две работы, валидация блоков в шарде и валидация блоков в мастерчейне. Блоки генерируются раз в 5 секунд (это ожидаемое время разработчиков), но при этом между блоками шардов и мастерчейна есть свдиг в одну секунду. В блок мастерчейна записываются хеши последних блоков всех шардчейнов. Примерно так описывается процесс в документации.

          Меня смущает другой момент. В этой системе встроен инструмент отката данных в блоках. Каждый блок на самом деле не блок, а как его называют в документации, «вертикальный блокчейн», который содержит разные вариации этого блока, и если блок окажется вдруг «плохим», то его помечают флагом, а потом выбирают другой вариант из предложенных в этом «вертикальном блокчейне». И вот это все как-то не особо применимо к определению «блокчейн». Что в целом авторы проекта в документации и указывают.


          1. Homakov
            28.05.2019 15:03

            Еще большой вопрос а как кто либо узнает что блок стал плохим. При высоком tps, ни у кого нет мотивации быть фул нодой некого шарда. И допустим если 4 валидатора этого шарда стали плохими то вообще никто помочь не может, и они начинают создавать ассеты из воздуха.


            1. WarFollowsMe
              28.05.2019 16:46

              Тут не идет речь о реалтайм детектрировании. Это интрумент — альтернатива rolling back в существующих системах, когда в случае серьезного факапа приходится откатывать всю сеть, удалив неугодные блоки, как было с эфиром при TheDAO. Поэтому понять, что что-то пошло не так, может пострадавшая сторона например.

              По поводу желание быть нодой шарда. У валидатора нет выбора быть ему валидатором шарда или не быть. Есть раунды когда определяются роли, и если ты попал в список подгруппы, то либо валидируешь и мастерчен и шард и получаешь за это награду, либо нет. К тому же, тут алгоритм консенсуса это обычный PoS, чтобы стать валидатором нужно стекнуть какую-то часть средств, и в случае «плохого» поведения эту часть у валидатора забирают.


              1. Homakov
                28.05.2019 22:34

                >У валидатора нет выбора быть ему валидатором шарда или не быть

                В предложении «ни у кого нет мотивации быть фул нодой некого шарда» я не говорил про валидаторов, я говорил про кого угодно. Те же фишермены или просто big economic nodes. Валидаторов выбирает алгоритм, это нам известно.

                >и в случае «плохого» поведения эту часть у валидатора забирают.
                Заберут копейки а атака обошлась людям/биржам/продавцам недвижимости в 100 раз дороже. Нарушение финальности в любой подсистеме шардинга = невозвратный факап уровня даблспента в главной сети. Либо нужно ставить требование финальности для шарда в 2 дня например (убедиться что всех все устроило), но тогда ктож этим будет пользоваться.


                1. ArthurOstapenko
                  29.05.2019 18:47

                  А почему заберут копейку а забенефитят миллиард? С чего вы это взяли?

                  Валидаторов в пике будет всего 1000, больше не позволит текущий консенсус, без значительного снижения производительности сети.
                  Капитализация сети в которой наконец-то можно будет реальные приложения и fog сервисы, и которая имеет массадопшен со старта благодаря готовой аудитории первого приложения — Телеграма в 200M+, будет очень скоро измеряться сотнями миллиардов. Соответственно конкуренция за роль валидатора будет очень жесткой.
                  Все кандидаты в валидаторы что пролетели на выборах на следующий месяц могут чтобы не простаивало железо рыбачить, не только чтобы заработать на штрафах, но чтобы поскорее выбить существующих валидаторов у которых оказалась недостаточно хорошая защита.
                  Помимо этого можно легко заложить в протокол «подкормку» рыбаков, подкидывая время от времени фейковый штраф который берется просто из эмиссии и никого реально не штрафует, тогда еще и коллаторам будет иметь смысл перепроверять блоки помимо простого хранения и подготовки кандидатов. (я не знаю заложат ли разрабочики TON его или нет, но в принципе ничего не мешает)

                  Если будет застейкано в среднем 60% всего капитала сети, разделенного на 1000 валидаторов плюс-минум равномерно (там будет ограничение на разницу в обьеме стейка между первым и последним валидатором чтобы избежать централизации), капитализация будет предположим $200B, то получается в среднем на одного валидатора придется 200B * 60% / 1000 = $120M стейка.
                  Предположим в рабочей группе валидаторов из 20 нод оказалось 14 malicious которые получили больше 2/3 силы и задаблспендили какую-нибудь крупную транзакцию себе на счет. Получается они потеряли ~$1.6B стейка (ну или часть от него) и репутацию, то есть сразу вылетели из бизнеса, что будет стоить тоже очень недешево. И теперь вопрос — какой экономический смысл быть malicious?
                  Тем более что через несколько секунд рыбаки/коллаторы нажалуются, общий пул всех валидаторов перепроверит и откатит эти 1-2 транзакции что успели сгенерится. За это время даже через атомик свопы в биткоин не успеют вывести украденные средства, не говоря уже про биржи.


          1. JekaMas
            28.05.2019 15:10

            «псевдорендомно выбираются подгруппы» — вот тут важно. что за псевдорандом и как мы ему доверяем?
            Мы ведь должны иметь ни много, ни мало, а verifiable distributed source of randomness.


            1. WarFollowsMe
              28.05.2019 16:32

              цитата из документации

              The algorithm uses pseudorandom numbers embedded by validators into each masterchain block (generated by a consensus using threshold signatures) to create a random seed, and then computes for example Hash(CODE(w).CODE(s).validator_id.rand_seed) for each validator. Then validators are sorted by the value of this hash, and the first several are selected, so as to have at least 20/T of the total validator stakes and consist of at least 5 validators.



              1. JekaMas
                28.05.2019 18:41

                VRF, теперь понятно


      1. Finderom
        28.05.2019 17:51

        Каждый шардчейн включает в себя блоки в которые входят транзакции на адреса этого шардчейна (адреса начинающиеся с определенного префикса). Но валидатор этого шардчейна должен как то проверить источник приходящих средств, а источник средств это другой адрес и его обслуживает другой шардчейн. Получается что валидатор должен сделать сетевой запрос в другой шардчейн о наличие средств на адресе-источнике и отсутствии двойной траты и поверить этому ответу на слово, так как не имеет собственной доказательной базы. Как это работает?


        1. Homakov
          28.05.2019 22:37

          Смею предположить — как у и любого другого inter blockchain communication, например cosmos. cosmos.network Две системы знают наборы валидаторов друг друга и обмениваются merkle пруфами.


          1. Finderom
            28.05.2019 23:14
            +1

            Валидатор соседнего шардчейна может вернуть правильный merkle_root но при этом неверный остаток средств адреса отправителя, и чтобы его поймать за руку нужно будет запросить у него весь блок и сделать так для каждой транзакции в новом блоке.


            1. Homakov
              28.05.2019 23:22

              Про это и говорю выше


  1. SerJook
    28.05.2019 11:09
    +1

    image


  1. dMac
    28.05.2019 13:48

    Господа программисты, Форт и фортоподобные языки на порядки превосходят по быстродействию и компактности всякие джаваскрипты и прочее — спросите у тех, кто программировал глубоководные контроллеры в 80x, где и памяти и быстродействия — кот наплакал.

    Как выше уже заметили — на блокчейне хранение данных стоит ОЧЕНЬ дорого и вычисления тоже стоят ОЧЕНЬ дорого.

    Так что применение на блокчейне чего-то подобного Форту — не прихоть левой пятки, а вполне себе обоснованное дизайн-решение, ИМХО. Другое дело, что в 21 веке мы, наверное, стали слишком ленивы для Форта, т.к. надо перестраивать образ мышления.

    И да, перелогиниваться не советуйте — я не Николай Дуров :)


    1. rogoz
      28.05.2019 14:58

      Кстати, числа тут — внезапно — 257-битные целые
      Ну, я уже чувствую быстродействие.


    1. Tagire
      28.05.2019 17:38
      +1

      >на порядки превосходят по быстродействию и компактности всякие джаваскрипты и прочее — спросите у тех, кто программировал глубоководные контроллеры в 80х

      Сейчас я протестирую это утверждение используя какую нибудь прикладную программу на Форте с нормальной современной функциональностью. Хм, а их нет. Нет смысла сравнивать воображаемую программу с настоящей.


      1. assembled
        28.05.2019 23:48

        Форт в основном в контроллерах живёт, для ПК, не считая самих форт-систем, я так сходу могу вспомнить только: Eserv, nnCron, ещё форт был в загрузчике FreeBSD, и использовался в Open Firmware.



  1. AlexPupyshev
    28.05.2019 15:48

    1. deNULL Автор
      28.05.2019 17:15
      +1

      ."Hello world"

      Согласен, Fift может быть довольно нечитабельным, но вот с лаконичностью у него вроде проблем нет :)


      1. FTOH
        28.05.2019 18:40

        Разве не


        "Hello world" .

        ?


        1. deNULL Автор
          28.05.2019 18:44

          Тоже допустимый вариант, но на один символ длиннее :)


          Слово ." берёт последующую за ним строку (до закрывающей кавычки) и сразу же выводит его в стандартный вывод. Посмотрите в примере кода (в статье) — там есть использования этой конструкции.


          1. FTOH
            28.05.2019 18:50

            Спасибо, увидел.


          1. assembled
            28.05.2019 21:17

            Раз ." это слово, а не специальный синтаксис, то не должно ли оно отделятся пробелом, как в форте?
            ." Hello, world!"


            1. deNULL Автор
              28.05.2019 21:29

              Это т.н. префиксное слово (которое обращается к последующему за ним тексту); для таких слов — нет, пробельный символ не нужен.


              1. assembled
                28.05.2019 21:36

                Но тогда как понять, что является словом, ." или ."Hello? В форте слово — последовательность любых непробельных символов, и слова всегда отделяются пробелами.


                1. deNULL Автор
                  28.05.2019 21:56

                  Вот как это описывает документация:


                  То есть с начала текущей строки откусывается максимальный префикс, который был до этого определён как слово (и далее это слово выполняется). Если бы мы определили ."Hello как слово — да, оно бы выполнилось вместо ."


  1. Vilgelm
    28.05.2019 17:04

    Это тестовый блокчейн или уже основной?


    1. deNULL Автор
      28.05.2019 17:11
      +1

      Тестовый. Не думаю, что в основном будут смарт-контракты для раздачи грамов за просто так :)


  1. humbug
    29.05.2019 01:08

    adnl/adnl-ext-connection.cpp:


    auto data_size = td::narrow_cast<td::uint32>(data.size()) + 32 + 32;
    S.copy_from(td::Slice(reinterpret_cast<const td::uint8 *>(&data_size), 4));

    Когда забыл про эндианесс))


  1. DirectX
    29.05.2019 08:43

    Пока не нашёл ответа на вопрос, в чём прикол использования int257? Подозреваю, что с архитектурной точки зрения это вроде как знаковое int256, но как это вообще сочетается с хранением? Понятно, что виртуальная машина своя и там можно хоть тернарную арифметику использовать, но реально ведь код будет исполняться на обычных и разные там SIMD-инструкции уже не так полетят.


  1. OZR
    30.05.2019 14:22

    Скомпилировалось. Запускается. Connection refused…


    1. deNULL Автор
      30.05.2019 23:19

      Видимо, тестовую ноду выключили


  1. vadiminshakov
    30.05.2019 23:19

    На убунте кто-нибудь сталкивался с таким?

    image