4

I want to use zero copy in an anchor program, but I don't have a clear path on how can I do that. Is there any guide or example program that does this?

2 Answers 2

11

This is how you use the account(zero). It will allow you to create data accounts of a size up to 10 MB.

In your context you wrap the account in an AccountLoader and add the #[account(zero)] decorator.

#[account(zero)]
pub my_account: AccountLoader<'info, MyAccount>

In your account struct you need to add the #[account(zero_copy)] decorator as well.

#[account(zero_copy)]
pub struct MyAccount {...}

to load your account if you have just initialized it

let my_account = &mut ctx.accounts.my_account.load_init()?;

or if you want to borrow as mut

let mut my_account = ctx.accounts.my_account.load_mut()?;

In your javascript test you first generate a keypair for the zero account. Then you can call the program instruction that takes the zero account together with an additional instruction that will create the account for you. The createInstruction will first be executed followed by the someInstruction that will change the owner of the myAccount to the program account.

const myAccount = anchor.web3.Keypair.generate();

const tx = await program.rpc.someInstruction(
      ...,
      {
        accounts: {
          ...
        },
        instructions: [
          await program.account.myAccount.createInstruction(myAccount),
        ],
        signers: [myAccount],
      }
    );

At the time where we zero an account the ownership is transferred from user to program. You can only change an account's owning program once, from the system program to some other program. So when the program is owned by your program you can't change the owner again.

2
  • 1
    You can also add #[account(mut)] instead of #[account(zero)] above the AccountLoader if you want use init, space, payer. Only the #[account(zero_copy)] would be enough. Commented Oct 19, 2022 at 5:00
  • 1
    How to use dynamic size of account. e.g. MyAccount { users: Vec<Pubkey> }. zero_copy doesn't seem to allow dynamic size of vector. We can adjust the size of account in prior creating account instruction. but I wasn't able to use it as load_init() occurred error panicked at 'range end index 320040 out of range for slice of length 3264', src/accounts/account_loader.rs:212:43 in case of smaller size of account than initial struct size. I set MyAccount {users: [Pubkey; 10000]}
    – Julbh
    Commented Mar 7 at 10:15
0

pda accounts have a restricted size of 10 kb

zero is a attribute you use when you create an account outside a cpi and want to initialize it, anchor skips discriminator checking on accounts with zero attribute anchor ref : Use this constraint if you want to create an account in a previous instruction and then initialize it in your instruction instead of using init. This is necessary for accounts that are larger than 10 Kibibyte because those accounts cannot be created via a CPI (which is what init would do).

Anchor adds internal data to the account when using zero just like it does with init which is why zero implies mut.

2
  • So how do we create an account in previous instruction do you have any code
    – Pratik.js
    Commented Aug 1, 2022 at 12:10
  • What are you quoting? Please add a link to your answer.
    – mikemaccana
    Commented Aug 1, 2022 at 12:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.