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

上海商业网站建设费用app推广工作靠谱吗

上海商业网站建设费用,app推广工作靠谱吗,如何注册公司需要多少钱,单位建设网站申请报告在之前的文章中,我们探讨了 Solana 账户的基础理论并进行了实操。然而,为了进一步加深理解,我们需要结合实际案例来应用这些知识。今天,我们将用两种方法实现账户之间的 SOL 转账。相信通过这个真实场景的学习,你一定能…

在之前的文章中,我们探讨了 Solana 账户的基础理论并进行了实操。然而,为了进一步加深理解,我们需要结合实际案例来应用这些知识。今天,我们将用两种方法实现账户之间的 SOL 转账。相信通过这个真实场景的学习,你一定能够更加透彻地掌握 Solana 的账户模型和转账机制。

在开始之前,请先思考一个问题:我写的程序可以直接从我的钱包里转出 SOL 吗? 带着这个问题,让我们开始今天的学习。

如何转出 SOL

回顾一下 Solana 的账户模型:每个账户都有一个 owner 字段,标明该账户受哪个程序管理。只有账户的 owner 程序可以对账户执行操作,比如减少余额或修改数据。

这意味着,如果我们希望从自己的钱包里转出 SOL,只有系统程序(SystemProgram)能够直接操作我们的钱包账户。我们自己编写的程序无法直接控制钱包余额。

那么问题来了:如果我们想编写一个程序来转账 SOL,该如何实现呢? 有两种方法:一种是创建受程序管理的账户,另一种是使用 CPI(跨程序调用)

创建受程序管理的账户

我们可以创建一个新账户,并将其 owner 设置为我们自己编写的程序。通过这种方式,我们的程序就可以完全控制该账户,执行各种操作,实现转账等功能。

实现过程概述

  1. 创建一个新账户,命名为 programOwnedAccount。

  2. 设置账户的 owner 为程序,将账户的权限交给我们自定义的程序。

  3. 向新账户存入 SOL,将其作为一个“中转账户”。

  4. 实现转账逻辑,从 programOwnedAccount 转出 SOL 到接收者的钱包。

这种方式有效避免了程序直接操作用户钱包的限制,同时保证账户的安全和程序的可控性。

创建受程序管理的账户

理清了这个过程,接下来我们就可以写代码了。

打开 tests/{your-program}.ts 文件,我们将通过调用 Solana 的 SystemProgram.createAccount 方法来实现账户的创建。以下是具体代码:

it('Create and fund account owned by our program', async () => {const instruction = SystemProgram.createAccount({fromPubkey: payer.publicKey, // 我的钱包地址newAccountPubkey: programOwnedAccount.publicKey, // 新账户地址space: 0, // 新账户的存储空间 (0 表示不存储额外数据)lamports: 1 * LAMPORTS_PER_SOL, // 存入新账户的初始余额 (1 SOL)programId: program.programId, // 设置 owner 为自定义程序的 ID});const transaction = new Transaction().add(instruction);// 发送交易并确认结果await sendAndConfirmTransaction(provider.connection, transaction, [payer.payer, programOwnedAccount]);
});

通过这段代码,我们创建了一个受程序管理的账户,并存入了 1 SOL 用作转账。需要注意的是在最后发送交易时,参数 [payer.payer, programOwnedAccount] 指明了签名账户,用户的钱包签名表示授权转账,programOwnedAccount 签名则激活新账户

转账逻辑的实现

完成账户创建后,我们可以实现从 programOwnedAccount 到接收者钱包的转账逻辑。

打开 src/lib.rs 文件,编写以下代码:

注意:以下代码示例默认你已经看过了之前的文章,具备了账户的实操能力。如果你感到不理解下面的代码,请回过头阅读我之前的文章。

  1. 定义账户上下文
#[derive(Accounts)]
pub struct TransferSolWithProgram<'info> {#[account(mut, owner = id())]payer: UncheckedAccount<'info>, // 支付账户#[account(mut)]recipient: SystemAccount<'info>, // 接收账户
}

在账户上下文中,我们可以看到 payer 和 recipient 两个字段的定义。分别使用了 UncheckedAccount 和 SystemAccount 两种类型,分别对应不同的账户类型和用途。

payer 字段

#[account(mut, owner = id())] 的含义如下:

  • mut:表示这个账户的余额会被修改。

  • owner = id():确保 payer 是由当前程序(通过 id() 获取的程序 ID)管理的账户,即一个受程序控制的账户。

  • UncheckedAccount:表明这个账户不需要额外的数据验证。因为 payer 是我们之前创建并初始化的中转账户 (programOwnedAccount),已经明确由程序控制,所以无需额外检查。

需要注意的是,这里没有使用 init,是因为 payer 是一个已存在的账户,并且在创建时已完成了初始化。因此,不需要重复初始化。

recipient 字段

#[account(mut)] 的含义如下:

  • mut:表示该账户的余额会被修改,即接收 SOL。

  • SystemAccount:标明这个账户的所有者是系统程序(SystemProgram),它是普通用户钱包的默认类型。

  1. 编写转账函数
#[program]
pub mod transfer_sol {use super::*;pub fn transfer_sol_with_program(ctx: Context<TransferSolWithProgram>, amount: u64) -> Result<()> {**ctx.accounts.payer.try_borrow_mut_lamports()? -= amount;**ctx.accounts.recipient.try_borrow_mut_lamports()? += amount;Ok(())}
}

代码解析

  • try_borrow_mut_lamports:获取账户余额的可变引用,允许我们直接操作账户的余额。

  • ** 运算符:解引用以访问账户的 lamports 字段,从而操作账户余额。错误通过 ? 运算符向上传递,要求调用者处理错误。

测试代码示例

我们通过以下测试代码验证程序的正确性:

it('Transfer SOL with Program', async () => {// 打印转账前的余额await program.methods.transferSolWithProgram(new anchor.BN(transferAmount)).accounts({payer: programOwnedAccount.publicKey,recipient: payer.publicKey,}).rpc();// 打印转账后的余额
});

使用 CPI(跨程序调用)

Solana 提供了一个强大的机制,称为 CPI(Cross-Program Invocation,跨程序调用)。通过 CPI,我们的程序可以调用其他程序的功能,包括系统程序。利用这一机制,我们可以在自己的程序中调用系统程序,间接操作钱包余额,实现更复杂的功能。

具体实现过程

  1. 编写转账程序,通过 CPI 调用系统程序的 transfer 方法。

  2. 执行转账逻辑,从钱包直接转出 SOL 到接收者的钱包。

编写转账程序

在上面的 src/lib.rs 文件里,我们定义一个函数,调用系统程序的 transfer 方法来实现转账功能。代码如下:

pub fn transfer_sol_with_cpi(ctx: Context<TransferSolWithCpi>, amount: u64) -> Result<()> {system_program::transfer(CpiContext::new(ctx.accounts.system_program.to_account_info(),system_program::Transfer {from: ctx.accounts.payer.to_account_info(),to: ctx.accounts.recipient.to_account_info(),},),amount,)?;Ok(())
}

在以上代码中,我们使用 system_program::transfer 通过 CPI 机制从 payer 账户向 recipient 账户转账。CpiContext::new 用于构造一个新的上下文,它包含了系统程序的账户信息和两个账户的地址(payer 和 recipient)。

另外,在代码中使用系统程序时,需要引入它。你可以通过以下方式来导入 system_program

use anchor_lang::system_program;

为了让程序能够与系统程序交互,我们需要在账户上下文中添加一个字段来引用 system_program。这是因为我们需要告诉 Solana 哪个程序提供了 transfer 方法。以下是账户上下文代码:

#[derive(Accounts)]
pub struct TransferSolWithCpi<'info> {#[account(mut)]payer: Signer<'info>,#[account(mut)]recipient: SystemAccount<'info>,system_program: Program<'info, System>,
}

编写测试代码

为了验证转账功能,我们需要编写相应的测试代码。以下是一个简单的测试示例,展示如何在程序中调用 transfer_sol_with_cpi 方法进行转账:

it('Transfer SOL with CPI', async () => {// 打印转账前的信息: payer余额、recipientawait program.methods.transferSolWithCpi(new anchor.BN(transferAmount)).accounts({payer: payer.publicKey,recipient: recipient.publicKey,}).rpc();// 打印转账后的信息: payer余额、recipient
});

总结

第一种方法:创建受程序管理的账户灵活性高,程序可以完全控制 programOwnedAccount,自由设计逻辑。这个在合约自动化转账领域非常有用。缺点是中转账户需要额外的存储费用。

第二种方法:使用 CPI简洁、高效,不需要额外创建中转账户,直接操作钱包账户,节省存储费用。缺点是程序必须经过审慎设计,避免误操作或安全漏洞。

两种方法对比

特性创建受程序管理的账户使用 CPI
灵活性程序完全控制账户程序受系统程序的限制
存储成本需要支付新账户的存储费用无额外存储费用
开发复杂度需要管理多个账户较为简单,直接调用系统程序
安全性程序外部无法直接操作中转账户钱包账户操作依赖程序逻辑,存在潜在风险

现在回答本文开头的问题:“程序可以直接操作我的钱包转出 SOL 吗?” 答案是:通过 CPI 调用系统程序,可以间接实现操作钱包的功能,更多信息,,https://t.me/+_QibemQqIIg1OTY1。

http://www.dtcms.com/wzjs/85218.html

相关文章:

  • 洛阳建网站百度竞价关键词查询
  • 表情包做旧网站软文营销的成功案例
  • 网站开发都用什么语言山东工艺美术学院网站建设公司
  • 西安跨境电子商务平台网站网站推广方案
  • 做陶瓷公司网站荆门网站seo
  • php做简单网站教程视频教程搜索引擎营销简称为
  • 成都市网站建设免费大数据分析网站
  • 景区网站怎么做的友情链接交换教程
  • 企业网站的分类市场调研报告ppt模板
  • 查询建设用地规划许可证在哪个网站站长统计 网站统计
  • 网站客户端制作多少钱全媒体运营师培训机构
  • 有哪些网站可以做图片打赏凡科网免费建站
  • 绵阳个人网站建设seo网页优化培训
  • 织梦儿童早教教育培训网站模板天津seo排名费用
  • 网站服务器租用价格怎么算百度搜索引擎平台
  • 可以做很多个网站然后哭推广百度seo刷排名软件
  • 如何用家庭电脑做网站中国万网域名注册服务内容
  • 哈市哪里网站做的好关于新品牌的营销策划
  • 电动车网站建设什么是seo文章
  • tcga做多因素分析的网站网站优化有哪些类型
  • 手机3g门户首页上海比较好的seo公司
  • 专业网站建设阿里云怎么让某个关键词排名上去
  • 建设网站的工作步骤网站seo 优化
  • wordpress需要哪些插件seo如何快速出排名
  • soho的外贸网站网站推广100种方法
  • 张北县网站建设seo兼职工资一般多少
  • 微信商店小程序怎么弄巩义网站推广优化
  • 怎么下别人wordpress模板seo哪个软件好
  • javaweb可以做网站吗网页制作公司排名
  • 免费推广的软件站长工具seo综合查询源码