Get-методы
Get-методы — это «окна» для чтения состояния контракта без отправки транзакций. Они выполняются локально на лайтсервере и не расходуют газ, что делает их идеальным инструментом для отображения данных в UI и интеграции с off-chain сервисами. Правильное проектирование get-методов определяет, насколько удобно будет другим разработчикам и фронтенд-приложениям взаимодействовать с вашим контрактом.
Get-методы — это read-only функции контракта, которые вызываются off-chain (вне блокчейна). Они позволяют читать состояние контракта без отправки транзакций и без оплаты газа.
Что такое get-метод?
Get-метод — это функция, объявленная с ключевым словом get fun. Она:
- Не изменяет состояние — только чтение
- Вызывается off-chain — из TypeScript, через API, из кошельков
- Бесплатна — не требует транзакции и газа
- Выполняется на ноде — TVM запускает код локально на ноде
contract Counter with Deployable {
counter: Int as uint32;
owner: Address;
lastSender: Address;
init(owner: Address) {
self.owner = owner;
self.counter = 0;
self.lastSender = owner;
}
receive("increment") {
self.counter += 1;
self.lastSender = sender();
}
// Get-методы
get fun counter(): Int {
return self.counter;
}
get fun owner(): Address {
return self.owner;
}
get fun lastSender(): Address {
return self.lastSender;
}
}
Синтаксис get fun
// Простой get-метод
get fun balance(): Int {
return self.balance;
}
// Get-метод с вычислением
get fun isActive(): Bool {
return self.balance > 0 && self.active;
}
// Get-метод, возвращающий строку
get fun version(): String {
return "1.0.0";
}
// Get-метод, возвращающий Cell
get fun stateData(): Cell {
return beginCell()
.storeUint(self.counter, 32)
.storeAddress(self.owner)
.endCell();
}
Возвращаемые типы
Get-методы могут возвращать любой тип Tact:
| Тип | Пример |
|---|---|
Int | Счётчики, балансы, timestamps |
Bool | Флаги состояния |
Address | Адреса владельцев, участников |
Cell | Сериализованные данные |
String | Строковые значения |
map<K, V> | Словари |
Вызов get-методов из TypeScript
Через wrapper-класс (Blueprint)
// wrappers/Counter.ts
import { Address, Contract, ContractProvider } from '@ton/core';
export class Counter implements Contract {
constructor(readonly address: Address) {}
async getCounter(provider: ContractProvider): Promise<bigint> {
const result = await provider.get('counter', []);
return result.stack.readBigNumber();
}
async getOwner(provider: ContractProvider): Promise<Address> {
const result = await provider.get('owner', []);
return result.stack.readAddress();
}
async getLastSender(provider: ContractProvider): Promise<Address> {
const result = await provider.get('lastSender', []);
return result.stack.readAddress();
}
}
Использование в тестах
import { Blockchain, SandboxContract, TreasuryContract } from '@ton/sandbox';
import { toNano } from '@ton/core';
import { Counter } from '../wrappers/Counter';
describe('Counter get methods', () => {
let blockchain: Blockchain;
let counter: SandboxContract<Counter>;
let deployer: SandboxContract<TreasuryContract>;
beforeEach(async () => {
blockchain = await Blockchain.create();
deployer = await blockchain.treasury('deployer');
counter = blockchain.openContract(
await Counter.fromInit(deployer.address)
);
await counter.send(
deployer.getSender(),
{ value: toNano('0.05') },
{ $$type: 'Deploy', queryId: 0n }
);
});
it('should return initial counter', async () => {
const value = await counter.getCounter();
expect(value).toEqual(0n);
});
it('should return owner', async () => {
const owner = await counter.getOwner();
expect(owner.equals(deployer.address)).toBe(true);
});
it('should update lastSender after increment', async () => {
const user = await blockchain.treasury('user');
await counter.send(
user.getSender(),
{ value: toNano('0.02') },
'increment'
);
const last = await counter.getLastSender();
expect(last.equals(user.address)).toBe(true);
});
});
Get Method IDs
Каждый get-метод имеет числовой ID, по которому TVM его находит. ID вычисляется как хеш от имени метода:
method_id = crc16(method_name) | 0x10000
Tact и FunC автоматически вычисляют ID при компиляции. При вызове через API указывается имя метода, а клиентская библиотека преобразует его в ID.
Get-методы в TON — это не транзакции. Они выполняются локально на ноде (lite-server) и не записываются в блокчейн. Это делает их быстрыми и бесплатными, но означает, что результат может быть слегка устаревшим (зависит от синхронизации ноды).
Паттерны использования
Проверка баланса
get fun balance(): Int {
return myBalance(); // Баланс контракта в наноТон
}
Инспекция состояния
contract Auction {
highestBid: Int as coins;
highestBidder: Address;
endTime: Int as uint64;
// ...
get fun auctionInfo(): AuctionInfo {
return AuctionInfo{
highestBid: self.highestBid,
highestBidder: self.highestBidder,
endTime: self.endTime,
isActive: now() < self.endTime,
};
}
}
Конфигурационные запросы
contract Config {
version: Int as uint16;
maxUsers: Int as uint32;
admin: Address;
// ...
get fun version(): Int {
return self.version;
}
get fun maxUsers(): Int {
return self.maxUsers;
}
get fun admin(): Address {
return self.admin;
}
}
Get-методы vs receivers
| Свойство | Get-метод | Receiver |
|---|---|---|
| Ключевое слово | get fun | receive |
| Изменение состояния | Нет | Да |
| Вызов | Off-chain (API) | On-chain (сообщение) |
| Стоимость | Бесплатно | Оплата газа |
| Запись в блокчейн | Нет | Да |
Частые ошибки
- Вызывают get-методы из on-chain кода (из других контрактов), хотя get-методы работают только off-chain; для on-chain чтения нужно отправлять сообщения.
- Возвращают слишком большие структуры данных из get-методов, что замедляет ответ лайтсервера и усложняет парсинг на клиенте.
- Не учитывают, что get-метод показывает состояние на момент последнего обработанного блока, и данные могут быть на несколько секунд устаревшими.
- Забывают реализовать базовые get-методы (balance, owner, state) в своих контрактах, что затрудняет мониторинг и интеграцию.
Проверка знанийПочему get-методы бесплатны для вызова, хотя они выполняют код TVM?
Проверьте понимание
Закончили урок?
Отметьте его как пройденный, чтобы отслеживать свой прогресс
Войдите чтобы оценить урок