• 0 Голоса
    2 Сообщения
    16 Просмотры

    В среде testnet есть код операции GASCONSUMED, выполняющий именно это. Обновление еще не отправлено в основную сеть.

  • Как "объединить" два числа в функции?

    TON Overflow на русском
    0 Голоса
    2 Сообщения
    18 Просмотры
    int concat(int x, int y, int y_len) { return (x << y_len) ^ y; }
  • Есть ли "перерыв" в функции?

    TON Overflow на русском
    0 Голоса
    1 Сообщения
    8 Просмотры

    Когда вы реализуете управление потоком в своей программе и у вас есть цикл, иногда вам нужно выпустить путь выполнения из этого цикла, пока его состояние еще не завершено. Во многих языках программирования для этого есть функция break. Есть ли что-то подобное в FunC?

    Этот вопрос был импортирован из чата Telegram: <***Скрыто***

    click to show

    Оригинал вопроса

  • 0 Голоса
    2 Сообщения
    8 Просмотры

    Да, это поддерживается, и ваш код действителен. - достаточно?будет целым числом со значением-1`.

  • 0 Голоса
    2 Сообщения
    9 Просмотры

    Для чтения фрагмента вы можете использовать load_uint(8) в функции.

    Более подробную информацию можно проверить на примере, подобном здесь: https://docs.ton.org/develop/smart-contracts/guidelines/tips#spend-less-gas-по-крупным-смарт-контрактам

    () recv_external(slice in_msg) impure { var signature = in_msg~load_bits(512); var cs = in_msg; var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32)); throw_if(36, valid_until <= now()); var ds = get_data().begin_parse(); var (stored_seqno, stored_subwallet, public_key, plugins) = (ds~load_uint(32), ds~load_uint(32), ds~load_uint(256), ds~load_dict()); ds.end_parse(); throw_unless(33, msg_seqno == stored_seqno); throw_unless(34, subwallet_id == stored_subwallet); throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key)); accept_message(); set_data(begin_cell() .store_uint(stored_seqno + 1, 32) .store_uint(stored_subwallet, 32) .store_uint(public_key, 256) .store_dict(plugins) .end_cell()); commit(); cs~touch(); int op = cs~load_uint(8);
  • 0 Голоса
    1 Сообщения
    8 Просмотры

    В разработке программного обеспечения TON все является ячейкой. Каждая ячейка может ссылаться до 4 других ячеек, создавая родительско-дочерние отношения. Что, если у меня есть конкретная ячейка, которая ссылается на некоторые другие ячейки, и мне нужно получить все ее "дочерние ячейки"?

    Этот вопрос был импортирован из чата Telegram: <***Скрыто***

    click to show

    Оригинал вопроса

  • Какие числа означают "истина" и "ложь" в FunC?

    TON Overflow на русском
    0 Голоса
    2 Сообщения
    8 Просмотры

    ложь равна нулю. истина - это "-1`. Все остальные ненулевые целые числа также подобны логическому значению "true".

  • Как измерить длину списка в стиле Lisp?

    TON Overflow на русском
    0 Голоса
    2 Сообщения
    21 Просмотры

    Определение длины списка в стиле lisp - это ручной процесс. Вы должны просмотреть весь список. Таким образом, это, скорее всего, не имеет смысла в контексте смарт-контракта, поэтому лучше сохранить отдельную переменную счетчика всякий раз, когда вам понадобится использовать length.

  • 0 Голоса
    2 Сообщения
    22 Просмотры

    Решено

    Вы можете подписать ячейку с помощью ton-crypto или ton-core, а позже проверить ее с помощью check_signature или check_data_signature из stdlib.fc в FunC.

    Вот приблизительный фрагмент кода, который вам следует просмотреть:

    sign(yourCell.hash(), keypair.secretKey); ## And in the FunC contract, check like this: check_signature(cell_hash(your_cell), signature, public_key)

    Для получения более подробной информации вы можете обратиться к документации TON по проверке подписей.

    С другой стороны, на языке такта, у нас также есть такая же функция на стороне смарт-контракта, как эта:

    external(msg: ExtMessage) { let hash: Int = beginCell().storeUint(msg.seqno, 32).storeUint(msg.valid_until, 32).storeRef(msg.message_parameters.toCell()).endCell().hash(); require(checkSignature(hash, msg.signature, self.publicKey), "Invalid Signature"); // 😃😃😃 We checek the hash here require(msg.seqno == self.seqno, "Invalid Seqno"); require(now() <= msg.valid_until, "Invalid Time"); acceptMessage(); self.seqno = self.seqno + 1; send(msg.message_parameters); } https://docs.tact-lang.org/language/ref/math#checksignature
  • Расширить регистр фаз `commit()`?

    TON Overflow на русском
    0 Голоса
    1 Сообщения
    6 Просмотры

    Согласно документации, мы находим функциональный код commit(), описанный следующим образом:

    Commits the current state of registers c4 (“persistent data”) and c5 (“actions”) so that the current execution is considered “successful” with the saved values, even if an exception is thrown later.

    https://docs.ton.org/develop/func/stdlib#commit

    Описание может сбить с толку. Вот несколько вопросов, которые необходимо прояснить:

    Что мы получим в виде исключения или ошибки, если мы уже зафиксировали код в смарт-контракте? * Почему нам нужно фиксировать данные или статус в коде смарт-контракта, даже если в конечном итоге это приведет к ошибке? * Каковы будут последствия, если смарт-контракт получит "статус неизвестной ошибки"?

    Оригинал вопроса

  • 0 Голоса
    1 Сообщения
    0 Просмотры

    вот мой функциональный код:

    forall X -> int is_null (X x) asm "ISNULL"; forall X -> (tuple, ()) push_back (tuple tail, X head) asm "CONS"; forall X -> (tuple, (X)) pop_back (tuple t) asm "UNCONS"; forall X -> X car(tuple list) asm "CAR"; () recv_internal() { ;;;;;;; } (tuple) write_bit(tuple lisp, int bit) { if (lisp.is_null()) | (lisp.car().builder_bits() == 1023) { lisp~push_back(begin_cell()); } builder b = lisp~pop_back(); b~store_int(bit, 1); lisp~push_back(b); return lisp; } ;; testable (cell) find_and_replace(int flag, int value, cell linked_list) method_id { tuple lisp = null(); int i = 0; ;; while i < 5 { ;; lisp = write_bit(lisp, 1); ;; ;; i += 1; ;; } lisp = write_bit(lisp, 1); lisp = write_bit(lisp, 1); lisp = write_bit(lisp, 1); lisp = write_bit(lisp, 1); lisp = write_bit(lisp, 1); return begin_cell().end_cell(); }

    Хотелось бы знать, почему я получил код ошибки здесь: "Ошибка: не удается выполнить метод get. Получил код выхода: 7"

    Но если я прокомментирую этот цикл и выполню итерацию вручную L147-151 - ошибок не будет

    lisp = write_bit(lisp, 1); lisp = write_bit(lisp, 1); lisp = write_bit(lisp, 1); lisp = write_bit(lisp, 1); lisp = write_bit(lisp, 1);

    Этот вопрос был импортирован из чата Telegram: > <***Скрыто***

    click to show

    Оригинал вопроса

  • 0 Голоса
    2 Сообщения
    6 Просмотры

    Решено

    К сожалению, ответ отрицательный.

    Потому что ячейки неизменяемы, и частично потому, что вы можете дешево вычислить хэш ячейки.

  • 0 Голоса
    2 Сообщения
    8 Просмотры

    Решено

    Вообще говоря, функциональный код op::increase = "op::increase"c сначала преобразует это в uint (целое число без знака), поскольку в TVM (виртуальной машине Тьюринга) обмен данными осуществляется только в целых числах без знака, чтобы различать "неограниченные" функции, которые вы создаете.

    С другой стороны, "uint" может быть преобразован в "шестнадцатеричный" код, чтобы сэкономить место при его хранении в смарт-контракте.

    **Вот пример в TypeScript для завершения преобразования операционного кода в uint и шестнадцатеричные данные. Он использует метод CRC32 для распаковки этой информации операционного кода. **

    Код:

    const POLYNOMIAL = -306674912; let crc32_table: Int32Array | undefined = undefined; export function crc32(str: string, crc = 0xFFFFFFFF) { let bytes = Buffer.from(str); if (crc32_table === undefined) { calcTable(); } for (let i = 0; i < bytes.length; ++i) crc = crc32_table![(crc ^ bytes[i]) & 0xff] ^ (crc >>> 8); return (crc ^ -1) >>> 0; } function calcTable() { crc32_table = new Int32Array(256); for (let i = 0; i < 256; i++) { let r = i; for (let bit = 8; bit > 0; --bit) r = ((r & 1) ? ((r >>> 1) ^ POLYNOMIAL) : (r >>> 1)); crc32_table[i] = r; } }

    Как только мы вызовем функцию crc32("депозит"), мы сможем получить значение 0xb04a29cf на практике.

    Для получения дополнительной информации о методе CRC32 вы можете перейти по следующим ссылкам:

    Документация TON CRC32 * Онлайн-инструмент CRC32
  • Как объединить строки в FunC?

    TON Overflow на русском
    0 Голоса
    1 Сообщения
    1 Просмотры

    Существует ли обычный способ объединить две строки с помощью FunC?

    Этот вопрос был импортирован из чата Telegram: <***Скрыто***

    click to show

    Оригинал вопроса

  • Как сравнить два среза на предмет равенства?

    TON Overflow на русском
    0 Голоса
    2 Сообщения
    9 Просмотры

    Похоже, он удален, чтобы заставить разработчиков использовать функцию equal_slice_bits. Это название функции лучше тем, что оно подчеркивает тот факт, что сравниваются только биты, а не ссылки.

    Это старое определение и того, и другого:

    ;;; Checks whether the data parts of two slices coinside int equal_slice_bits(slice a, slice b) asm "SDEQ"; int equal_slices(slice a, slice b) asm "SDEQ";

    Таким образом, это были обе равнозначные функции.

  • Имеет ли функция модульное умножение?

    TON Overflow на русском
    0 Голоса
    1 Сообщения
    0 Просмотры

    В модульной арифметике существует такое понятие, как модульное умножение. Есть ли у него встроенная поддержка в FunC?

    Этот вопрос был импортирован из чата Telegram: <***Скрыто***

    click to show

    Оригинал вопроса

  • 0 Голоса
    3 Сообщения
    1 Просмотры

    Спасибо!

  • 0 Голоса
    2 Сообщения
    7 Просмотры

    Решено

    Да, потребление газа действительно увеличивается с увеличением размера словаря. Это связано с тем, как упакован словарь.

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

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

  • 1 Голоса
    2 Сообщения
    15 Просмотры

    Вы можете использовать Buffer.from, чтобы решить эту проблему.

  • 0 Голоса
    1 Сообщения
    4 Просмотры

    Я использую Visual Studio Code с расширением "FunC Language Support" от Whales Corp. Эта настройка удобна и часто помогает при автозавершении в FunC. Но по какой-то причине, когда я набираю load_uint() или store_uint(), автозаполнение предлагает всевозможные варианты от load_coins до load_ref, но не тот, который мне нужен, хотя это популярная функция.

    Это не конец света, я могу напечатать все это вручную, но мне это кажется очень странным. Может быть, я чего-то не понимаю и поддержку load_uint() можно как-то включить?

    Оригинал вопроса