您的USDC正在按昨天的利率产生收益Quicknode 会自动将其转移到今日最佳的 Morpho 保险库中。已在 7 条链上上线。
制定您的策略Solana :与Ethereum 方法的对比
对Ethereum基于 EVM 的 RPC 方法与Solana RPC 调用进行全面对比。通过弥合这两大领先区块链之间的知识鸿沟,深入理解其中的细微差别、相似之处和区别。

2023年8月31日 — 阅读时间11分钟

在探索广阔的区块链世界时,许多熟悉Ethereum RPC 方法的开发者常常希望了解这些方法在其他区块链(如Solana)中的对应实现。本入门指南对比了Ethereum RPC 方法与Solana 方法,阐明了它们各自的功能及等效关系。 无论您是希望厘清Solana 运作机制的Ethereum ,还是初涉Solana 领域的开发者,本入门指南都将为您提供有助于拓展区块链知识的见解。
与Ethereum 对应的Solana 方法 eth_getBlockByNumber 对应的Solana 方法 getBlock。但需要注意的是Solana Ethereum 在区块链结构及术语Ethereum ,因此返回的数据以及调用这些方法的方式可能会有所不同。
在Ethereum中, eth_getBlockByNumber 允许您通过区块编号或区块标签来获取区块信息。同样,在Solana 中, getBlock 函数则允许您通过提供区块的槽位(相当于Ethereum区块号)来获取区块信息。
以下是一个关于如何使用 getBlock 方法的Solana:
# Using solana-cli solana block <block_slot>
如果您正在通过编程方式与Solana API 进行交互,可以使用 JavaScript 库(如solana.js)来调用此方法:
const web3 = require('@solana/web3.js');
const solanaRpcUrl = 'QUICKNODE_URL'; // Replace with the quicknode url
const connection = new web3.Connection(solanaRpcUrl, 'confirmed');
async function getSolanaBlock(slot) {
const block = await connection.getBlock(slot);
console.log(block);
}
const blockSlot = 12345678; // Replace with the desired block slot
getSolanaBlock(blockSlot);Ethereum eth_getTransactionReceipt 可获取交易的收据,其中包括合约事件和日志的相关信息。在Solana 中,由于Solana Ethereum 交易模型及数据结构Ethereum 没有直接对应的方法。不过,您可以通过结合使用Solana RPC 方法和编程特性来实现类似的功能。
要获取与 eth_getTransactionReceiptSolana,您需要按照以下步骤操作:
使用Solana RPC 方法获取交易信息:
使用 getTransactionSolana 方法来获取交易详情。
解析日志和事件:
Solana 本身Solana 像Ethereum那样具备日志的概念。相反,你需要在设计Solana 时,使其发布你希望跟踪的自定义事件或数据。
从事务的消息或事务日志中解析并解码这些自定义事件。
构建自定义响应:
根据解码后的事件和信息,您可以构建一个自定义响应对象,其内容与从Ethereum 收据中获取的信息相似。
以下是一个简化的示例,展示了如何使用 JavaScript 和Solana solana.js库来实现这一功能:
const web3 = require('@solana/web3.js');
async function getSolanaTransactionReceipt(transactionSignature) {
const solanaRpcUrl = 'QUICKNODE_URL'; // Replace with the quicknode url
const connection = new web3.Connection(solanaRpcUrl, 'confirmed');
const transaction = await connection.getTransaction(transactionSignature);
if (!transaction) {
return null; // Transaction not found
}
// Parse and decode custom events/logs from transaction.message
const decodedEvents = parseAndDecodeEvents(transaction.message.logs);
const receipt = {
transactionHash: transactionSignature,
blockNumber: transaction.slot, // Solana's equivalent of block number
// Other relevant information based on your decoded events
decodedEvents,
};
return receipt;
}
function parseAndDecodeEvents(logs) {
// Implement logic to parse and decode logs into custom event data
// This could involve iterating through logs and extracting data
// Refer to Solana's documentation and your program's event structure
return decodedEvents;
}
const transactionSignature = '...'; // Replace with the Solana transaction signature
getSolanaTransactionReceipt(transactionSignature)
.then((receipt) => {
console.log(receipt);
})
.catch((error) => {
console.error('Error:', error);
});请注意Solana设计和数据结构Ethereum不同,因此您需要据此调整实现方法。所提供的示例仅为高层次的指导,您需要根据具体的Solana 用例进行定制。
Ethereum eth_getCode 用于检索部署在Ethereum 上的智能合约的字节码。Solana 中与此功能相当的Solana 方法是 getAccountInfo,该方法可用于检索账户的相关信息,包括与其关联的数据。
以下是使用Solana getAccountInfo 方法,并与Ethereum的 eth_getCode的对比说明:
Ethereum eth_getCode:
// Using web3.js for Ethereum
const Web3 = require('web3');
const web3 = new Web3('QUICKNDOE_URL'); // Replace with the quicknode url
async function getEthContractBytecode(address) {
const bytecode = await web3.eth.getCode(address);
return bytecode;
}
const contractAddress = '0x...'; // Replace with the Ethereum contract address
getEthContractBytecode(contractAddress)
.then((bytecode) => {
console.log(bytecode);
})
.catch((error) => {
console.error('Error:', error);
});Solana getAccountInfo:
const web3 = require('@solana/web3.js');
async function getSolanaContractData(address) {
const solanaRpcUrl = 'QUICKNODE_URL'; // Replace with the quicknode url const connection = new web3.Connection(solanaRpcUrl, 'confirmed');
const publicKey = new web3.PublicKey(address);
const accountInfo = await connection.getAccountInfo(publicKey);
if (!accountInfo) {
return null; // Account not found
}
const contractData = accountInfo.data;
return contractData;
}
const contractAddress = '...'; // Replace with the Solana contract address
getSolanaContractData(contractAddress)
.then((contractData) => {
console.log(contractData);
})
.catch((error) => {
console.error('Error:', error);
});在Solana 中, getAccountInfo 会检索指定账户的相关信息,而账户信息对象的data字段中包含与合约相关的字节码或数据。请注意Solana 可以存储多种类型的数据,而不仅仅是字节码,因此根据您的具体用例,data字段的内容可能需要进一步处理。
请根据您的具体用例和所使用的库对示例进行调整。Solana设计和术语与Ethereum不同,因此您处理合约及其数据的方式也会有所不同。
Ethereum eth_call 用于调用合约函数或检索合约状态,而无需在Ethereum 实际发起交易。Solana 与此功能相当的Solana 方法是 simulateTransaction,它允许您模拟一笔交易,并获取在Solana 执行程序(智能合约)的结果。
以下是使用Solana simulateTransaction 方法,并与Ethereum的 eth_call的对比:
Ethereum eth_call:
// Using web3.js for Ethereum
const Web3 = require('web3');
const web3 = new Web3('QUICKNODE_URL'); // Replace with the quicknode url
async function ethCall(contractAddress, data) {
const result = await web3.eth.call({
to: contractAddress,
data: data,
});
return result;
}
const contractAddress = '0x...'; // Replace with the Ethereum contract address
const inputData = '0x...'; // Replace with the input data for the function call
ethCall(contractAddress, inputData)
.then((result) => {
console.log(result);
})
.catch((error) => {
console.error('Error:', error);
});Solana simulateTransaction:
const web3 = require('@solana/web3.js');
async function simulateSolanaTransaction(sender, programId, data) {
const solanaRpcUrl = 'QUICKNODE_URL'; // Replace with the quicknode url
const connection = new web3.Connection(solanaRpcUrl, 'confirmed');
const instruction = new web3.TransactionInstruction({
keys: [{ pubkey: sender, isSigner: true, isWritable: true }],
programId,
data,
});
const simulatedTransactionResponse = await connection.simulateTransaction(
new web3.Transaction().add(instruction)
);
const simulatedResult = simulatedTransactionResponse.value;
return simulatedResult;
}
const senderPublicKey = new web3.PublicKey('...'); // Replace with the sender's public key
const programId = new web3.PublicKey('...'); // Replace with the Solana program ID
const inputData = Buffer.from('...'); // Replace with the input data for the program
simulateSolanaTransaction(senderPublicKey, programId, inputData)
.then((simulatedResult) => {
console.log(simulatedResult);
})
.catch((error) => {
console.error('Error:', error);
});在Solana 中, simulateTransaction 允许您使用交易指令模拟程序(智能合约)的执行。请注意Solana 设置Ethereum不同,因此您需要相应地调整代码。与基于Ethereum)的方法相比Solana架构和设计可能需要额外的考虑和调整。
Ethereum eth_getBalance 用于查询特定Ethereum 余额。Solana 中与此对应的Solana 方法是 getBalance,该方法可用于查询特定Solana 地址的余额。
以下是使用Solana getBalance 方法,并与Ethereum的 eth_getBalance的对比说明:
Ethereum eth_getBalance:
// Using web3.js for Ethereum
const Web3 = require('web3');
const web3 = new Web3('QUICKNODE_URL'); // Replace with the quicknode url
async function getEthBalance(address) {
const balance = await web3.eth.getBalance(address);
return balance;
}
const ethAddress = '0x...'; // Replace with the Ethereum address
getEthBalance(ethAddress)
.then((balance) => {
console.log(balance);
})
.catch((error) => {
console.error('Error:', error);
});Solana getBalance:
const web3 = require('@solana/web3.js');
async function getSolanaBalance(address) {
const solanaRpcUrl = 'QUICKNODE_URL'; // Replace with the quicknode url
const connection = new web3.Connection(solanaRpcUrl, 'confirmed');
const publicKey = new web3.PublicKey(address);
const balance = await connection.getBalance(publicKey);
return balance;
}
const solanaAddress = '...'; // Replace with the Solana wallet address
getSolanaBalance(solanaAddress)
.then((balance) => {
console.log(balance);
})
.catch((error) => {
console.error('Error:', error);
});在这两种情况下,您查询的都是特定地址的余额,但请注意,Ethereum Solana在地址格式及网络特定细节方面存在差异。Solana Ed25519 公钥格式作为地址,而Ethereum 十六进制格式。
请将占位符替换为实际地址,并根据您使用的库和工具调整代码。Solana Ethereum 架构和设计Ethereum ,因此代码和实现方法在某些方面可能会有所差异。
Solana 的架构和设计与Ethereum截然不同,虽然Ethereum debug_traceBlockByHash 方法来追踪和调试区块Solana方法和工具可能没有具备同等详细程度的直接对应功能。
在Ethereum中, debug_traceBlockByHash 可用于详细追踪和分析区块内的执行过程及状态变化。而Solana(Solana则主要侧重于高吞吐量和高性能,这可能会导致其调试和追踪机制的实现方式有所不同。
Solana RPC 方法没有提供与Ethereumdebug_traceBlockByHash方法。Solana 的设计优先考虑速度和可扩展性,且其侧重于并行处理,这可能使得追踪区块中的每个细节变得不太现实。
不过,出于调试和追踪的目的,以下这些Solana 方法可能会对你有所帮助:
交易浏览器: Solana 在其区块浏览器网站(例如Solana )Solana 交易浏览器。虽然它提供的详细程度可能不及Ethereum区块追踪功能,但它可以帮助您直观地查看区块内的交易和程序执行情况。
Solana 与日志记录: Solana 界面(CLI)提供了用于与Solana 命令。虽然它可能无法提供Ethereum调试方法相同的追踪能力,但确实提供了用于监控交易和程序日志的工具。
程序日志: Solana 可以生成日志,这些日志可通过 getLogs RPC 方法检索。这些日志有助于了解Solana 执行情况。
开发者社区:随着Solana 生态系统的不断发展,可能会出现用于调试和追踪的新工具与新技术。建议关注Solana官方渠道和开发者社区讨论,以获取最新动态和最佳实践。
在Solana 中,跨程序调用的概念与Ethereum内部交易类似,但在工作原理和返回的数据方面存在一些差异。
在Ethereum,当你执行跟踪调用以分析内部交易时(使用 debug_traceTransaction RPC 方法)执行跟踪调用以分析内部交易时,你可以看到交易内部发生的调用和交互序列,包括合约调用及其效果。
在Solana 中,跨程序调用是指从Solana 内部调用其他Solana (智能合约)。Solana 通常使用 Rust 语言编写,并编译为一种名为 BPF(Berkeley Packet Filter)字节码的自定义字节码,该字节码在Solana 区块链上执行。当一个Solana 调用另一个Solana 时,即为跨程序调用。
然而,您从Solana 的跨程序调用中获取的信息和数据更多Solana Solana 之间的交互,其详细程度可能无法Ethereum内部交易相媲美。Solana原生交易结构和编程模型旨在实现高性能和并行处理,这可能与Ethereum基于 EVM 的智能合约交互并不完全一致。
如果你想在Solana 中找到Ethereum追踪功能完全对应的功能,需要注意的是Solana架构和设计可能无法提供完全相同粒度的信息。Solana 更侧重于实现高吞吐量和效率,而Ethereum侧重于提供合约交互的全面视图。
若要探索Solana 中的跨程序调用,您可以参考Solana 了解如何在Solana 使用invoke方法,以及可用于与Solana 交互并获取其执行信息的可用 RPC 方法。
如需进一步了解如何基于Solana 进行开发,请访问以下资源:
Quicknode 成立于 2017 年,Quicknode 为开发者和企业Quicknode 机构级区块链基础设施。凭借 99.99% 的运行时间以及对 80 多条区块链的支持,各团队能够毫无妥协地构建和扩展链上应用。
将最新的工程见解、产品更新和 Web3 资讯直接发送至您的收件箱。
通过 SOC 2 II 类认证 · ISO 27001