Solana 60 天课程

2025年02月27日更新 66 人订阅
原价: ¥ 28 限时优惠
专栏简介 开始 Solana - 安装与故障排除 Solana 和 Rust 中的算术与基本类型 Solana Anchor 程序 IDL Solana中的Require、Revert和自定义错误 Solana程序是可升级的,并且没有构造函数 Solidity开发者的Rust基础 Rust不寻常的语法 Rust 函数式过程宏 Rust 结构体与属性式和自定义派生宏 Rust 和 Solana 中的可见性与“继承” Solana时钟及其他“区块”变量 Solana 系统变量详解 Solana 日志、“事件”与交易历史 Tx.origin、msg.sender 和 onlyOwner 在 Solana 中:识别调用者 Solana 计算单元与交易费用介绍 在 Solana 和 Anchor 中初始化账户 Solana 计数器教程:在账户中读写数据 使用 Solana web3 js 和 Anchor 读取账户数据 在Solana中创建“映射”和“嵌套映射” Solana中的存储成本、最大存储容量和账户调整 在 Solana 中读取账户余额的 Anchor 方法:address(account).balance 功能修饰符(view、pure、payable)和回退函数在 Solana 中不存在的原因 在 Solana 上实现 SOL 转账及构建支付分配器 使用不同签名者修改账户 PDA(程序派生地址)与 Solana 中的密钥对账户 理解 Solana 中的账户所有权:从PDA中转移SOL Anchor 中的 Init if needed 与重初始化攻击 Solana 中的多重调用:批量交易与交易大小限制 Solana 中的所有者与权限 在Solana中删除和关闭账户与程序 在 Anchor 中:不同类型的账户 在链上读取另一个锚点程序账户数据 在 Anchor 中的跨程序调用(CPI)

Rust 和 Solana 中的可见性与“继承”

  • RareSkills
  • 发布于 2024-02-19 15:59
  • 阅读 833

本文详细讲解了如何将Solidity中的函数可见性和合约继承概念化到Solana中,并提供了Rust语言中实现这些概念的代码示例。

Rust function visibillity

今天我们将学习如何在 Solana 中构思 Solidity 的函数可见性和合约继承。Solidity 中有四种函数可见性级别,它们是:

  • public – 从合约内部和外部均可访问。
  • external – 从合约外部仅可访问。
  • internal – 从合约内部和继承合约中可访问。
  • private – 仅在合约内部可访问。

让我们在 Solana 中实现相同的功能,好吗?

公共函数

自第一天起到现在我们定义的所有函数都是公共函数:

pub fn my_public_function(ctx: Context<Initialize>) -> Result<()> {
    // 函数逻辑...

    Ok(())
}

在函数声明前添加 pub 关键字,从而使函数变为公共。

你不能移除标记为 #[program] 的模块 (mod) 内部的函数的 pub 关键字。这将导致无法编译。

不用太担心 external 和 public 之间的区别

在 Solana 程序中,调用自己公共函数通常是不方便的。如果 Solana 程序中存在 pub 函数,从实际角度来看,你可以将其视作为在 Solidity 中的外部函数。

如果你想在同一个 Solana 程序中调用公共函数,包裹这个公共函数并调用该内部实现函数要更容易。

私有和内部函数

虽然你不能在使用 #[program] 宏的模块中声明没有 pub 的函数,但你可以在文件内部声明函数。考虑以下代码:

use anchor_lang::prelude::*;

declare_id!("F26bvRaY1ut3TD1NhrXMsKHpssxF2PAUQ7SjZtnrLkaM");

#[program]
pub mod func_test {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        // -------- 调用一个“私有”函数 --------
        let u = get_a_num();
        msg!("{}", u);
        Ok(())
    }
}

// ------- 我们在此声明了一个非 pub 函数 -------
fn get_a_num() -> u64 {
    2
}

#[derive(Accounts)]
pub struct Initialize {}

这将按预期运行并记录。

如果你想构建简单的 Solana 程序,这些是你真正需要了解的有关公共和内部函数的所有内容。但如果你希望比仅仅在文件中声明一堆函数更好地组织代码,你可以继续深入。Rust,因此 Solana,没有像 Solidity 那样的“类”,因为 Rust 不是面向对象的。因此,“私有”和“内部”之间的区别在 Rust 中没有直接类比。

Rust 使用模块来组织代码。模块内外函数的可见性在Rust 文档的可见性和隐私部分中有很好的讨论,但我们将添加自己针对 Solana 的见解。

内部函数

通过在程序模块内定义函数并确保其在其自己的模块及导入或使用它的其他模块内可访问来实现。这是怎么做的:

use anchor_lang::prelude::*;

declare_id!("53hgft52DHUKMPHGu1kusuwxFGk2T8qngwSw2SyGRNrX");

#[program]
pub mod func_visibility {
    use super::*;

    pub fn initialize(_ctx: Context<Initialize>) -> Result<()> {
        // 从其父模块内部调用 internal_function
        some_internal_function::internal_function();

        Ok(())
    }

    pub mod some_internal_function {
        pub fn internal_function() {
            // 内部函数逻辑...
        }
    }
}

mod do_something {
    // 导入 func_visibility 模块
    use crate::func_visibility;

    pub fn some_func_here() {
        // 从外部其父模块调用 internal_function
        func_visibility::some_internal_function::internal_function();

        // 做其他事情...
    }
}

#[derive(Accounts)]
pub struct Initialize {}

构建程序后,如果导航到 ./target/idl/func_visibility.json 文件,你将看到定义在 some_internal_function 模块中的函数没有被包含在构建程序中。这表明 some_internal_function 函数是内部的,仅能在程序内部及任何导入或使用它的程序中访问。

从上面的例子中,我们能够从其“父”模块(func_visibility)内部访问 internal_function 函数,也能从 func_visibility 模块外的单独模块中访问(do_something)。

私有函数

在特定模块内定义函数并确保它们不会暴露在该作用域之外就是实现私有可见性的一种方式:


use anchor_lang::prelude::*;

declare_id!("53hgft52DHUKMPHGu1kusuwxFGk2T8qngwSw2SyGRNrX");

#[program]
pub mod func_visibility {
    use super::*;

    pub fn initialize(_ctx: Context<Initialize>) -> Result<()> {
        // 从其父模块内部调用...

剩余50%的内容订阅专栏后可查看

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论