Get 方法
介绍
Get方法是智能合约中用于查询特定数据的特殊函数。它们的执行不需要任何费用,并且在区块链之外进行。
这些函数对于大多数智能合约来说都非常常见。例如,默认的钱包合约有几个get方法,如seqno()
、get_subwallet_id()
和get_public_key()
。它们被钱包、SDK和API用来获取有关钱包的数据。
Get 方法的设计模式
基本 get 方法设计模式
-
单一数据点检索:一种基本设计模式是创建返回合约状态中单个数据点的方法。这些方法没有参数,并返回单个值。
示例:
int get_balance() method_id {
return get_data().begin_parse().preload_uint(64);
} -
聚合数据检索:另一种常见的模式是创建一次返回合约状态中多个数据点的方法。这通常在某些数据点一起使用时采用。这些在Jetton和NFT合约中非常常见。
示例:
(int, slice, slice, cell) get_wallet_data() method_id {
return load_data();
}
高级 get 方法设计模式
-
计算数据检索:在某些情况下,需要检索的数据并不直接存储在合约的状态中,而是根据状态和输入参数计算得出的。
示例:
slice get_wallet_address(slice owner_address) method_id {
(int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data();
return calculate_user_jetton_wallet_address(owner_address, my_address(), jetton_wallet_code);
} -
条件数据检索:有时需要检索的数据取决于某些条件,如当前时间。
示例:
(int) get_ready_to_be_used() method_id {
int ready? = now() >= 1686459600;
return ready?;
}
最常见的 get 方法
标准钱包
seqno()
int seqno() method_id {
return get_data().begin_parse().preload_uint(32);
}
返回特定钱包中交易的序列号。这个方法主要用于重放保护。
get_subwallet_id()
int get_subwallet_id() method_id {
return get_data().begin_parse().skip_bits(32).preload_uint(32);
}
get_public_key()
int get_public_key() method_id {
var cs = get_data().begin_parse().skip_bits(64);
return cs.preload_uint(256);
}
检索与钱包关联的公钥。
Jettons
get_wallet_data()
(int, slice, slice, cell) get_wallet_data() method_id {
return load_data();
}
这个方法返回与Jetton钱包相关的完整数据集:
- (int) 余额
- (slice) 持有者地址
- (slice) Jetton主合约地址
- (cell) Jetton钱包代码
get_jetton_data()
(int, int, slice, cell, cell) get_jetton_data() method_id {
(int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data();
return (total_supply, -1, admin_address, content, jetton_wallet_code);
}
返回Jetton主合约的数据,包括其总供应量、管理员地址、Jetton内容和钱包代码。
get_wallet_address(slice owner_address)
slice get_wallet_address(slice owner_address) method_id {
(int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data();
return calculate_user_jetton_wallet_address(owner_address, my_address(), jetton_wallet_code);
}
根据所有者的地址,此方法计算并返回所有者的Jetton钱包合约地址。
NFTs
get_nft_data()
(int, int, slice, slice, cell) get_nft_data() method_id {
(int init?, int index, slice collection_address, slice owner_address, cell content) = load_data();
return (init?, index, collection_address, owner_address, content);
}
返回与非同质化代币相关的数据,包括是否已初始化、在集合中的索引、集合地址、所有者地址和个体内容。
get_collection_data()
(int, cell, slice) get_collection_data() method_id {
var (owner_address, next_item_index, content, _, _) = load_data();
slice cs = content.begin_parse();
return (next_item_index, cs~load_ref(), owner_address);
}
返回NFT集合的数据,包括下一个要铸造的项目索引、集合内容和所有者地址。
get_nft_address_by_index(int index)
slice get_nft_address_by_index(int index) method_id {
var (_, _, _, nft_item_code, _) = load_data();
cell state_init = calculate_nft_item_state_init(index, nft_item_code);
return calculate_nft_item_address(workchain(), state_init);
}
给定索引,此方法计算并返回该集合的相应NFT项目合约地址。
royalty_params()
(int, int, slice) royalty_params() method_id {
var (_, _, _, _, royalty) = load_data();
slice rs = royalty.begin_parse();
return (rs~load_uint(16), rs~load_uint(16), rs~load_msg_addr());
}
获取NFT的版税参数。这些参数包括原始创作者在NFT被出售时应支付的版税百分比。
get_nft_content(int index, cell individual_nft_content)
cell get_nft_content(int index, cell individual_nft_content) method_id {
var (_, _, content, _, _) = load_data();
slice cs = content.begin_parse();
cs~load_ref();
slice common_content = cs~load_ref().begin_parse();
return (begin_cell()
.store_uint(1, 8) ;; offchain tag
.store_slice(common_content)
.store_ref(individual_nft_content)
.end_cell());
}
给定索引和个体NFT内容,此方法获取并返回NFT的常见内容和个体内容。