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

响应式网站 推广效果wordpress伪静态说明

响应式网站 推广效果,wordpress伪静态说明,移动互联网应用程序个人信息保护管理暂行规定,手机网站制作要求标准前言: 前面我们介绍了 solana 关于 anchor 智能合约的环境搭建 配置,简单编写 发布 部署 调用 的一些落地。等等。接下来我们借着案例。详细剖析下智能合约编写。 案例 vesting 介绍: 这是一个关于 释放 spl token 的案例。老板将 token 作为…

前言:

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

 案例 vesting 介绍:

这是一个关于 释放 spl  token 的案例。老板将 token 作为激励 发放给员工。包含 锁定期, 受益人 开始兑换时间,结束兑换时间, 解锁账户 等等,

主要功能步骤

  1. 雇主先创建一个  以公司名称作为派生种子的账户,用于存放 待释放 SPL Token,
  2. 雇主再为 每个员工创建一个 pad 账户,记录员工待解锁 账户的信息,(token总量,锁定期限,开始兑换期限,员工接收token地址 等等, )
  3. 员工领取 token

智能合约的分析: 

智能合约 编写包含很多固定写法。这里就不赘述了。可以先看前面的章节内容。我们这里主要介绍下 学到的新姿势:

 

  • 雇主创建 账户
    /**
    创建 老板解锁 账户:主要就是 给 vesting_account 赋值
    **/
    pub fn create_vesting_account(ctx: Context<CreateVestingAccount>,company_name:String
    ) -> Result<()> {*ctx.accounts.vesting_account = VestingAccount {owner: ctx.accounts.signer.key(),mint: ctx.accounts.mint.key(),treasury_token_account: ctx.accounts.treasury_token_account.key(),company_name,treasury_bump: ctx.bumps.treasury_token_account,bump: ctx.bumps.treasury_token_account,};Ok(())
    }#[derive(Accounts)]
    #[instruction(company_name:String)]
    pub struct CreateVestingAccount<'info>{#[account(mut)]pub signer: Signer<'info>,#[account(init,space = 8 + VestingAccount::INIT_SPACE,payer = signer,seeds = [company_name.as_ref()],bump,)]pub vesting_account: Account<'info, VestingAccount>,pub mint:InterfaceAccount<'info, Mint>,/**1. 需要创建2. 指定 spl  mint3. 授权账户就是自己4. 支付的费用5. 生成 pda 账户种子6. pda bump**/#[account(init,token::mint = mint,token::authority = treasury_token_account,payer = signer,seeds = [b"vesting_treasury".as_ref(),company_name.as_ref()],bump,)]pub treasury_token_account:InterfaceAccount<'info,TokenAccount>,pub system_program: Program<'info, System>,pub token_program: Interface<'info, TokenInterface>,
    }/**
    解锁账户 雇主操作的账户 用于公司员工管理,存储需要解锁的 spl token1.owner 归属人 觉得谁可以更新2.spl 发放 spl mint3.用于保存 spl 账户信息,雇主 用于分配 所有要发放的 SPL4.公司名称 标识,  用于派生 PDA5.保存 分配 SPL 账户的 bump,6.保存 归属账号的 bump宏 :#[account]  用于构造数据 指定改结构体为一个 solana 账户#[derive(InitSpace)] 是对数据结构的实现, 指定我们想要使用 InitSpace,会让 anchor 自动计算 结构体大小#[max_len(50)]  字符串类型没有固定大小,这里指定为 固定大小 才能使用 InitSpace 推导出结构体大小
    **/
    #[account]
    #[derive(InitSpace)]
    pub struct VestingAccount {pub owner: Pubkey,pub mint: Pubkey,pub treasury_token_account: Pubkey,#[max_len(50)]pub company_name:String,pub treasury_bump:u8,pub bump:u8,
    }
  • 雇主为每个员工 创建账号

    /**
    创建雇员 待解锁的账号:
    结构体包含 解锁 token 的  所有信息
    **/
    pub fn create_employee_account(ctx: Context<CreateEmployeeAccount>,start_time:i64,end_time:i64,total_amount:u64,cliff_time:i64,
    ) -> Result<()> {*ctx.accounts.employee_account = EmployeeAccount {beneficiary: ctx.accounts.beneficiary.key(),start_time,end_time,total_amount,total_withdrawn:0,cliff_time,vesting_account: ctx.accounts.vesting_account.key(),bump:ctx.bumps.employee_account,};Ok(())
    }/**1.支付费用的账户2.受益人账户,领取 token 的 账户地址3.操作该账户的权限4.员工账户5.指定系统程序
    **/
    #[derive(Accounts)]
    pub struct CreateEmployeeAccount<'info>{#[account(mut)]pub owner:Signer<'info>,pub beneficiary:SystemAccount<'info>,//has_one 解锁 账户的所有者 是刺指令的签名者 owner#[account(has_one = owner,)]pub vesting_account:Account<'info, VestingAccount>,//创建员工账户#[account(init,space = 8 + EmployeeAccount::INIT_SPACE,payer = owner,seeds = [b"employee_vesting", beneficiary.key().as_ref(), vesting_account.key().as_ref()],bump,)]pub employee_account: Account<'info, EmployeeAccount>,pub system_program: Program<'info, System>,
    }/**1.受益人  接收token 的雇员 钱包 (ATA账号)2.开始兑换时间  unix 时间3.截止的兑换时间4.锁定期 员工需要等待多久才能解锁(类似期权,几年不能交易)5.解锁账户 雇主创建的放 spl token 的账户6.分配给该员工的 总 spl 数量7.记录该员工 解锁的数量,用于后期计算
    **/
    #[account]
    #[derive(InitSpace)]
    pub struct EmployeeAccount {pub beneficiary: Pubkey,pub start_time:i64,pub end_time:i64,pub cliff_time:i64,pub vesting_account: Pubkey,pub total_amount:u64,pub total_withdrawn:u64,pub bump:u8,
    }
  • 员工释放 token

    /**
    员工认领 Token,保证员工在正确的时间里 领取 token**/
    pub fn claim_tokens(ctx:Context<ClaimTokens>,company_name:String,) -> Result<()>{//获取员工账户(有老板已经创建好的)let employee_account =&mut ctx.accounts.employee_account;//获取系统时间let now = Clock::get()?.unix_timestamp;//当前时间小于 锁定期则 不能释放if now < employee_account.cliff_time {return  Err(ErrorCode::ClaimNotAvailableYet.into())}//已经开放的时间, saturating_sub 防止数组越界let time_since_start = now.saturating_sub(employee_account.start_time);//总释放时间let total_vesting_time = employee_account.end_time.saturating_sub(employee_account.start_time);if total_vesting_time == 0 {return  Err(ErrorCode::InvalidVestingPeriod.into())}//解锁数量//如果当前时间 大于 释放结束时间。那可以全部都 解锁掉let vested_amount = if now >= employee_account.end_time {employee_account.total_amount}else {//checked_mul 防止 乘法的溢出//数量*总的开放时间 / 当前已经开放的时间 = 当前开放时间可以获取的数量match employee_account.total_amount.checked_mul(time_since_start as u64) {Some(product) => product / (total_vesting_time as u64),None =>{return  Err(ErrorCode::CalculationOverflow.into())}}};//可申领金额let claimable_amount = vested_amount.saturating_sub(employee_account.total_withdrawn);if claimable_amount == 0 {return  Err(ErrorCode::NothingToClaim.into())}//从老板设立的账号中 转账 到员工let transfer_cpi_accounts = TransferChecked {from: ctx.accounts.treasury_token_account.to_account_info(),mint: ctx.accounts.mint.to_account_info(),//to: ctx.accounts.employee_account.to_account_info(),to: employee_account.to_account_info(),//已经将权限设置为自己了。所有这里是可以调用的authority: ctx.accounts.treasury_token_account.to_account_info(),};let cip_program = ctx.accounts.token_program.to_account_info();let signer_seeds:&[&[&[u8]]] = &[&[b"vesting_treasury",ctx.accounts.vesting_account.company_name.as_ref(),&[ctx.accounts.vesting_account.treasury_bump],]];let cpi_context = CpiContext::new(cip_program, transfer_cpi_accounts).with_signer(signer_seeds);let decimals = ctx.accounts.mint.decimals;token_interface::transfer_checked(cpi_context, claimable_amount, decimals)?;employee_account.total_withdrawn += claimable_amount;Ok(())
    }}

依赖 Cargo.toml:

[package]
name = "tokenvesting"
version = "0.1.0"
description = "Created with Anchor"
edition = "2021"[lib]
crate-type = ["cdylib", "lib"]
name = "tokenvesting"[features]
default = []
cpi = ["no-entrypoint"]
no-entrypoint = []
no-idl = []
no-log-ix-name = []
idl-build = ["anchor-lang/idl-build","anchor-spl/idl-build"][dependencies]
#cargo add anchor-lang --features init-if-needed
anchor-lang = { version = "0.31.1", features = ["init-if-needed"] }
anchor-spl = "0.31.1"
solana-program = "2.3.0"

完整脚本: 

#![allow(clippy::result_large_err)]use anchor_lang::prelude::*;
use anchor_spl::associated_token::AssociatedToken;
use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface, TransferChecked};declare_id!("JAVuBXeBZqXNtS73azhBDAoYaaAFfo4gWXoZe2e7Jf8H");/**
(智能合约 和 http 请求类似都是 无状态的)
智能合约主要功能:1.雇主先创建一个  以公司名称作为派生种子的账户,用于存放 待释放 SPL Token,2.雇主再为 每个员工创建一个 pad 庄户,记录员工带解锁庄户的信息,(token总量,锁定期限,开始兑换期限,员工接收token地址 等等, )3.员工领取 token**/
#[program]
pub mod vesting {use super::*;use anchor_spl::token_interface;/**创建 老板解锁 账户:主要就是 给 vesting_account 赋值**/pub fn create_vesting_account(ctx: Context<CreateVestingAccount>,company_name: String,) -> Result<()> {*ctx.accounts.vesting_account = VestingAccount {owner: ctx.accounts.signer.key(),mint: ctx.accounts.mint.key(),treasury_token_account: ctx.accounts.treasury_token_account.key(),company_name,treasury_bump: ctx.bumps.treasury_token_account,bump: ctx.bumps.treasury_token_account,};Ok(())}/**创建雇员 待解锁的账号:结构体包含 解锁 token 的  所有信息**/pub fn create_employee_account(ctx: Context<CreateEmployeeAccount>,start_time: i64,end_time: i64,total_amount: u64,cliff_time: i64,) -> Result<()> {*ctx.accounts.employee_account = EmployeeAccount {beneficiary: ctx.accounts.beneficiary.key(),start_time,end_time,total_amount,total_withdrawn: 0,cliff_time,vesting_account: ctx.accounts.vesting_account.key(),bump: ctx.bumps.employee_account,};Ok(())}/**员工认领 Token,保证员工在正确的时间里 领取 token**/pub fn claim_tokens(ctx: Context<ClaimTokens>, company_name: String) -> Result<()> {//获取员工账户(有老板已经创建好的)let employee_account = &mut ctx.accounts.employee_account;//获取系统时间let now = Clock::get()?.unix_timestamp;//当前时间小于 锁定期则 不能释放if now < employee_account.cliff_time {return Err(ErrorCode::ClaimNotAvailableYet.into());}//已经开放的时间, saturating_sub 防止数组越界let time_since_start = now.saturating_sub(employee_account.start_time);//总释放时间let total_vesting_time = employee_account.end_time.saturating_sub(employee_account.start_time);if total_vesting_time == 0 {return Err(ErrorCode::InvalidVestingPeriod.into());}//解锁数量//如果当前时间 大于 释放结束时间。那可以全部都 解锁掉let vested_amount = if now >= employee_account.end_time {employee_account.total_amount} else {//checked_mul 防止 乘法的溢出//数量*总的开放时间 / 当前已经开放的时间 = 当前开放时间可以获取的数量match employee_account.total_amount.checked_mul(time_since_start as u64){Some(product) => product / (total_vesting_time as u64),None => return Err(ErrorCode::CalculationOverflow.into()),}};//可申领金额let claimable_amount = vested_amount.saturating_sub(employee_account.total_withdrawn);if claimable_amount == 0 {return Err(ErrorCode::NothingToClaim.into());}//从老板设立的账号中 转账 到员工let transfer_cpi_accounts = TransferChecked {from: ctx.accounts.treasury_token_account.to_account_info(),mint: ctx.accounts.mint.to_account_info(),//to: ctx.accounts.employee_account.to_account_info(),to: employee_account.to_account_info(),//已经将权限设置为自己了。所有这里是可以调用的authority: ctx.accounts.treasury_token_account.to_account_info(),};let cip_program = ctx.accounts.token_program.to_account_info();let signer_seeds: &[&[&[u8]]] = &[&[b"vesting_treasury",ctx.accounts.vesting_account.company_name.as_ref(),&[ctx.accounts.vesting_account.treasury_bump],]];let cpi_context =CpiContext::new(cip_program, transfer_cpi_accounts).with_signer(signer_seeds);let decimals = ctx.accounts.mint.decimals;token_interface::transfer_checked(cpi_context, claimable_amount, decimals)?;employee_account.total_withdrawn += claimable_amount;Ok(())}
}/**
创建雇主账号1.signer  mut 签名者,支付手续费,应为需要支付手续费 所以需要是 mut2.指定 解锁账号 派生信息3.spl mint 地址4.存储 激励 spl 的 ATA 地址,(即将分配给 员工的 Token)5.指定使用到的系统程序 System6.指定使用到的系统程序 TokenInterface宏:#[instruction(company_name:String)] 是对数据结构的实现 (创建), 指定入参 company_name**/#[derive(Accounts)]
#[instruction(company_name:String)]
pub struct CreateVestingAccount<'info> {#[account(mut)]pub signer: Signer<'info>,#[account(init,space = 8 + VestingAccount::INIT_SPACE,payer = signer,seeds = [company_name.as_ref()],bump,)]pub vesting_account: Account<'info, VestingAccount>,pub mint: InterfaceAccount<'info, Mint>,/**1. 需要创建2. 指定 spl  mint3. 授权账户就是自己4. 支付的费用5. 生成 pda 账户种子6. pda bump**/#[account(init,token::mint = mint,token::authority = treasury_token_account,payer = signer,seeds = [b"vesting_treasury".as_ref(),company_name.as_ref()],bump,)]pub treasury_token_account: InterfaceAccount<'info, TokenAccount>,pub system_program: Program<'info, System>,pub token_program: Interface<'info, TokenInterface>,
}/**
解锁账户 雇主操作的账户 用于公司员工管理,存储需要解锁的 spl token1.owner 归属人 觉得谁可以更新2.spl 发放 spl mint3.用于保存 spl 账户信息,雇主 用于分配 所有要发放的 SPL4.公司名称 标识,  用于派生 PDA5.保存 分配 SPL 账户的 bump,6.保存 归属账号的 bump宏 :#[account]  用于构造数据 指定改结构体为一个 solana 账户#[derive(InitSpace)] 是对数据结构的实现, 指定我们想要使用 InitSpace,会让 anchor 自动计算 结构体大小#[max_len(50)]  字符串类型没有固定大小,这里指定为 固定大小 才能使用 InitSpace 推导出结构体大小
**/
#[account]
#[derive(InitSpace)]
pub struct VestingAccount {pub owner: Pubkey,pub mint: Pubkey,pub treasury_token_account: Pubkey,#[max_len(50)]pub company_name: String,pub treasury_bump: u8,pub bump: u8,
}/**1.支付费用的账户2.受益人账户,领取 token 的 账户地址3.操作该账户的权限4.员工账户5.指定系统程序
**/
#[derive(Accounts)]
pub struct CreateEmployeeAccount<'info> {#[account(mut)]pub owner: Signer<'info>,pub beneficiary: SystemAccount<'info>,//has_one 解锁 账户的所有者 是刺指令的签名者 owner#[account(has_one = owner,)]pub vesting_account: Account<'info, VestingAccount>,//创建员工账户#[account(init,space = 8 + EmployeeAccount::INIT_SPACE,payer = owner,seeds = [b"employee_vesting", beneficiary.key().as_ref(), vesting_account.key().as_ref()],bump,)]pub employee_account: Account<'info, EmployeeAccount>,pub system_program: Program<'info, System>,
}/**1.受益人  接收token 的雇员 钱包 (ATA账号)2.开始兑换时间  unix 时间3.截止的兑换时间4.锁定期 员工需要等待多久才能解锁(类似期权,几年不能交易)5.解锁账户 雇主创建的放 spl token 的账户6.分配给该员工的 总 spl 数量7.记录该员工 解锁的数量,用于后期计算
**/
#[account]
#[derive(InitSpace)]
pub struct EmployeeAccount {pub beneficiary: Pubkey,pub start_time: i64,pub end_time: i64,pub cliff_time: i64,pub vesting_account: Pubkey,pub total_amount: u64,pub total_withdrawn: u64,pub bump: u8,
}/**
员工认领 token1.交易的签名2.查找 待认领的 员工账户信息,雇主创建好的, mut 可编辑, has_one 约束验证,结构体中 EmployeeAccount 的两个字段与 当前约束值 是否一直3.查找 存放 解锁的 spl token 账户, mut 可编 has_one = treasury_token_account,has_one = mint 共同约束 vesting_account pda 账户4.spl mint 信息, 确定  vesting_account5.待 解锁的 老板庄户6.员工 待接收的 token account 账户
**/
#[derive(Accounts)]
#[instruction(company_name:String)]
pub struct ClaimTokens<'info> {#[account(mut)]pub beneficiary: Signer<'info>,#[account(mut,seeds = [b"employee_vesting",beneficiary.key().as_ref(),vesting_account.key().as_ref()],bump = employee_account.bump,has_one = beneficiary,has_one = vesting_account,)]pub employee_account: Account<'info, EmployeeAccount>,//宏  根据 传入的公司名称处理,是否存在 对应的pad#[account(mut,seeds = [company_name.as_ref()],bump = vesting_account.bump,has_one = treasury_token_account,has_one = mint,)]pub vesting_account: Account<'info, VestingAccount>,pub mint: InterfaceAccount<'info, Mint>,#[account(mut)]pub treasury_token_account: InterfaceAccount<'info, TokenAccount>,#[account(init_if_needed,payer = beneficiary,associated_token::mint = mint,associated_token::authority = beneficiary,associated_token::token_program = token_program,)]pub employee_token_account: InterfaceAccount<'info, TokenAccount>,pub token_program: Interface<'info, TokenInterface>,pub associated_token_program: Program<'info, AssociatedToken>,pub system_program: Program<'info, System>,
}#[error_code]
pub enum ErrorCode {#[msg("Claim not available yet")]ClaimNotAvailableYet,#[msg("Invalid Vesting Period")]InvalidVestingPeriod,#[msg("Calculation Overflow")]CalculationOverflow,#[msg("Nothing To Claim")]NothingToClaim,
}


文章转载自:

http://ew0xMmVe.cLgbb.cn
http://15WkQ1aF.cLgbb.cn
http://dphQtroE.cLgbb.cn
http://4g4xdqCn.cLgbb.cn
http://aTpeSaNJ.cLgbb.cn
http://nmVJDzVw.cLgbb.cn
http://98C9UUSe.cLgbb.cn
http://7AIvtqdl.cLgbb.cn
http://lrcY5xDS.cLgbb.cn
http://ngBSu4oT.cLgbb.cn
http://4Ik3I2cK.cLgbb.cn
http://qzv9Ninq.cLgbb.cn
http://2vXJjS3u.cLgbb.cn
http://INvmI91W.cLgbb.cn
http://8BAExIOX.cLgbb.cn
http://olWjzOR3.cLgbb.cn
http://cA7avZf9.cLgbb.cn
http://oiVWlzft.cLgbb.cn
http://Oy4LtxfP.cLgbb.cn
http://20B4hZfn.cLgbb.cn
http://dl1Qk7E1.cLgbb.cn
http://Su3nfAgz.cLgbb.cn
http://2I87Thz4.cLgbb.cn
http://CIVez15c.cLgbb.cn
http://E3VGFNPv.cLgbb.cn
http://2Qe8fghB.cLgbb.cn
http://ZoXP6RUy.cLgbb.cn
http://W6b9Dwqi.cLgbb.cn
http://Vl6fraEk.cLgbb.cn
http://N24mEnLm.cLgbb.cn
http://www.dtcms.com/wzjs/634614.html

相关文章:

  • 广州上市网站建设的公司想做个人域名网站怎么做
  • 建商城网站网站建设的素材
  • 网站建设和源代码问题企业网站建设组织人员可行性分析
  • 飞鱼网站建设浙江职业能力建设网站
  • 企业网站备案号密码忘记我市精神文明建设的门户网站
  • 企业网站的制作周期外贸信息发布平台
  • 网站如何不被百度搜到wordpress发外链
  • 网站色差表广州互联网广告推广
  • githup网站建设建筑工程技术培训
  • 单网页网站如何做昆明建设路租房信息昆明租房网站
  • 建立网站就是制作网页吗网站开发有哪几类
  • 如何在手机上开自己的网站网站建设 客户定位
  • 网站建设与网页设计专业的江阴做公司网站有哪些
  • 站酷网如何接单构建平台还是搭建平台
  • 做餐饮如何加入外卖网站格力网站建设需求分析
  • 智能网站建设哪家好做暧暧网站在线观看
  • 做网站要学什么c语言asp.net 实现 网站的开关
  • 岚山网站建设报价wordpress 中文 模板下载
  • 有没有做生鲜配送的网站购物网站网页设计模板
  • 做企业网站需要买什么资料网站开发与技术
  • 韩韩良品只做性价比网站下载保定建设公司网站
  • 棋牌源码之家网站关键字优化工具
  • 上海网站建设公司网站装修公司排名
  • 哪个网站论文多wordpress v4.9.5
  • 青岛市建设监督管理局网站企业建设网站 入账
  • 兰溪做网站太原小程序制作电话
  • 网站怎么制作客户关系管理的重要性
  • 漯河专业做网站的公司长沙网站开发微联讯点官网
  • 怎么建设推广网站公司注册地址可以变更吗
  • 青岛网站优化公司哪家好网站建设环境搭建心得体会