简体   繁体   English

如何从 solana 的 PDA 中提取 sol/lamports

[英]How to withdraw sol/lamports from PDA in solana

I transfer the SOL/Lamports to the PDA accounts but I am not able to withdraw SOL from PDA back.我将 SOL/Lamports 转移到 PDA 帐户,但无法从 PDA 取回 SOL。

Transfer SOL to PDA将 SOL 传输到 PDA

I generate PDA account from the below given code.我从下面给定的代码生成 PDA 帐户。

 const GREETING_SEED = 'Hello';
  greetedPubkey = await PublicKey.createWithSeed(
    payer.publicKey,
    GREETING_SEED,
    programId,
  );
const transaction = new Transaction().add(
      SystemProgram.createAccountWithSeed({
        fromPubkey: payer.publicKey,
        basePubkey: payer.publicKey,
        seed: GREETING_SEED,
        newAccountPubkey: greetedPubkey,
        lamports,
        space: GREETING_SIZE,
        programId,
      }),
    );
    await sendAndConfirmTransaction(connection, transaction, [payer]);

Transaction of Sol make using below code snippet:使用以下代码片段进行 Sol 交易:

 transaction.add(
    SystemProgram.transfer({
      fromPubkey:toaccount.publicKey,
      toPubkey:  greetedPubkey,
      lamports: LAMPORTS_PER_SOL/100,
      programId: programId,
     
    }),
    
  );
  const signature=await sendAndConfirmTransaction(connection, transaction, [toaccount]);

Above code is working fine.上面的代码工作正常。

Withdraw SOL from PDA从 PDA 中提取 SOL

But I am not able to withdraw SOL from the PDA account.但是我无法从 PDA 帐户中提取 SOL。

transaction.add(
    SystemProgram.transfer({
      fromPubkey: greetedPubKey,
      toPubkey:  toaccount.publicKey,
      lamports: LAMPORTS_PER_SOL/100,
      programId: programId,

    }),

  );
  const signature=await sendAndConfirmTransaction(connection, transaction, [greetedPubKey]);

I try all the way to do it.我尽一切努力去做。 But not able to sign transaction using PDA address.但无法使用 PDA 地址签署交易。 Is there any other way or Point if I make any mistake如果我犯了任何错误,还有其他方法或点吗

An account that is assigned to a program, like greetedPubkey is after doing createAccountWithSeed , can only have its data changed or lamports deducted by the program itself.分配给程序的帐户,如greetedPubkey是在执行createAccountWithSeed之后,只能由程序本身更改其数据或扣除 lamports。 Here's an excerpt from the docs:这是文档的摘录:

A created account is initialized to be owned by a built-in program called the System program and is called a system account aptly.创建的帐户被初始化为一个称为系统程序的内置程序所拥有,因此被恰当地称为系统帐户。 An account includes "owner" metadata.帐户包括“所有者”元数据。 The owner is a program id.所有者是程序 ID。 The runtime grants the program write access to the account if its id matches the owner.如果帐户的 ID 与所有者匹配,则运行时会授予程序对该帐户的写入权限。 For the case of the System program, the runtime allows clients to transfer lamports and importantly assign account ownership, meaning changing the owner to a different program id.对于系统程序,运行时允许客户端传输 lamports 并且重要的是分配帐户所有权,这意味着将所有者更改为不同的程序 ID。 If an account is not owned by a program, the program is only permitted to read its data and credit the account.如果帐户不属于某个程序,则只允许该程序读取其数据并记入该帐户。

https://docs.solana.com/developing/programming-model/accounts#ownership-and-assignment-to-programs https://docs.solana.com/developing/programming-model/accounts#ownership-and-assignment-to-programs

In order to transfer the lamports back then, you must have your program process an instruction to move the lamports from greetedPubkey back to your account, for example, by doing:为了将 lamports 转移回来,您必须让您的程序处理一条指令,将 lamports 从greetedPubkey回您的帐户,例如,通过执行以下操作:

**from_account.try_borrow_mut_lamports()? -= amount_of_lamports;
**to_account.try_borrow_mut_lamports()? += amount_of_lamports;

You can find the full example at https://solanacookbook.com/references/programs.html#how-to-transfer-sol-in-a-program您可以在https://solanacookbook.com/references/programs.html#how-to-transfer-sol-in-a-program中找到完整示例

This isn't part of your question, but as an addendum, an account created with createAccountWithSeed is not a PDA, so your program will not be able to sign for it.这不是您问题的一部分,但作为附录,使用createAccountWithSeed创建的帐户不是PDA,因此您的程序将无法为其签名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM