You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solana web3.js交互脚本未返回transactionSignature问题求助

问题分析与解决

核心问题1:异步函数未等待导致日志丢失

你的main函数中调用pingProgram时没有添加await,主线程会直接跳过异步操作执行后续的then块并退出程序,导致pingProgram里的交易签名日志根本没机会打印。

核心问题2:交易Blockhash的时机问题

Web3.Transaction实例创建时不会自动包含blockhash,sendAndConfirmTransaction方法内部会自动获取最新blockhash并填充到交易中。所以在调用该方法前打印transaction,自然看不到blockhash信息。如果需要在发送前查看,可以显式获取并赋值。

修改后的代码

/*  What this program will do?
    Our client will ping a counter program, which will increment a counter. 
    I'm going to tell everyone on the network that I'm a builder
*/

// I'm adding these
import * as Web3 from '@solana/web3.js';
import * as fs from 'fs'; // for file handling
import dotenv from 'dotenv';
dotenv.config();

// WE NEED TO KNOW WHAT ACCOUNTS THESE INSTRUCTIONS ARE DEALING WITH, THESE ARE 2 DUMMY ACCOUNTS
const PROGRAM_ID = new Web3.PublicKey("ChT1B39WKLS8qUrkLvFDXMhEJ4F1XZzwUNHUt4AU9aVa")
const PROGRAM_DATA_PUBLIC_KEY = new Web3.PublicKey("Ah9K7dQ8EHaZqcAsgBW8w37yN2eAy3koFmUn4x3CJtod")

async function initializeKeypair(connection : Web3.Connection): Promise<Web3.Keypair> {
    if(!process.env.PRIVATE_KEY) {
        console.log("Generating secret key...🗝️");
        const signer = Web3.Keypair.generate();

        console.log("Creating .env file...");
        fs.writeFileSync('.env', `PRIVATE_KEY=[${signer.secretKey.toString()}]`);

        return signer;
    }

    const secret = JSON.parse(process.env.PRIVATE_KEY ?? '') as number[];
    const secretKey = Uint8Array.from(secret);
    const keypairFromSecret = Web3.Keypair.fromSecretKey(secretKey);
 
    // When creating it from the secret key
    await airdropSolIfNeeded(keypairFromSecret, connection);
    
    return keypairFromSecret;
}

async function airdropSolIfNeeded(signer : Web3.Keypair, connection : Web3.Connection) {
    const balance = await connection.getBalance(signer.publicKey);
    console.log('Current balance is ', balance / Web3.LAMPORTS_PER_SOL, 'SOL');

    //1 SOL is enough for anything we do
    if(balance / Web3.LAMPORTS_PER_SOL < 1) {
        // We can only get up to 2 SOL per request 
        console.log("Airdropping 1 SOL...");
        const airdropSignature = await connection.requestAirdrop(signer.publicKey, Web3.LAMPORTS_PER_SOL);

        const latestBlockhash = await connection.getLatestBlockhash();

        await connection.confirmTransaction({
            blockhash : latestBlockhash.blockhash,
            lastValidBlockHeight : latestBlockhash.lastValidBlockHeight,
            signature : airdropSignature,
        });

        const newBalance = await connection.getBalance(signer.publicKey);
        console.log('The new balance is ', newBalance / Web3.LAMPORTS_PER_SOL, 'SOL');
    }
}

async function pingProgram(connection : Web3.Connection, payer : Web3.Keypair) {
    const transaction = new Web3.Transaction(); // 1. WE MAKE A TRANSACTION
    const instruction = new Web3.TransactionInstruction({ // 2. WE MAKE AN INSTRUCTION
        // Instructions need 3 things 
    
        // (i) The public keys of all the accounts the instruction will read/write
        keys : [
            {
                pubkey : PROGRAM_DATA_PUBLIC_KEY,
                isSigner : false,
                isWritable : true
            }
        ],
        // (ii) The ID of the program this instruction will be sent to
        programId : PROGRAM_ID

        // (iii) Data - in this case, there's none!
    });

    transaction.add(instruction); // 3. WE ADD THIS INSTRUCTION TO THE TRANSACTION

    // 可选:手动获取并设置blockhash,打印时即可看到
    const latestBlockhash = await connection.getLatestBlockhash();
    transaction.recentBlockhash = latestBlockhash.blockhash;
    transaction.lastValidBlockHeight = latestBlockhash.lastValidBlockHeight;
    transaction.feePayer = payer.publicKey; 
    console.log(transaction)

    const transactionSignature = await Web3.sendAndConfirmTransaction(connection, transaction, [payer]); // 4. WE SEND THE TRANSACTION TO THE NETWORK
    console.log(transactionSignature)
    console.log(`Transaction https://explore.solana.com/tx/${transactionSignature}?cluster=devnet`);
}

async function main() {
    const connection = new Web3.Connection(Web3.clusterApiUrl('devnet'));
    const signer = await initializeKeypair(connection);

    console.log('Public Key : ', signer.publicKey.toBase58()); // Solana Public keys are Base58 alphanumeric characters

    // 添加await,等待pingProgram执行完成
    await pingProgram(connection, signer);
}

main()
    .then(() => {
        console.log("Finished successfully")
        process.exit(0)
    })
    .catch((error) => {
        console.log(error)
        process.exit(1)
    })

关键修改点

  • 在main函数中调用pingProgram时添加await,确保程序等待交易流程完成再退出。
  • (可选)在pingProgram中手动设置交易的recentBlockhash、lastValidBlockHeight和feePayer,提前打印transaction就能看到blockhash信息。

内容的提问来源于stack exchange,提问作者m1k3_0xm0L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 23:55:25