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

小试牛刀-Solana合约账户详解

目录

一.Solana

三.账户详解

3.1 程序账户

3.2 系统所有账户

3.3 程序派生账户(PDA)

3.4 Token账户

四、相关学习文档

五、在线编辑器


Welcome to Code Block's blog

本篇文章主要介绍了

[Solana合约账户详解]
❤博主广交技术好友,喜欢文章的可以关注一下❤

注:该篇文章在测试环境下进行,使用测试账户进行。

一.合约账户类型

        开发语言上,Solana合约使用Rust为主要开发语言,其次是Solana合约并不像其它链那样将数据直接存到合约里,而是使用了更加独立的账户来代币转移和存储数据。按功能可以分为以下账户: 

  •         程序账户
  •         系统所有账户
  •         程序派生账户(PDA)
  •         Token账户

二.账户详解

2.1 程序账户

        程序账户即为合约部署后生成的账户,这个账户用于存储和执行智能合约代码,即合约部署后生成的地址。这里部署地址是:Fckx9Sxf17hyauwe1nfxL9GtvruESb5kTrU2LCPLJpzm
测试截图:

2.2 系统所有账户

       用户通过调用程序账户生成用于存储状态的数据的账户为系统所有账户,这个账户的所有者为当前合约。同时用户可以获得当前账户的公钥和私钥信息。使用TS创建的代码如下:

    const greetingAccountKp = new web3.Keypair();const lamports = await pg.connection.getMinimumBalanceForRentExemption(GREETING_SIZE);console.log(GREETING_SIZE);const createGreetingAccountIx = web3.SystemProgram.createAccount({fromPubkey: pg.wallet.publicKey,lamports,newAccountPubkey: greetingAccountKp.publicKey,programId: pg.PROGRAM_ID,space: GREETING_SIZE,});const tx = new web3.Transaction();tx.add(createGreetingAccountIx);const txHash = await web3.sendAndConfirmTransaction(pg.connection, tx, [pg.wallet.keypair,greetingAccountKp,]);console.log(`Use 'solana confirm -v ${txHash}' to see the logs`);

执行上述代码并成功后,这里的greetingAccountKp内的公钥和私钥即为创建账户的公钥和私钥。可以通过以下方式进行打印:

    console.log("publicKey:" + greetingAccountKp.publicKey.toBase58());console.log("secretKey:" + greetingAccountKp.secretKey);

这个账户与普通账户的不同之处在于其用于存储数据,账户owner为当前程序账户,在合约内可以使用以下方式在合约内进行打印:

    // 账户列表let accounts_iter = &mut accounts.iter();// 下一个账户let account = next_account_info(accounts_iter)?;// 打印账户拥有者msg!("account:{}", account.owner);

log截图:

测试截图:

2.3 程序派生账户(PDA)

        在实际应用中,用户在创建账户后即需要存储账户信息,这显然是不符合实际需求的,首先这会生成大量账户浪费资源,并且不利于账户管理和维护。如实现用户锁仓功能:用户创建一个账户后,服务程序即需要存储这个钱包创建的对应账户地址。PDA账户很好的解决了这个问题。PDA的原理为让程序通过利用种子(方法名或其它)+用户钱包公钥+程序账户(合约地址),三者进行加密运算生成一个钱包地址,这个地址是唯一的,在后续运算中仍然会生成这个地址,这样即解决了账户存储和管理问题。TS代码PDA账户生成方式如下:

async function getPda(programId, userPubkey) {const [pda, bump] = await web3.PublicKey.findProgramAddressSync([Buffer.from("lock"), userPubkey.toBuffer()],programId);console.log("PDA:", pda.toBase58());return pda;
}

这里的lock为种子(种子是可变的,可使用对应合约方法名,便于管理),userPubkey为用户地址,programId为程序账户账户地址.使用如下方式进行调用(会发现每次生成地址结果为同一地址):

    const pda = getPda(pg.PROGRAM_ID, greetingAccountKp.publicKey);console.log(pda);

测试截图:

通过截图可以看到运行多次生成的地址为相同的.

2.4 Token账户

        SPL账户即为存储某个特定的代币创建的账户,该账户用于存储某个特定类型的代币,创建方式如下:

async function createSPLAccount() {const mint = new web3.PublicKey('代币合约地址'); const owner = payerAccount.publicKey; // 付款账户// 创建 SPL 账户const tokenAccount = await splToken.Token.createAccount(connection, {mint,owner,});console.log('SPL 账户创建成功:', tokenAccount.toBase58());
}

三、相关学习文档

1.Solana官方文档

2.Solana GitHub 仓库

四、在线编辑器

1.Solana IDE

声明:该文章只作为学习和使用相关,不涉及投资等其它建议.

相关文章:

  • JS实现当前元素的同级元素 以及父元素的同级元素
  • k8s流控平台apiserver详解
  • xtrabackup 备份报错“too many open files“ 突然消失
  • Hive数据倾斜--处理方法
  • 数据操作10-15题(30 天 Pandas 挑战)
  • Redis面试合集
  • JVM原理(二):JVM之HotSpot虚拟机中对象的创建寻位与定位整体流程
  • 如何取消闪迪Micro SD卡的写保护?这个技巧很有效!
  • 【C语言内存函数】
  • PHP景区旅游多商户版微信小程序系统源码
  • Kafka 管理TCP连接
  • 《妃梦千年》第二十四章:皇后的考验
  • Java+前后端分离架构+ MySQL8.0.36产科信息管理系统 产科电子病历系统源码
  • AIGI赋能未来:人工智能如何重塑电子电路学习体验
  • 探索金融数据API:现代投资的关键工具
  • 2019.2.20 c++ 知识梳理
  • Debian下无root权限使用Python访问Oracle
  • JS+CSS实现数字滚动
  • Linux CTF 逆向入门
  • Lucene解析 - 基本概念
  • nodejs调试方法
  • spark本地环境的搭建到运行第一个spark程序
  • 安卓应用性能调试和优化经验分享
  • 闭包--闭包之tab栏切换(四)
  • 理解在java “”i=i++;”所发生的事情
  • 深度学习中的信息论知识详解
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 我建了一个叫Hello World的项目
  • 想写好前端,先练好内功
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #pragma data_seg 共享数据区(转)
  • $.proxy和$.extend
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (十三)Flask之特殊装饰器详解
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (转载)深入super,看Python如何解决钻石继承难题
  • 、写入Shellcode到注册表上线
  • .chm格式文件如何阅读
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .Net Core 中间件与过滤器
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .Net的C#语言取月份数值对应的MonthName值
  • .Net环境下的缓存技术介绍
  • .net网站发布-允许更新此预编译站点
  • .NET中使用Protobuffer 实现序列化和反序列化
  • /usr/lib/mysql/plugin权限_给数据库增加密码策略遇到的权限问题
  • @Autowired自动装配
  • [ C++ ] STL---仿函数与priority_queue
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)
  • [ 网络通信基础 ]——网络的传输介质(双绞线,光纤,标准,线序)
  • [ 英语 ] 马斯克抱水槽“入主”推特总部中那句 Let that sink in 到底是什么梗?
  • [].slice.call()将类数组转化为真正的数组