发送程序指令时的调试"Transaction simulation failed"(Solana Solidity)



当试图调用用@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())

这导致了我原来帖子中包含的更详细的错误。当我意识到要查找什么时,这个错误消息确实很有帮助——TransactionTransactionInstructionkeys字段中缺少发送帐户的公钥。我把它添加到@solana/solidity库的分叉中,错误就消失了。

简而言之,我能够调试的方法是通过

  1. 使用provider.request({ method: 'signTransaction' })connection.sendRawTransaction(transaction)而不是Phantom的provider.signAndSendTransaction()方法来获得更详细的错误消息
  2. 记录事务对象并仔细检查指令

我希望这对将来的其他人有所帮助。

最新更新