TON Дев Чат
var
, вместо этого пишите указывайте конкретный тип переменных, которые как вы думаете будет у переменной. Обратите внимание, что можно указывать тип внутри кортежа, например:
(int request_seqno, int valid_until) = (msg_slice~load_uint(32), msg_slice~load_uint(32));
swap <s s, b{0} s, swap B, swap <s s, b>
swap <s s,
дописать в конец билдера state_init (т.е. биты дописываются в конец бит, референсы переходят билдеру)b{0} s,
положить единичный бит false (хз что он значит)swap B,
дописать в конец билдера подпись (она до выполнения этой команды как раз лежала под билдером в Bytes формате)swap <s s,
дописать в конец билдера ячейку с сообщением (по дефолту там слово TEST в аски)b>
закрыть билдер (билдер превращается в ячейку)
."Printing point 1" cr .s cr
это набор команд который печатает строку Printing point 1
(чтобы разобраться когда вывода много) и печатает весь стек не меняя его.
https://www.binance.com.ru/telegram-token-gram-ton
(мошенники)
1 exit_code 43 - 0= / // Stop if wrong exit code
$# 1- -2 and // true если дали не 1 или 2 аргумента
runvmctx
.runvm
, теперь туда можно передавать идентификатор функции с которой нужно начинать исполнение. Функциям recv_internal
и main
присваивается идентификатор 0, recv_external
- -1
. Таким образом, чтобы код тестирования выше снова работал необходимо вызов runvm
заменить на
-1 constant recv_external
message recv_external code storage runvm
runvm
не инициализирует регистр c7
в котором содержатся внешние сведения о контракте и блокчейне: unix время, логическое время, адрес контракта, баланс итп. Соответственно, контракты которые использут, например опкод NOW, будут падать. Чтобы тестировать такие контракты нужно самостоятельно заполнить кортеж который должен быть в c7
и передать его при запуске runvmctx
. Пример заполнения кортежа:
0 tuple 0x076ef1ea , // magic
0 , 0 , // actions msg_sents
1570470873 , // unix_time
1 , 1 , 0 , // block_lt, trans_lt, rand_seed
0 tuple 9223372036854775807 , dictnew , , // remaining balance
0 , dictnew , // contract_address, global_config
1 tuple // wrap to another tuple
constant c7
и запуска кода:
message recv_external code storage c7 runvmctx
(tuple) wrap_single (slice x) asm "SINGLE";
(tuple) wrap2tuples (tuple x, tuple y) asm "PAIR";
(tuple) zip_bomb(slice seed, int level) impure {
int current_level = 0;
var bomb = wrap_single(seed);
do {
current_level += 1;
bomb = wrap2tuples(bomb, bomb);
} until (current_level > level );
return bomb;
}
() recv_external(slice in_msg) impure {
zip_bomb(in_msg, 10);
}
() main () {
}
(slice) zip_bomb(slice seed, int level) impure {
int current_level = 0;
var bomb = begin_cell();
do {
current_level += 1;
cell c = bomb.end_cell();
builder bomb1 = bomb.store_ref(c).store_ref(c);
bomb = bomb1;
} until (current_level > level );
return bomb.end_cell().begin_parse();
}
() recv_external(slice in_msg) impure {
zip_bomb(in_msg, 2);
}
() main () {
}
new-wallet.fif
подставляю код, полученный из wallet-code.fc
и отправляю сгенерированное сообщение в сеть. External message НЕ отобрбажается. Что я мог сделать не так?simple-wallet-code.fc
компилировать
throw_if
после accept_message
. Проблема таких ошибочных транзакйий не в том что в этом случае с тебя спишут все деньги выделенные на газ (в аналогичной ситуации в биткоин скрипте, скрипт просто не войдет в блок), как например в эфире. Валидаторы смогут снова и снова посылать сообщение контракту (а replay protection рассчитанный на запись в storage не сработает) и таким образом можно потерять все деньги.sequence_number
достаточно. С мультисигами это не так, один и тот же ключ довольно часто будет фигурировать в разных мультисигах. И если для авторизации ордера использовать подпись seq_no+
order_data, то поскольку seq_no
у разных контрактов заведомо повторится, подпись ордера в одном контракте может авторизовать тот же самый ордер в другом (против воли подписавшего этот ордер в первом контракте). Вещь о которой совершенно не надо думать в эфире с его replay protection на уровне всех сообщений. Соответсвенно, чтобы этого избежать стоит подписывать что-то уникальное для контракта, например его адрес, т.е. seq_no
(для защиты от реплея на уровне контракта), address
(для защиты реплея между контрактами) и order
(для защиты от подмены ордера).seq_no
изменит). Очевидное решение - сделать одну подпись на все сообщение целиком на первый взгляд ломает возможность "доподписывать" сообщения и мержить коллекции подписей.