当试图调用用@solana/solity编译的程序时,我收到以下错误:
Transaction simulation failed: Error processing Instruction 0: Program failed to complete
Program jdN1wZjg5P4xi718DG2HraGuxVx1mM7ebjXpxbJ5R3N invoke [1]
Program log: pxKTQePwHC9MiR52J5AYaRtSLAtkVfcoGS3GaLD24YX
Program log: sender account missing from transaction
Program jdN1wZjg5P4xi718DG2HraGuxVx1mM7ebjXpxbJ5R3N consumed 200000 of 200000 compute units
Program failed to complete: BPF program Panicked in solana.c at 285:0
Program jdN1wZjg5P4xi718DG2HraGuxVx1mM7ebjXpxbJ5R3N failed: Program failed to complete
jdN1wZjg5P4xi718DG2HraGuxVx1mM7ebjXpxbJ5R3N
是程序的公钥,pxKTQePwHC9MiR52J5AYaRtSLAtkVfcoGS3GaLD24YX
是发送者的公钥。
我使用的是@solana/solidity库的一个分叉,它公开了Transaction
对象,这样它就可以由Phantom Wallet在前端签名和发送。导致错误的代码如下:
// Generate the transaction
const transaction = contract.transactions.send(...args);
// Add recent blockhash and fee payer
const recentBlockhash = (await connection.getRecentBlockhash()).blockhash;
transaction.recentBlockhash = recentBlockhash;
transaction.feePayer = provider.publicKey;
// Sign and send the transaction (throws an error)
const res = await provider.signAndSendTransaction(transaction);
我会尝试自己进一步调试,但我不确定从哪里开始。查找错误消息没有得到任何结果,而且错误消息的描述性也不强。我不确定这个错误是发生在程序执行本身,还是事务对象的组成有问题。如果这是程序执行中的一个问题,有没有办法将日志添加到我的solidity代码中?如果事务对象有问题,可能缺少什么?如何更好地调试此类问题?
谢谢你的帮助。
编辑:我现在得到了一个不同的错误,尽管我没有更改任何提供的代码。错误消息现在如下:
Phantom - RPC Error: Transaction creation failed. {code: -32003, message: 'Transaction creation failed.'}
不幸的是,此错误消息的帮助甚至不如上一条。我不确定Phantom Wallet是否更新了,或者项目依赖项是否在某个时候更新了,但考虑到这两条错误消息的模糊性,以及我的代码没有更改的事实,我相信它们是由同一个问题引起的。再次感谢任何帮助或调试技巧。
我能够解决这个问题,尽管我遇到了另一个问题,但它与这个问题的内容无关,所以我将单独发布。
关于我的编辑,我发现错误消息之间的差异取决于我发送交易的方式。起初,我尝试使用Phantom的.signAndSendTransaction()
方法发送它,这产生了第二条错误消息(在我的编辑下列出(。然后我试着签名&手动发送交易,如下所示:
const signed = await provider.request({
method: 'signTransaction',
params: {
message: bs58.encode(transaction.serializeMessage()),
},
});
const signature = bs58.decode(signed.signature);
transaction.addSignature(provider.publicKey, signature);
await connection.sendRawTransaction(transaction.serialize())
这导致了我原来帖子中包含的更详细的错误。当我意识到要查找什么时,这个错误消息确实很有帮助——Transaction
上TransactionInstruction
的keys
字段中缺少发送帐户的公钥。我把它添加到@solana/solidity库的分叉中,错误就消失了。
简而言之,我能够调试的方法是通过
- 使用
provider.request({ method: 'signTransaction' })
和connection.sendRawTransaction(transaction)
而不是Phantom的provider.signAndSendTransaction()
方法来获得更详细的错误消息 - 记录事务对象并仔细检查指令
我希望这对将来的其他人有所帮助。