@mnill
Ну любые вызовы между смарт контрактами это сообщения. Есть два типо сообщений, internal и external.
Internal - созданное другим смарт контрактом, и которое через hypercube routing(хз работает ли он сейчас) приехал в нужный шардчейн и вызвал ваш контракт.
External - сообщение из ниоткуда, типо вот через кошелек или tonos-cli можно его послать. Просто любое сообщение из внешнего мира.
Вот, у internal сообщений есть Logical time, это посути просто номер транзакции созданной этим контрактом ( всегда возрастает ). И гарантируется что одно сообщение с этим Logical time придет в ваш контракт один раз.
А у External message по умолчанию нет никакой защиты от replay аттак. То есть если ваш смарт контракт специально не проверяет дубликаты, то валидатор вашу транзакцию может исполнить сколько угодно раз
То есть создатель смарт контракта, к которому юзер может обращатся на прямую должен реализовать какую то защиту от повторных вызовов сам. Есть в тон солидити pragma time; как мне сказали, которая это делает, но на нее видимо нет публичной документации.
Например у вас есть смарт контракт Zombie где есть вызов “Подратся с другим зомби”. И этот вызов посылается через crystal wallet например пользователем как External message.
.....
Вообщем по идее надо добавить pragma AbiHeader time; в контракт, это заставит вызывающего добавить к сообщению время вызова и создатель контракта должен проверить, что это время вызова больше чем время предыдущего вызова, чтобы не дать валидаторам или злоумышленникам два раза заставить ваш контракт что то сделать, когда вы хотели один раз (например заставить вашего зомби подратся)
но что контректо делает pragma AbiHeader time и пример этой проверки я пока только изучаю. Вот например в эфире, нет сообщений ниодкуда, там сообщения всегда начинаются с адреса кошелька который их отправляет по сути. И когда создается сообщение там уже есть Nonce, и два сообщения с одинаковым Nonce быть не может, это уже решено на уровне протокола. А тут нет.
@defenseoftheblockchain
Потому что там разделено все между собой итак
@mnill
блин я вот все изучил, а в итоге сказали что pragma time; “Походу добавляется сама и проверять ничего не надо”, ну все равно полезно знать, что они встроили в солидити проверку на дубликаты такую с ms.
к каждому сообщению добавляется ms, и если ты оправляешь два одновременно или близко к тому, есть шанс что одно зафейлится можно реализовать свою проверку и отказатся от стандартной если у тебя хайлоад контракт. В гивере так сделано, своя проверка на дубликаты:
@ilyarsoftware
На эту тему у меня в планах руками проверить это:
https://github.com/tonlabs/TON-Solidity-Compiler/blob/master/API.md#pragma-abiheader https://docs.ton.dev/86757ecb2/p/88321a-message-expiration
@renatSK
Есть всякие highload контракты которые записывают запросы в свой сторедж и отсекают дубликаты, они понятно более дорогие по газу, но позволяют работать со смартконтрактом в паралель.
https://docs.ton.dev/86757ecb2/p/55f73e-security
https://nodeschool.io/#workshopper-list или этого https://www.youtube.com/watch?v=XzLuMtDelGk
описания флагов есть тут https://github.com/tonlabs/TON-Solidity-Compiler/blob/master/API.md#addresstransfer
Создание и деплой контракта ZombieFactory.sol чтобы применить на практике урок https://cryptozombies.io/ru/lesson/1
npm install -g tondev
tondev sol update
tondev sol version
tondev sol set --compiler 0.50.0 --linker 0.13.66 --stdlib 0.50.0
tondev network default se
tondev signer add giver_keys 172af540e43a524763dd53b26a066d472a97c4de37d5498170564510608250c3
tondev network giver se 0:b5e9240fc2d2f1ff8cbb1d1dee7fb7cae155e5f6320e585fcc685698994a19a5 --signer giver_keys
tondev signer generate owner_keys
tondev signer default owner_keys
tondev sol compile ZombieFactory.sol
tondev se start
tondev contract deploy ZombieFactory --value 1000000000
tondev contract run ZombieFactory
— имеет смыл только createZombie
чтение контракта:
tondev contract run-local ZombieFactory zombieCount
tondev contract run-local ZombieFactory getZombieDna
tondev contract run-local ZombieFactory getZombieName
https://hackmd.io/LLwxyC0rRYOJ9ZXptAzKxA?view
https://www.youtube.com/watch?v=ngD88UraMmU&list=PLPj4C8ti8UaSPAP6afsy0wQ53lihBT5l1
Вопросы и ответы:
Есть ли различие в ТОНе между storage / memory? - во фритон нет memory, всё storage
Обязателен ли tvm.accept() при вызове callback? - tvm.accept обязателен для внешних сообщений но не обязателен для внутренних, к которым прикладывается value. в ссылке выше есть описание этой функции.
Создать в github репозитории файл readme.md в этот файл, используя markdown выпишите свои выводы и структуру, которую вы поняли и сами для себя сформировали.
КриптоЗомби - интерактивная школа программирования. Это игра больше к эфиру, но там семантика схожа с той что у нас на фритон в компиляторе..
https://telegra.ph/Links-08-28-58
https://github.com/tonlabs/TON-Solidity-Compiler/tree/master/compiler/docs
https://github.com/tonlabs/TON-Solidity-Compiler/blob/master/compiler/docs/style-guide.rst
скомпилировать этот контракт: https://github.com/broxus/ton-contracts/blob/master/contracts/wallets/Account.sol и изучить его
https://docs.ton.dev/86757ecb2/p/950f8a-write-smart-contract-in-solidity
https://docs.soliditylang.org/en/latest/cheatsheet.html
https://docs.soliditylang.org/en/latest/style-guide.html
https://docs.soliditylang.org/en/latest/structure-of-a-contract.html
На основе массива создаётся структура данных - стек или полное двоичное дерево. На основе полного двоичного дерева создаются двоичная куча. Назначение - распараллеливане данных.
На основе связанного списка создаётся очередь или двоичное дерево поиска. (AWL-, красное- и чёрное- дерево). Назначение - упорядовочиние данных.
позволяют создать префиксное дерево способое компактно хранить в памяти обьекты - например строки. Строки хранятся в массиве.
Работа с массивами строк, храняшимися в опеределюнной кодировке (big & little endian) в бинарном виде, в массивах, через адресацию памяти и битовые манипуляции создаёт битовый вектор.
Обьеденив битовый вектор, массив и связанный список через хэш таблицу получим граф - основу для любого серьёзного программирования.
Оценка сложности - требует знаний о функциях, логоритмах, математической индукции, арифмитической и геометрической прогрессии, BigO и теории вероятности (комбинаторики).
Почему и когда память работает как стек или куча
Почему работает математическая индукция
Навыки комбинаторики
Рекурсия
Динамическое программирование
Алгоритмы (Сортировка и двоичный поиск)
https://docs.soliditylang.org/en/latest/grammar.html
Синтактический анализ
Парсинг
Семантический анализ
Оптимизация
Генерация кода
https://docs.soliditylang.org/en/latest/types.html#value-types
Список типов значений поддерживаемых TVM:
Integer - 257-битные целые числа со знаком, представляющие целые числа в диапазон
Cell - Ячейка TVM состоит не более чем из 1023 бит данных и не более максимум четыре ссылки на другие ячейки. Все постоянные данные (включая TVM code) в блокчейне TON представлен в виде набора TVM клетки
Tuple - упорядоченный набор до 255 компонентов, имеющих произвольные типы значений, возможно, разные. Может использоваться для представления непостоянных значений произвольных алгебраических типов данных.
Null - Тип с ровно одним значением ⊥, используемый для представления пустого списки, пустые ветви бинарных деревьев, отсутствие возвращаемого значения в некоторых ситуации и так далее.
Slice - Срез ячейки TVM, или для краткости, представляет собой непрерывную «субячейку». существующей ячейки, содержащей некоторые ее биты данных и некоторые из ее использованная литература. По сути, срез это доступное только для чтения представление для подъячейки ячейки. Срезы используются для распаковки данных, ранее сохраненных (или сериализованных) в ячейка или дерево ячеек.
Builder - Строитель ячеек TVM, или, для краткости, строитель, является «неполным» ячейка, которая поддерживает быстрые операции добавления битовых строк и ссылок на ячейки в ее конце. Строители используются для упаковки (или сериализации) данных. из вершины стека в новые ячейки (например, перед их переносом в постоянное хранилище).
Continuation - представляет собой «токен выполнения» для TVM, который может быть вызванным (выполненным) позже. Таким образом, он обобщает адреса функций. (т.е. указатели на функции и ссылки), адреса возврата подпрограмм, адреса указателей инструкций, адреса обработчиков исключений, замыкания, частичные приложения, анонимные функции и т. д.
! (logical negation)
&& (logical conjunction, “and”)
|| (logical disjunction, “or”)
== (equality)
!= (inequality)
intN, uintN - N разрядность 8,16,32...256
fixedMxN, ufixedMxN - М количество битов, N количество десятичных
address: Содержит 20-байтовое значение (размер адреса Ethereum). address payable: То же, что и address, но с дополнительными элементами transferи send.
.balance( uint256)баланс адреса
.code( )bytes memoryкод по адресу (может быть пустым)
.codehash( bytes32)хеш-код адреса
.transfer(uint256 amount)отправить заданное количество Wei на адрес , возвращается в случае неудачи, пересылает стипендию на газ в размере 2300, не регулируется
.send(uint256 amount) returns (bool)отправить указанное количество Wei на адрес , возврат falseв случае неудачи, пересылка 2300 стипендий на бензин, не регулируется
.call(bytes memory) returns (bool, bytes memory)выдает низкоуровневую информацию CALLс заданной полезной нагрузкой, возвращает условие успеха и данные, пересылает весь доступный газ, настраивается
.delegatecall(bytes memory) returns (bool, bytes memory)выдает низкоуровневую информацию DELEGATECALLс заданной полезной нагрузкой, возвращает условие успеха и данные, пересылает весь доступный газ, настраивается
.staticcall(bytes memory) returns (bool, bytes memory)выдает низкоуровневую информацию STATICCALLс заданной полезной нагрузкой, возвращает условие успеха и данные, пересылает весь доступный газ, настраивается
bytesI - I размер 1..32
.length дает фиксированную длину массива байтов (только для чтения).
bytes, string
Шестнадцатеричные литералы, которые проходят проверку контрольной суммы адреса
Перечисления
Типы функций
Сравнения: <=, <, ==, !=, >=, >(вычисляться bool)
Арифметические операторы: +, -, Унарный -, *, /, %(по модулю)
Битовые операторы: &, |, ^(побитовое исключающее или), ~(побитовое отрицание)
Операторы сдвига: <<(сдвиг влево), >>(сдвиг вправо)
Доступ к индексу: если x имеет тип bytesI, то x[k]for возвращает -й байт (только для чтения).0 <= k < Ik