Проверка отправителя сообщения (sender) в Tact

Настроишь require(sender() == trusted): не примешь поддельные уведомления от чужих контрактов.

Проверка sender

В TON аутентификация на приёме internal-сообщения — это sender(): адрес контракта (или кошелька), который реально отправил сообщение. Поля body можно скопировать; адрес отправителя подделать нельзя. Доверяй данным только после сверки с известным адресом.


Уязвимо: доверие к opcode без sender

tact (fallback highlight)
// @tact-lang/compiler 1.6.13
// УЯЗВИМО: любой пришлёт PriceUpdate с нужным opcode

message PriceUpdate {
    price: Int as uint64;
}

contract ConsumerBad(
    price: Int as uint64,
) {
    receive() { cashback(sender()) }

    receive(msg: PriceUpdate) {
        // нет require(sender() == oracle)
        self.price = msg.price;
        cashback(sender());
    }

    get fun currentPrice(): Int {
        return self.price;
    }
}

Исправлено: whitelist адреса

tact (fallback highlight)
// @tact-lang/compiler 1.6.13
// ИСПРАВЛЕНО

message PriceUpdate {
    price: Int as uint64;
}

message SetOracle {
    next: Address;
}

contract ConsumerOk(
    oracle: Address,
    owner: Address,
    price: Int as uint64,
) {
    receive() { cashback(sender()) }

    receive(msg: PriceUpdate) {
        require(sender() == self.oracle, "fake oracle");
        require(msg.price > 0, "bad price");
        self.price = msg.price;
        cashback(sender());
    }

    receive(msg: SetOracle) {
        require(sender() == self.owner, "not owner");
        self.oracle = msg.next;
        cashback(sender());
    }

    get fun currentPrice(): Int {
        return self.price;
    }
}

Как это работает

  • Jetton deposit: sender() должен быть ожидаемым jetton-wallet (вычисленным из master + owner), а не «любым контрактом с похожим body».
  • NFT ingress: sender() = item, плюс проверка, что item принадлежит нужной collection.
  • sender() — не «пользователь с фронта»; часто это промежуточный контракт в цепочке сообщений.
  • Owner-check и partner-check — один механизм (require на адрес), разные роли в storage.

Частые ошибки

Сверяешь строку/opcode и игнорируешь sender → классическая подделка уведомления.

Хардкодишь адрес testnet-oracle в mainnet → либо тишина, либо чужой контракт с тем же init-кодом на другом ключе.

Принимаешь «с любого wallet пользователя» без привязки к своему registry → спам и ложные зачисления.


Что дальше

Материалы gramdocs.tech носят образовательный характер и не являются финансовой, юридической или инвестиционной рекомендацией. Работа с блокчейном TON и токеном Gram связана с рисками потери средств. Правовая информация