anchor 智能合约案例3 之 journal

前言:

前面我们介绍了 solana 关于 anchor 智能合约的环境搭建 配置,简单编写 发布 部署 调用 的一些落地。等等。接下来我们借着案例。详细剖析下智能合约编写。

案例 journal 介绍:

这是一个关于 日志的一个区块链应用。作者可以 将自己的日志 记录于 区块链:

智能合约的分析:

很多类似的操作 和 固定写法我们 之前的章节 有更详细的讲解。我们这里 着重 讲解下 这这个章节中学到的 新的姿势:

  • 更新 日记,因为

    复制代码
    solana 对于链上 pda 使用空间费用 是按照 实际占用的空间大小进行计算的,所以如果改变日记 内容。会造成 pda 账户 租金的变化。这里需要注意
    rust 复制代码
    // 更新日记
    pub fn update_journal_entry(ctx:Context<UpdateEntry>,title:String,message:String) -> Result<()> {
        let journal_entry = &mut ctx.accounts.journal_entry;
        journal_entry.message = message;
    
        Ok(())
    }
    
    // 对应结构体
    #[derive(Accounts)]
    #[instruction(title:String)]
    pub struct UpdateEntry<'info> {
        #[account(mut)]
        pub owner: Signer<'info>,
    
        // 这里不是创建 而是查找,并且要修改
        // solana 对于链上 pda 使用空间费用 是按照实际占用的空间大小进行计算的,
        // 这里的两个更新 会涉及两个 String 类型占用空间大小的改变。因此需要重新计算 费用,可能是 增加,也有可能是减小
        // 所以 这里的 account 宏  使用 realloc 约束,超出的需要付费,减少的 会 退回
        // realloc::zero = true,//原始空间设置为0 然后重新计算 大小
        #[account(
            mut,
            seeds = [title.as_bytes(), owner.key().as_ref()],
            bump,
            realloc = 8 + JournalEntryState::INIT_SPACE,
            realloc::payer = owner,
            realloc::zero = true,
        )]
        pub journal_entry:Account<'info, JournalEntryState>,
    
        pub system_program: Program<'info, System>,
    
    }
  • 删除日志,删除 pda 回收账户资金

    rust 复制代码
    // 删除日记
    pub fn delete_journal_entry(ctx:Context<DeleteEntry>,title:String) -> Result<()> {
    
        Ok(())
    }
    
    //对应结构体
    #[derive(Accounts)]
    #[instruction(title:String)]
    pub struct DeleteEntry<'info> {
        #[account(mut)]
        pub owner: Signer<'info>,
        // close 指定删除的 pda 必须是自己 也就是 payer,回收账户租金
        #[account(
          mut,
          seeds = [title.as_bytes(), owner.key().as_ref()],
          bump,
          close = owner,
        )]
        pub journal_entry:Account<'info, JournalEntryState>,
    
        pub system_program: Program<'info, System>,
    }

完整脚本:

rust 复制代码
use anchor_lang::prelude::*;

declare_id!("5U8DEe5jUTsTAWZBRmD6aRRnFwoDQSNHBqE9H93R2aXA");

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

    // 创建日记
    pub fn create_journal_entry(ctx: Context<CreateEntry>,title:String,message:String) -> Result<()> {
        //通过 CreateEntry  结构体指令 定位到 pad 上下文 进行赋值
        let journal_entry = &mut  ctx.accounts.journal_entry;
        journal_entry.title = title;
        journal_entry.message = message;
        journal_entry.owner = ctx.accounts.owner.key();

        Ok(())
    }

// 更新日记
pub fn update_journal_entry(ctx:Context<UpdateEntry>,title:String,message:String) -> Result<()> {
    let journal_entry = &mut ctx.accounts.journal_entry;
    journal_entry.message = message;

    Ok(())
}

// 删除日记
pub fn delete_journal_entry(ctx:Context<DeleteEntry>,title:String) -> Result<()> {

    Ok(())
}
}



#[derive(Accounts)]
#[instruction(title:String)]
pub struct CreateEntry<'info> {
    #[account(mut)]
    pub owner: Signer<'info>,

    #[account(
        init,
        payer = owner,
        space = 8 + JournalEntryState::INIT_SPACE,
        seeds = [title.as_bytes(), owner.key().as_ref()],
        bump,
    )]
    pub journal_entry:Account<'info, JournalEntryState>,

    pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
#[instruction(title:String)]
pub struct UpdateEntry<'info> {
    #[account(mut)]
    pub owner: Signer<'info>,

    // 这里不是创建 而是查找,并且要修改
    // solana 对于链上 pda 使用空间费用 是按照实际占用的空间大小进行计算的,
    // 这里的两个更新 会涉及两个 String 类型占用空间大小的改变。因此需要重新计算 费用,可能是 增加,也有可能是减小
    // 所以 这里的 account 宏  使用 realloc 约束,超出的需要付费,减少的 会 退回
    // realloc::zero = true,//原始空间设置为0 然后重新计算 大小
    #[account(
        mut,
        seeds = [title.as_bytes(), owner.key().as_ref()],
        bump,
        realloc = 8 + JournalEntryState::INIT_SPACE,
        realloc::payer = owner,
        realloc::zero = true,
    )]
    pub journal_entry:Account<'info, JournalEntryState>,

    pub system_program: Program<'info, System>,

}


#[derive(Accounts)]
#[instruction(title:String)]
pub struct DeleteEntry<'info> {
    #[account(mut)]
    pub owner: Signer<'info>,
    // close 指定删除的 pda 必须是自己 也就是 payer,回收账户租金
    #[account(
      mut,
      seeds = [title.as_bytes(), owner.key().as_ref()],
      bump,
      close = owner,
    )]
    pub journal_entry:Account<'info, JournalEntryState>,

    pub system_program: Program<'info, System>,
}




#[account]
#[derive(InitSpace)]
pub struct JournalEntryState {
    pub owner: Pubkey,
    #[max_len(50)]
    pub title: String,
    #[max_len(1000)]
    pub message: String,
}
相关推荐
葫三生15 分钟前
如何评价《论三生原理》在科技界的地位?
人工智能·算法·机器学习·数学建模·量子计算
m0_751336391 小时前
突破性进展:超短等离子体脉冲实现单电子量子干涉,为飞行量子比特奠定基础
人工智能·深度学习·量子计算·材料科学·光子器件·光子学·无线电电子
美狐美颜sdk4 小时前
跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能
android·人工智能·ios·架构·音视频·美颜sdk·第三方美颜sdk
DeepSeek-大模型系统教程5 小时前
推荐 7 个本周 yyds 的 GitHub 项目。
人工智能·ai·语言模型·大模型·github·ai大模型·大模型学习
郭庆汝5 小时前
pytorch、torchvision与python版本对应关系
人工智能·pytorch·python
小雷FansUnion7 小时前
深入理解MCP架构:智能服务编排、上下文管理与动态路由实战
人工智能·架构·大模型·mcp
资讯分享周7 小时前
扣子空间PPT生产力升级:AI智能生成与多模态创作新时代
人工智能·powerpoint
叶子爱分享8 小时前
计算机视觉与图像处理的关系
图像处理·人工智能·计算机视觉
鱼摆摆拜拜8 小时前
第 3 章:神经网络如何学习
人工智能·神经网络·学习
一只鹿鹿鹿8 小时前
信息化项目验收,软件工程评审和检查表单
大数据·人工智能·后端·智慧城市·软件工程