区块链开发中`function`与`method`的区别及相关概念问询
区分Scrypto中的Function与Method,理解状态变更
什么是State(状态)?
在Scrypto这类区块链智能合约里,State就是合约存在链上的持久化数据——比如NFT的元数据、用户的代币余额、合约的运营参数这些。这些数据会被区块链全网记录,一旦修改就会永久写入区块,所有节点都能同步和查询。“改变state”就是指修改这些链上存储的数据,比如更新NFT的名称、给用户转代币,这类操作会改变链上的永久记录。
Function与Method的核心区别
- Function(函数):纯读/创建类操作,不会修改已有合约的State,执行时一般不消耗Gas(除非是创建新资源/合约的场景,因为要写入链上新数据)。Scrypto里用
#[function]注解标记。 - Method(方法):写操作,会修改合约的State,执行时必须消耗Gas(因为要把新状态写入区块链),且必须通过调用已部署的合约组件实例来执行。Scrypto里用
#[method]注解标记。
Scrypto代码实例(带NFT元数据操作)
use scrypto::prelude::*; #[blueprint] mod nft_collection { struct NFTCollection { // 存储NFT的Vault,属于合约State nft_vault: Vault, // 存储NFT元数据的哈希表,属于合约State nft_metadata: HashMap<NonFungibleLocalId, String>, } impl NFTCollection { // 构造函数:创建新的NFT合约实例,标记为function #[function] pub fn instantiate_collection() -> ComponentAddress { // 创建NFT资源并 mint 初始供应 let nft_bucket = ResourceBuilder::new_non_fungible() .metadata("collection_name", "My Cool NFTs") .mint_initial_supply([(NonFungibleLocalId::integer(1), "Genesis NFT".to_string())]); // 初始化合约结构体并部署为全局组件 Self { nft_vault: Vault::with_bucket(nft_bucket), nft_metadata: HashMap::from([(NonFungibleLocalId::integer(1), "Genesis NFT".to_string())]), } .instantiate() .globalize() } // 读取NFT元数据:纯读操作,标记为function #[function] pub fn get_nft_metadata(&self, nft_id: NonFungibleLocalId) -> Option<&String> { // 只读取State中的nft_metadata,不做修改 self.nft_metadata.get(&nft_id) } // 修改NFT元数据:写操作,标记为method #[method] pub fn update_nft_metadata(&mut self, nft_id: NonFungibleLocalId, new_desc: String) { // 修改State中的nft_metadata哈希表 self.nft_metadata.insert(nft_id, new_desc); } } }
实例说明
instantiate_collection:作为合约的构造函数,用来创建新的合约实例和NFT资源,虽然会写入链上新数据,但Scrypto中仍标记为function,因为它不是修改已有合约的状态。get_nft_metadata:仅读取合约State中的元数据,没有任何修改操作,所以是function。update_nft_metadata:修改了合约内部的nft_metadata变量(属于State),需要&mut self来获取可变引用,因此是method。
你的问题解答:修改NFT元数据属于Method吗?
是的,修改NFT元数据完全属于method。因为这个操作会改变合约存储在链上的State(比如上面例子里的nft_metadata哈希表),需要写入区块链并消耗Gas,符合method的核心特征。
Scrypto中快速区分的指南
- 看注解:直接看代码里的
#[function]或#[method]标记,这是最直观的区分方式。 - 看参数中的self:如果函数需要
&mut self,那一定是method(要修改合约状态);如果是&self或不需要self,大概率是function。 - 看操作类型:
- 读取数据、计算结果、创建新合约/资源 → Function
- 修改已有数据、转移资产、更新配置 → Method
- 看Gas消耗:Method执行必然消耗Gas;Function除非是创建资源/合约,否则不消耗Gas。
内容的提问来源于stack exchange,提问作者Kaustubh Shete
相关产品推荐
相关产品推荐

