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,
}
相关推荐
AI科技星8 小时前
引力与电磁的动力学耦合:变化磁场产生引力场与电场方程的第一性原理推导、验证与统一性意义
服务器·人工智能·科技·线性代数·算法·机器学习·生活
hkNaruto8 小时前
【AI】AI学习笔记:OpenAI Tools完全指南:从原理到实战入门
人工智能·笔记·学习
狮子座明仔8 小时前
MiMo-V2-Flash 深度解读:小米 309B 开源 MoE 模型如何用 15B 激活参数吊打 671B 巨头?
人工智能·语言模型·自然语言处理
紧固件研究社8 小时前
从标准件到复杂异形件,紧固件设备如何赋能制造升级
人工智能·制造·紧固件
木头左8 小时前
贝叶斯深度学习在指数期权风险价值VaR估计中的实现与应用
人工智能·深度学习
反向跟单策略8 小时前
期货反向跟单—高频换人能够提高跟单效率?
大数据·人工智能·学习·数据分析·区块链
哎吆我呸8 小时前
Android studio 安装Claude Code GUI 插件报错无法找到Node.js解决方案
人工智能
咕噜企业分发小米8 小时前
独立IP服务器有哪些常见的应用场景?
人工智能·阿里云·云计算
测试者家园8 小时前
AI 智能体如何构建模拟真实用户行为的复杂负载场景?
人工智能·压力测试·性能测试·智能体·用户行为·智能化测试·软件开发和测试
MF_AI8 小时前
苹果病害检测识别数据集:1w+图像,5类,yolo标注
图像处理·人工智能·深度学习·yolo·计算机视觉