当前位置: 首页 > news >正文

anchor 智能合约案例3 之 journal

前言:

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

案例 journal 介绍: 

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

 智能合约的分析:

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

  • 更新 日记,因为
    solana 对于链上 pda 使用空间费用 是按照 实际占用的空间大小进行计算的,所以如果改变日记 内容。会造成 pda 账户 租金的变化。这里需要注意
    // 更新日记
    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  回收账户资金 

    // 删除日记
    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>,
    }

完整脚本: 

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,
}

http://www.lqws.cn/news/594325.html

相关文章:

  • Docker进阶命令与参数——AI教你学Docker
  • 想做跑腿配送生意,怎么第三方平台订单对接?
  • MCU、LIN收发器、LIN总线、节点,它们之间是如何协作的?
  • SVN 分支管理(本文以Unity项目为例)
  • 以下是 Kafka 不同认证方式的配置示例,结合前面的单表设计方案,展示如何为每种认证方式填充配置表
  • 【Go-选项模式】
  • Spring Boot 2 多模块项目中配置文件的加载顺序
  • 2025年主流大厂Java后端面试题主题深度解析
  • 【深度学习新浪潮】人工智能在文物考古领域有哪些最新研究进展?
  • 基于开源AI大模型AI智能名片S2B2C商城小程序的流量转化与价值沉淀研究
  • 借助飞算AI新手小白快速入门Java实操记录
  • AbMole| H₂DCFDA(M9096;活性氧(ROS)探针)
  • C#基础(DllImport)
  • CppCon 2018 学习:Better C++ using Machine Learning on Large Projects
  • [Python 基础课程]字符串
  • Tomcat9部署jsp产生错误FileCountLimitExceededException
  • 网络安全监测探针功能
  • Python 数据分析:DataFrame,生成,用字典创建 DataFrame ,键值对数量不一样怎么办?
  • python+uniapp基于微信小程序的PS社区系统
  • 基于3D卷积神经网络与多模态信息融合的医学影像肿瘤分类与可视化分析
  • JVM调优实战 Day 15:云原生环境下的JVM配置
  • Go 服务如何“主动”通知用户?SSE广播与断线重连实战
  • 【算法】动态规划:python实现 1
  • 前端开发git的使用(常用命令和规范)
  • Python ORM 完全指南:从基础到高级实践
  • UI前端大数据可视化实战技巧分享:如何选择合适的颜色与图表类型?
  • MATLAB构建capm和三因子模型
  • t检验​、​z检验、χ²检验中的P值
  • rabbitmq动态创建交换机、队列、动态绑定,销毁
  • 企业上网行为管理:零信任安全产品的对比分析