Solana:无法使 createAccount 工作,createAccountWithSeed 工作

Solana: Can't make createAccount work, createAccountWithSeed works

我目前正在尝试学习如何为 Solana 编写程序并与之交互。

我正在使用 example-helloworld 代码。为了与helloworld程序进行交互,nodejs代码创建了一个账户,seed:

const transaction = new Transaction().add(
    SystemProgram.createAccountWithSeed({
        fromPubkey: payer.publicKey,
        basePubkey: payer.publicKey,
        seed: GREETING_SEED,
        newAccountPubkey: greetedPubkey,
        lamports,
        space: GREETING_SIZE,
        programId,
    })
)
tx = client.send_transaction(transaction, payer)

我的理解是,它创建了一个数据帐户,由具有 programId 的程序拥有。还不确定为什么要用种子。

我尝试用以下代码替换这段代码:

const transaction = new Transaction().add(
    SystemProgram.createAccount({
        fromPubkey: payer.publicKey,
        newAccountPubkey: greetedPubkey,
        lamports,
        space: GREETING_SIZE,
        programId,
    })
)
tx = client.send_transaction(transaction, payer)

但它不起作用。发送交易后,出现以下错误:

{'code': -32602, 'message': 'invalid transaction: Transaction failed to sanitize accounts offsets correctly'}

谁能解释一下区别以及我做错了什么??

使用 createAccount 创建帐户时,您必须提供该新帐户的签名。因此,在您的情况下,greetedPubkey 必须是 Keypair,就像 payer 一样。你可以这样做:

const greeted = Keypair.generate();
const transaction = new Transaction().add(
    SystemProgram.createAccount({
        fromPubkey: payer.publicKey,
        newAccountPubkey: greeted.publicKey,
        lamports,
        space: GREETING_SIZE,
        programId,
    })
);
tx = client.send_transaction(transaction, payer, greeted);

createAccountWithSeed比较特殊,因为它是从base派生出一个新地址,也就是说你不需要用新地址签名,只需要用base地址。