ATA所有权变更为Token Program导致PDA无法转账的问题求助
问题:ATA账户所有者变为Token Program,导致PDA无法转出代币
我花了几小时排查,发现我的ATA地址所有者突然变成了Token Program,而非预期的账户地址。原本计划使用vaultInfoPDA从它的ATA账户中转出代币,完成Vault移除操作,但由于PDA不再是该ATA的所有者,操作无法执行。以下是我用Anchor进行测试的控制台日志及脚本,寻求解决方案。
Mint测试结果与脚本
测试结果
Mint: A2ojTC6aQZYP6bwUq1FmWN9kwaQTB7NKQmMs89j4FUkx Sender ATA: 2KcR41e2NxnYY5DWDzvgzHiKpSoaZJ55kvBiqU111DaY Sender ATA owner: 7QzoE1okkpgsn7Rx5pxyGDkXMSc3nsqhWitDHc6c8rKb program ATA: H9SEYZsU5ao1WoUNoVTQjVMBbJLNjJmKA5N1cGfjxLqE Supply: 100 PDA: 10 User: 90 ✔ Mint token! (7001ms)
测试脚本
it("Mint token!", async () => { mintPubkey = await createMint( program.provider.connection, // conneciton user, // fee payer user.publicKey, // mint authority user.publicKey, // freeze authority (you can use `null` to disable it. when you disable it, you can't turn it on again) 9 // decimals ); console.log("Mint:", mintPubkey.toBase58()) let tokenAccountPubkeyUser = await getOrCreateAssociatedTokenAccount(program.provider.connection, user, mintPubkey, user.publicKey) console.log("Sender ATA:", tokenAccountPubkeyUser.address.toBase58()) let tokenAuth = await program.provider.connection.getAccountInfo(tokenAccountPubkeyUser.address); console.log("Sender ATA owner:", tokenAccountPubkeyUser.owner.toBase58()) let tokenAccountPubkeyPda = await getOrCreateAssociatedTokenAccount(program.provider.connection, user, mintPubkey, program.programId) console.log("program ATA:", tokenAccountPubkeyPda.address.toBase58()) let txhash = await mintToChecked( program.provider.connection, // connection user, // fee payer mintPubkey, // mint tokenAccountPubkeyUser.address, // receiver (sholud be a token account) user, // mint authority 100e9, // amount. if your decimals is 9, you mint 10^9 for 1 token. 9 // decimals ); let tokenSupply = await program.provider.connection.getTokenSupply(mintPubkey); console.log("Supply:", tokenSupply.value.uiAmount) txhash = await transferChecked( program.provider.connection, // connection user, // payer tokenAccountPubkeyUser.address, // from (should be a token account) mintPubkey, // mint tokenAccountPubkeyPda.address, // to (should be a token account) user, // from's owner 10e9, // amount, if your deciamls is 9, send 10^9 for 1 token 9 // decimals ); let tokenAmount = await program.provider.connection.getTokenAccountBalance(tokenAccountPubkeyPda.address); console.log("PDA:", tokenAmount.value.uiAmount) let tokenAmountUser = await program.provider.connection.getTokenAccountBalance(tokenAccountPubkeyUser.address); console.log("User:", tokenAmountUser.value.uiAmount) })
移除Vault测试结果与脚本
测试结果
Mint: A2ojTC6aQZYP6bwUq1FmWN9kwaQTB7NKQmMs89j4FUkx userProfilePDA CanbMWdj5UT8KWCAUwsmMyZFeyG8kWQER2tZQdxTohEK Last vault: 3 vaultAccountPDA: 8tvqq4zWMGZuoe4tsjuC85WRQY8n5qxZeoyY2Ro7UwGi vaultInfoPDA: A5E257kztkqdwxeqrjgFzjG2uPmECNX7LD96Vp6Tve7z tokenProgram: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA receiver ATA: 2KcR41e2NxnYY5DWDzvgzHiKpSoaZJ55kvBiqU111DaY receiver (user) ATA owner: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA sender (VaultInfo) ATA: BQhNK47ygEYARanGqJnSjKBco3Crot9ihDMJzT8u7yLU VaultInfo ATA supply: 10 VaultATA owner: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA Program owner: BPFLoaderUpgradeab1e11111111111111111111111 vaultInfoPDA owner: GsCu69BThDsobWHorHkNf8h8zobN6VsexiYkwkH2VtfV
测试脚本
it("User Vault removed!", async () => { // Add your test here. // const tx = await program.methods.initializeUser().rpc(); console.log("user:", user.publicKey) console.log("program:", program.programId) console.log("token program:", TOKEN_PROGRAM_ID) console.log("Mint:", mintPubkey.toBase58()) const [userProfilePDA] = await anchor.web3.PublicKey.findProgramAddress([ utf8.encode("USER_STATE"), user.publicKey.toBuffer(), ], program.programId ); console.log("userProfilePDA", userProfilePDA.toBase58()); const userProfile = await program.account.userProfile.fetch(userProfilePDA); // console.log("UserProfile:", userProfile) console.log("Last vault:", userProfile.lastVault) const [vaultAccountPDA] = await anchor.web3.PublicKey.findProgramAddress([ utf8.encode("VAULT_STATE"), user.publicKey.toBuffer(), new anchor.BN(0).toBuffer() ], program.programId ); console.log("vaultAccountPDA:", vaultAccountPDA.toBase58()); const [vaultInfoPDA] = await anchor.web3.PublicKey.findProgramAddress([ utf8.encode("INFO_STATE"), // user.publicKey.toBuffer(), ], program.programId ); console.log("vaultInfoPDA:", vaultInfoPDA.toBase58()); let tokenAccountPubkeyUser = await getOrCreateAssociatedTokenAccount(program.provider.connection, user, mintPubkey, user.publicKey) console.log("tokenProgram:", TOKEN_PROGRAM_ID.toBase58()) console.log("receiver ATA:", tokenAccountPubkeyUser.address.toBase58()) let tokenAuth = await program.provider.connection.getAccountInfo(tokenAccountPubkeyUser.address); console.log("receiver (user) ATA owner:", tokenAuth.owner.toBase58()) let tokenAccountPubkeyVault = await getOrCreateAssociatedTokenAccount(program.provider.connection, user, mintPubkey, vaultInfoPDA, true) console.log("sender (VaultInfo) ATA:", tokenAccountPubkeyVault.address.toBase58()) let txhash = await transferChecked( program.provider.connection, // connection user, // payer tokenAccountPubkeyUser.address, // from (should be a token account) mintPubkey, // mint tokenAccountPubkeyVault.address, // to (should be a token account) user, // from's owner 10e9, // amount, if your deciamls is 9, send 10^9 for 1 token 9 // decimals ); let tokenAmount = await program.provider.connection.getTokenAccountBalance(tokenAccountPubkeyVault.address); console.log("VaultInfo ATA supply:", tokenAmount.value.uiAmount) tokenAuth = await program.provider.connection.getAccountInfo(tokenAccountPubkeyVault.address); console.log("VaultATA owner:", tokenAuth.owner.toBase58()) tokenAuth = await program.provider.connection.getAccountInfo(program.programId); console.log("Program owner:", tokenAuth.owner.toBase58()) tokenAuth = await program.provider.connection.getAccountInfo(vaultInfoPDA); console.log("vaultInfoPDA owner:", tokenAuth.owner.toBase58()) const tx = await program.rpc.removeVault(0, { accounts: { authority: user.publicKey, userProfile: userProfilePDA, vaultAccount: vaultAccountPDA, vaultInfo: vaultInfoPDA, systemProgram: anchor.web3.SystemProgram.programId, tokenProgram: TOKEN_PROGRAM_ID, from: tokenAccountPubkeyVault.address, to: tokenAccountPubkeyUser.address, owner: vaultInfoPDA, // sender: vaultInfoPDA }, signers: [] }) console.log("Your transaction signature", tx); });
我期望vaultInfoPDA作为该ATA的所有者,将代币转出给用户以完成Vault移除操作,求指点。
内容的提问来源于stack exchange,提问作者Syahmi Shaarani
相关产品推荐
相关产品推荐

