Solana Anchor: CPI с КПК

Я пытаюсь создать Mint с моей программой в качестве авторитета, и я изо всех сил пытаюсь правильно настроить вызовы CPI.

Вот игрушечный пример того, что у меня есть до сих пор:

use anchor_lang::prelude::*;
use anchor_spl::token::{
    self, set_authority, spl_token::instruction::AuthorityType, SetAuthority, Token,
};
use program::MintTest;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

#[program]
pub mod mint_test {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        let bump = *ctx.bumps.get("mint").unwrap();
        let seeds = vec![bump];
        let seeds = vec![b"some-seed".as_ref(), seeds.as_slice()];
        let seeds = vec![seeds.as_slice()];
        let seeds = seeds.as_slice(); // ❓ slightly unrelated but I'd love to understand why all this nesting is required 🤔

        let cpi_program = ctx.accounts.token_program.to_account_info();
        let cpi_accounts = SetAuthority {
            account_or_mint: ctx.accounts.mint.to_account_info(),
            current_authority: ctx.accounts.program.to_account_info(),
        };
        let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, seeds);
        set_authority(cpi_ctx, AuthorityType::MintTokens, None)?; // ❌ This fails 🙁

        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(
        init,
        payer = signer,
        mint::decimals = 0,
        mint::authority = program,
        seeds = [b"some-seed".as_ref()],
        bump,
    )]
    pub mint: Account<'info, token::Mint>,

    #[account(mut)]
    pub signer: Signer<'info>,
    pub token_program: Program<'info, Token>,
    pub system_program: Program<'info, System>,
    pub rent: Sysvar<'info, Rent>,
    pub program: Program<'info, MintTest>,
}

Монетный двор создается правильно, но вызов any CPI завершается с ошибкой Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: Cross-program invocation with unauthorized signer or writable account (set_authority — это просто пример, я пробовал другие CPI, такие как mint_to, без особого успеха 😔).

Это работает, если я устанавливаю подписавшего TX в качестве авторитета, поэтому я предполагаю, что делаю что-то не так с моими семенами подписавшего, но я просто не могу понять это, и я застрял на этом уже несколько часов.

Вот мой тест TS:

import * as anchor from "@project-serum/anchor";
import { Program } from "@project-serum/anchor";
import { MintTest } from "../target/types/mint_test";

describe("mint-test", () => {
  anchor.setProvider(anchor.AnchorProvider.env());

  const program = anchor.workspace.MintTest as Program<MintTest>;

  it("Is initialized!", async () => {
    const [mint] = await anchor.web3.PublicKey.findProgramAddress(
      [Buffer.from("some-seed")],
      program.programId
    );

    const tx = await program.methods
      .initialize()
      .accounts({
        mint,
        program: program.programId,
      })
      .rpc();

    console.info("Your transaction signature", tx);
  });
});

Заранее спасибо за помощь 😇

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
272
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Так что, похоже, мое понимание всего этого было немного неправильным. Программа просто не может подписывать, поэтому наша программа не может быть авторитетом нашего монетного двора.

Однако мы можем назначить КПК владельцем нашего монетного двора и использовать семена, используемые для нахождения адреса этого КПК, для «подписания» инструкций.

Следующие работы:

use anchor_lang::prelude::*;
use anchor_spl::token::{
    self, set_authority, spl_token::instruction::AuthorityType, SetAuthority, Token,
};

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

#[program]
pub mod mint_test {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        let bump = *ctx.bumps.get("auth").unwrap();
        let seeds = vec![bump];
        let seeds = vec![b"auth".as_ref(), seeds.as_slice()];
        let seeds = vec![seeds.as_slice()];
        let seeds = seeds.as_slice();

        let cpi_program = ctx.accounts.token_program.to_account_info();
        let cpi_accounts = SetAuthority {
            account_or_mint: ctx.accounts.mint.to_account_info(),
            current_authority: ctx.accounts.auth.to_account_info(),
        };
        let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, seeds);
        set_authority(cpi_ctx, AuthorityType::MintTokens, None)?;

        Ok(())
    }
}

#[account]
pub struct Auth {}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(
        init,
        space = 8,
        payer = signer,
        seeds = [b"auth".as_ref()],
        bump,
    )]
    pub auth: Account<'info, Auth>,

    #[account(
        init,
        payer = signer,
        mint::decimals = 0,
        mint::authority = auth,
        seeds = [b"some-seed".as_ref()],
        bump,
    )]
    pub mint: Account<'info, token::Mint>,

    #[account(mut)]
    pub signer: Signer<'info>,
    pub token_program: Program<'info, Token>,
    pub system_program: Program<'info, System>,
    pub rent: Sysvar<'info, Rent>,
}

И тест:

import * as anchor from "@project-serum/anchor";
import { Program } from "@project-serum/anchor";
import { MintTest } from "../target/types/mint_test";

describe("mint-test", () => {
  anchor.setProvider(anchor.AnchorProvider.env());

  const program = anchor.workspace.MintTest as Program<MintTest>;

  it("Is initialized!", async () => {
    const [auth] = await anchor.web3.PublicKey.findProgramAddress(
      [Buffer.from("auth")],
      program.programId
    );

    const [mint] = await anchor.web3.PublicKey.findProgramAddress(
      [Buffer.from("some-seed")],
      program.programId
    );

    const tx = await program.methods
      .initialize()
      .accounts({
        mint,
        auth,
      })
      .rpc();

    console.info("Your transaction signature", tx);
  });
});

Надеюсь, это кому-то поможет.

Как указано в этом ответе https://stackoverflow.com/a/73950605/20494156 , программа не может подписать сама по себе, единственный способ - использовать КПК. Более подробную информацию о программах в качестве подписантов можно найти здесь: https://book.anchor-lang.com/anchor_in_depth/PDA.html#programs-as-signers

Просто хотел добавить следующее относительно вопроса внутренних комментариев о вложении семян, этот ответ может быть полезен: https://solana.stackexchange.com/questions/3002/can-there-be-two-signers-in- якорь-CPI.

В основном идея состоит в том, что вы можете отправить несколько массивов начальных значений в случае, если имеется несколько подписей КПК.

Другие вопросы по теме