各位,我从索拉纳开始,学习起来很艰难。尽管Rust的错误信息和学习曲线很差,但我正在努力克服它。
我正在尝试开发一种新的代币,它将是一种可替代的资产(0位小数,为同一代币提供大于1的小数(。
在另一笔交易中,我已经创建了一个薄荷账户并对其进行了初始化。现在我正试图将其薄荷到另一个钱包中。基本上,这是mint帐户上下文(为了简单起见,我排除了元数据帐户(:
pub struct MintAsset<'info> {
#[account(mut)]
pub mint: Account<'info, token::Mint>,
#[account(mut)]
pub mint_authority: Signer<'info>,
/// CHECK: We're about to create this with Anchor
#[account(mut)]
pub minter_token: UncheckedAccount<'info>,
#[account(mut)]
pub payer: Signer<'info>,
pub rent: Sysvar<'info, Rent>,
pub system_program: Program<'info, System>,
pub token_program: Program<'info, token::Token>,
pub associated_token_program: Program<'info, associated_token::AssociatedToken>,
}
然后,我继续运行这个交易来铸造我的代币
pub fn mint_asset(ctx: Context<MintAsset>, data: MintArgs) -> Result<()> {
associated_token::create(
CpiContext::new(
ctx.accounts.associated_token_program.to_account_info(),
associated_token::Create {
payer: ctx.accounts.mint_authority.to_account_info(),
associated_token: ctx.accounts.minter_token.to_account_info(),
authority: ctx.accounts.mint_authority.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
token_program: ctx.accounts.token_program.to_account_info(),
rent: ctx.accounts.rent.to_account_info(),
},
),
)?;
token::mint_to(
CpiContext::new(
ctx.accounts.token_program.to_account_info(),
token::MintTo {
mint: ctx.accounts.mint.to_account_info(),
to: ctx.accounts.minter_token.to_account_info(),
authority: ctx.accounts.mint_authority.to_account_info(),
},
),
data.amount,
)?;
Ok(())
}
通过使用以下测试:
async function mintToken(
program: anchor.Program<Pdas>,
wallet: anchor.Wallet,
mintKeypair: anchor.web3.Keypair,
minterWallet: anchor.Wallet,
amount: number
) {
try {
const buyerTokenAddress = await anchor.utils.token.associatedAddress({
mint: mintKeypair.publicKey,
owner: wallet.publicKey,
});
const accounts = {
mint: mintKeypair.publicKey,
mintAuthority: wallet.publicKey,
minterToken: buyerTokenAddress,
payer: wallet.publicKey,
};
const signers = [];
const args = {
amount: new BN(amount),
};
const signature = await program.methods
.mintAsset(args)
.accounts(accounts)
.signers(signers)
.rpc();
} catch (error) {
console.log("MINT ERROR:", inspect({ error }, { depth: null }));
}
}
现在,如果对于buyerTokenAddress
,我使用minterWallet
作为所有者,那么该测试将抛出一个错误。我知道,要拥有代币,必须有一个相关的代币账户,正如文件所述,这是一个
给定钱包地址的账户只是一个由钱包地址本身和代币薄荷组成的程序衍生账户
https://spl.solana.com/associated-token-account
为什么?我的意思是,难道没有人能铸造这种代币吗?我知道只有mintAuthority
可以铸造令牌,但将其作为签名者是有意义的(正如accounts结构所期望的那样(,但是(还有另一个问题(如果我放置一个空的签名者数组,代码仍然会运行(再说一遍,为什么?我想我必须至少为mint_authority
提供一个签名者帐户(。
我应该创建一个新的薄荷帐户并初始化它吗?这不是一个新的代币吗?
在索拉纳代币开发中,我缺少了什么?提前感谢
我可能无法正确回答您的第一个问题,所以我将把这个问题留给更有经验的人。对于您的第二个问题,您对签名者的看法是正确的,因为您使用的是锚点,它隐式地从配置(anchor.toml文件(中获取所有者钱包并对其进行签名。如果您在签名者数组中提供wallet.key,则不会有任何区别。因为锚点通常是这样做的,所以签名者[]中没有提供