ZBLOG

Web3之门,如何访问以太坊的Public类型数据与接口

在Web3的浪潮中,以太坊作为最著名的区块链平台,其核心魅力之一在于其公开透明性,开发者、用户和研究者经常需要与以太坊网络上的数据进行交互,而“public类型”在其中扮演着至关重要的角色,理解什么是以太坊的“public类型”,以及如何在Web3应用中访问它们,是踏入Web3开发领域的必备技能,本文将深入探讨这一主题。

什么是以太坊的“Public类型”?

在以太坊的语境下,“public类型”并非指某种特定的数据类型(如uint256, address等),而是指那些在以太坊网络上公开可见、可以被任何人读取(甚至写入,取决于合约逻辑)的数据和接口,这种公开性是以太坊作为区块链的基石之一,确保了网络的透明度和可审计性。

“public类型”主要包括:

  1. Public状态变量 (Public State Variables):在智能合约中,被声明为public的状态变量,Solidity编译器会自动为其生成一个公共的getter函数,这意味着任何人都可以通过调用这个函数来读取该变量的值,无需知道合约的具体内部实现细节。

    • uint256 public myNumber; 会自动生成一个 function myNumber() external view returns (uint256) 的函数。
  2. Public函数 (Public Functions):合约中明确声明为public的函数,可以被任何外部账户或其他合约调用(除非有访问控制修饰符如onlyOwner等限制),这些函数通常用于修改合约状态或触发特定逻辑。

  3. Public事件 (Public Events):合约发出的事件(Event)本质上是公开的,一旦交易被挖矿确认,事件就会被记录在区块链的日志中,任何人都可监听和查询,事件是前端应用与区块链交互、获取实时数据的重要途径。

  4. Public数据本身:存储在以太坊区块链上的所有数据,包括账户余额、交易历史、合约代码以及合约状态变量的存储值,都是公开的,任何人都可以通过以太坊节点或区块链浏览器查询这些信息。

Web3应用如何访问以太坊的Public类型?

Web3应用(通常指运行在浏览器、移动设备或服务器端的应用程序)通过以太坊节点来访问这些公开数据,以太坊节点是运行以太坊客户端软件(如Geth, Parity, Infura, Alchemy等)的计算机,它们维护着区块链的完整或部分副本。

访问以太坊public类型数据的主要方式和工具如下:

使用Web3.js (JavaScript/TypeScript)

Web3.js是最流行的JavaScript库之一,用于与以太坊节点进行交互,它提供了一系列API来调用public函数、读取状态变量、监听事件等。

示例:读取合约的Public状态变量

假设我们有一个简单的合约SimpleStorage,有一个public uint256 storedData

const Web3 = require('web3');
const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID'); // 连接到以太坊主网节点
// 合约ABI (Application Binary Interface) - 定义合约的接口
const abi = [
    {
        "inputs": [],
        "name": "storedData",
        "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
        "stateMutability": "view",
        "type": "function"
    }
    // ... 其他函数的ABI
];
// 合约地址
const contractAddress = '0x...YourContractAddress...';
// 创建合约实例
const contract = new web3.eth.Contract(abi, contractAddress);
// 调用public getter函数读取storedData
async function getStoredData() {
    try {
        const result = await contract.methods.storedData().call();
        console.log('Stored Data:', result);
    } catch (error) {
        console.error('Error:', error);
    }
}
getStoredData();

示例:监听Public事件

// 假设合约有一个名为"DataChanged"的public事件
const eventAbi = {
    "anonymous": false,
    "inputs": [
        {"indexed": false, "name": "newValue", "type": "uint256"}
    ],
    "name": "DataChanged",
    "type": "event"
};
// 将事件ABI添加到合约实例的ABI数组中
contract.events.DataChanged({}, (error, event) => {
    if (!error) {
        console.log('Event emitted:', event.returnValues);
    }
})
.on('data', event => {
    console.log('Event data:', event.returnValues);
})
.on('error', err => {
    console.error('Event error:', err);
});

使用Ethers.js (JavaScript/TypeScript)

Ethers.js是另一个功能强大且日益流行的Web3库,以其更清晰的API设计和更好的错误处理而受到欢迎。

示例:读取Public状态变量

const { ethers } = require('ethers');
const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID');
const abi = [/* 与上面类似的ABI */];
const contractAddress = '0x...YourContractAddress...';
const contract = new ethers.Contract(contractAddress, abi, provider);
async function getStoredDataWithEthers() {
    try {
        const result = await contract.storedData();
        console.log('Stored Data (Ethers):', result.toString());
    } catch (error) {
        console.error('Error:', error);
    }
}
getStoredDataWithEthers();

使用以太坊JSON-RPC API

Web3.js和Ethers.js底层都是通过调用以太坊节点的JSON-RPC接口来实现功能,开发者也可以直接使用JSON-RPC API进行更底层的交互。

使用eth_call来调用view函数(即读取public状态变量或纯函数):

// JSON-RPC请求示例
{
    "jsonrpc": "2.0",
    "method": "eth_call",
    "params": [
        {
            "to": "0x...YourContractAddress...",
            "data": "0x6d4ce63c000000000000000000000000000000000000000000000000000000000000000a" // 这是abi.encodePacked("storedData()")的结果,需要根据实际情况计算
        },
        "latest"
    ],
    "id": 1
}

响应中会包含函数调用的返回值。

使用区块链浏览器

对于不需要编程的普通用户,区块链浏览器(如Etherscan, Ethplorer等)是最直观访问以太坊public数据的工具,你可以通过浏览器查看:

  • 账户余额和交易记录
  • 合约源代码和ABI
  • 合约的public状态变量值
  • 合约发出的事件日志

访问Public类型时的注意事项

  1. 节点选择:你可以运行自己的全节点(数据最全但资源消耗大),或使用第三方节点服务(如Infura, Alchemy,方便快捷但有潜在的中心化风险和调用限制)。
  2. Gas费用:对于写入操作(调用public函数修改状态),需要支付Gas费用,读取操作(调用view/pure函数)通常不消耗Gas(除非通过特定节点服务收费)。
  3. 数据同步:如果你运行的是全节点,需要确保节点同步到最新区块,才能获取最新的public数据。
  4. ABI的重要性:与智能合约交互时,正确的ABI(Application Binary Interface)至关重要,它定义了函数如何编码和解码参数。
  5. 安全性:虽然public数据是公开的,但在与合约交互时,要注意智能合约的安全性,避免恶意合约或重入攻击等风险。
分享:
扫描分享到社交APP