HTML中调用Solana web3.js初始化Connection连接失败如何解决?
问题根因
你同时加载了以太坊Web3.js库和Solana web3.js库,两个库都默认绑定window.web3全局变量,导致你调用Solana相关API时实际访问的是以太坊Web3实例,自然找不到Connection等方法。同时Solana官方IIFE格式的web3.js包默认绑定的全局变量名为solanaWeb3,不是web3,也是报错原因之一。
修复步骤
- 第一步:删除不需要的以太坊Web3.js引入代码,就是以下这行:
<script src="https://cdnjs.cloudflare.com/ajax/libs/web3/3.0.0-rc.5/web3.min.js" integrity="sha512-jRzb6jM5wynT5UHyMW2+SD+yLsYPEU5uftImpzOcVTdu1J7VsynVmiuFTsitsoL5PJVQi+OtWbrpWq/I+kkF4Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
- 第二步:将你业务代码中所有的
web3.前缀替换为solanaWeb3.,Solana官方IIFE包的全局导出名称为solanaWeb3,示例如下:
// 修正前 const connection = new web3.Connection(web3.clusterApiUrl("devnet")); // 修正后 const connection = new solanaWeb3.Connection(solanaWeb3.clusterApiUrl("devnet"));
- 第三步:补充
provider变量定义,你的代码中直接使用了未声明的provider变量,Phantom钱包注入的实例就是window.solana,你可以直接替换所有provider.为window.solana.,也可以在函数开头加一行声明:
const provider = window.solana;
- 第四步:可选优化,devnet的airdrop接口有调用频率限制,如果运行时报错可以直接删除airdrop相关代码,手动向测试地址转入测试SOL即可,另外原代码中已废弃的
getRecentBlockhash方法可替换为新版的getLatestBlockhash。
修正后的核心函数示例
async function transferSOL() { const provider = window.solana; if (!provider.isConnected){ await provider.connect(); } const pubKey = provider.publicKey; console.log("Public Key: ", pubKey); const connection = new solanaWeb3.Connection(solanaWeb3.clusterApiUrl("devnet")); alert('hello2'); const recieverWallet = new solanaWeb3.PublicKey("4iSD5Q6AnyhRHu6Uz4u1KAzXh3TwNwwQshEGhZbEXUTw"); alert('hello3'); // 测试用airdrop逻辑,触发频率限制可删除 try { const airdropSignature = await connection.requestAirdrop( pubKey, solanaWeb3.LAMPORTS_PER_SOL, ); await connection.confirmTransaction(airdropSignature); console.log("Airdropped"); } catch(e) { console.log("airdrop失败,可忽略:", e) } const transaction = new solanaWeb3.Transaction().add( solanaWeb3.SystemProgram.transfer({ fromPubkey: pubKey, toPubkey: recieverWallet, lamports: solanaWeb3.LAMPORTS_PER_SOL }), ); transaction.feePayer = pubKey; const blockhashObj = await connection.getLatestBlockhash(); transaction.recentBlockhash = blockhashObj.blockhash; if(transaction) { console.log("Txn created successfully"); } const signed = await provider.signTransaction(transaction); const signature = await connection.sendRawTransaction(signed.serialize()); await connection.confirmTransaction(signature); console.log("Signature: ", signature); }
内容的提问来源于stack exchange,提问作者isash
相关产品推荐
相关产品推荐

