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

如何使用私钥而非Phantom钱包签名Solana智能合约函数调用?

用私钥直接签名Solana合约调用的实现方案

完全可以实现,不需要依赖Phantom等钱包,直接用@solana/web3.js(或结合Anchor工具链)就能完成私钥签名的合约函数调用,以下是具体实现步骤:

核心思路

通过加载本地私钥生成Keypair对象,直接用它对交易进行签名,全程无需钱包交互。

1. 基础依赖准备

确保已安装必要的包:

npm install @solana/web3.js
# 如果是Anchor开发的合约,额外安装
npm install @project-serum/anchor

2. 加载私钥生成签名者

将你的私钥(通常是64字节的Uint8数组)转换为Keypair,注意私钥要安全存储,绝对不要硬编码在代码中:

import { Keypair } from "@solana/web3.js";

// 示例:从环境变量加载私钥(推荐方式)
const privateKey = Uint8Array.from(JSON.parse(process.env.SOLANA_PRIVATE_KEY));
const payer = Keypair.fromSecretKey(privateKey);

3. 构建合约调用交易

场景1:普通Solana合约(非Anchor)

需要手动编码函数调用数据和构建交易指令:

import { Transaction, TransactionInstruction, PublicKey, SystemProgram, Connection, clusterApiUrl } from "@solana/web3.js";

// 初始化连接
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

// 合约相关参数
const programId = new PublicKey("你的合约程序ID");
const contractAccount = new PublicKey("合约部署后的账户地址");
const recipient = new PublicKey("接收者地址");
const amount = 1000000000; // 1 SOL

// 编码函数调用数据:函数选择器 + 参数
// 函数选择器是函数签名哈希的前8字节,比如sha256("transfer(u64,Pubkey)").slice(0,8)
const functionSelector = new Uint8Array([0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX]);
const amountBuffer = Buffer.from(new BigUint64LE(amount).buffer);
const recipientBuffer = recipient.toBytes();
const data = Buffer.concat([functionSelector, amountBuffer, recipientBuffer]);

// 构建交易指令
const instruction = new TransactionInstruction({
  keys: [
    { pubkey: payer.publicKey, isSigner: true, isWritable: true }, // 付款人(签名者)
    { pubkey: contractAccount, isSigner: false, isWritable: true }, // 合约账户
    { pubkey: SystemProgram.programId, isSigner: false, isWritable: false } // 系统程序(如果需要)
    // 添加其他必要的账户(比如代币账户等)
  ],
  programId,
  data
});

// 创建交易并设置区块哈希
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
const transaction = new Transaction({
  recentBlockhash: blockhash,
  lastValidBlockHeight,
  feePayer: payer.publicKey
}).add(instruction);

场景2:Anchor开发的合约

借助Anchor IDL可以自动编码数据,实现更简洁:

import { AnchorProvider, Program, web3 } from "@project-serum/anchor";
import idl from "./your-contract-idl.json"; // 合约的IDL文件

const connection = new web3.Connection(web3.clusterApiUrl("devnet"), "confirmed");
const payer = web3.Keypair.fromSecretKey(privateKey);

// 创建Anchor Provider,用本地Keypair作为钱包
const provider = new AnchorProvider(
  connection,
  new web3.Wallet(payer),
  { commitment: "confirmed" }
);

// 初始化Program实例
const program = new Program(idl, "你的合约程序ID", provider);

// 直接调用合约函数
await program.methods
  .transfer(new web3.BN(amount), recipient)
  .accounts({
    payer: payer.publicKey,
    contract: contractAccount,
    systemProgram: web3.SystemProgram.programId
    // 其他需要的账户
  })
  .rpc();

4. 签名并发送交易

对于普通合约场景,需要手动签名后发送:

// 用私钥签名交易
transaction.sign(payer);

// 序列化并发送交易
const signature = await connection.sendRawTransaction(transaction.serialize());

// 等待交易确认
await connection.confirmTransaction({
  signature,
  blockhash,
  lastValidBlockHeight
});

console.log("交易完成,签名:", signature);

注意事项

  • 私钥必须严格保密,建议通过环境变量、加密配置文件等方式加载,禁止硬编码或暴露在前端代码中。
  • 交易的账户列表必须包含所有涉及的账户(签名者、可写账户、只读账户),否则交易会执行失败。
  • 区块哈希的有效期很短,获取后要尽快完成签名和发送,避免交易过期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 09:15:29