我正在尝试使用 OpenSea api 创建一个列表,其中一个参数是“counter”。
他们(OpenSea)说,如果你不确定当前的计数器,可以从 Etherscan 上的合约中读取。
我四处询问,似乎你可以使用 Solidity 通过 getCounter() 获得这个计数器。
我使用 C# - 我该怎么做?
我尝试使用合约 ABI - 查找并调用一个名为 getCounter 或类似函数的函数,但 ABI 中没有这样的东西。
我有办法做到这一点吗?
编辑:这里是 C# 代码,应该调用合约 ABI 中的 getCounter 函数并获取计数器。问题是 ABI 不包含这样的功能。
using System;
using System.Net.Http;
using System.Numerics;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
public class ContractInteraction
{
private readonly string contractAddress;
private readonly JArray contractAbi;
private readonly string walletAddress;
public ContractInteraction(string contractAddress, JArray contractAbi, string walletAddress)
{
this.contractAddress = contractAddress;
this.contractAbi = contractAbi;
this.walletAddress = walletAddress;
}
public async Task<int> GetCounter()
{
// Replace this URL with the Ethereum node endpoint you're using
string ethereumNodeUrl = "https://mainnet.infura.io/v3/your-infura-key";
// You might need to adjust this based on the specific function in your contract that returns the counter
string methodName = "getCounter";
// Build the JSON-RPC request
var rpcRequest = new
{
jsonrpc = "2.0",
method = "eth_call",
@params = new
{
to = contractAddress,
data = GetFunctionCallData(methodName),
},
id = 1
};
using (var client = new HttpClient())
{
var response = await client.PostAsJsonAsync(ethereumNodeUrl, rpcRequest);
var responseData = await response.Content.ReadAsStringAsync();
var result = JObject.Parse(responseData)["result"].ToString();
// Convert the hex result to an integer
int counter = int.Parse(result, System.Globalization.NumberStyles.HexNumber);
return counter;
}
}
private string GetFunctionCallData(string methodName)
{
var function = contractAbi
.Where(token => token["type"].ToString() == "function" && token["name"].ToString() == methodName)
.FirstOrDefault();
if (function == null)
{
throw new InvalidOperationException($"Function '{methodName}' not found in contract ABI.");
}
string signature = function["signature"].ToString();
return $"{signature.Substring(0, 10)}{walletAddress.Substring(2).PadLeft(64, '0')}";
}
}
class Program
{
static async Task Main()
{
string contractAddress = "0xYourContractAddress";
string contractAbiFilePath = "path/to/your/abi-file.txt";
string yourWalletAddress = "0xYourWalletAddress";
string abiJson = System.IO.File.ReadAllText(contractAbiFilePath);
JArray abiArray = JArray.Parse(abiJson);
ContractInteraction contractInteraction = new ContractInteraction(contractAddress, abiArray, yourWalletAddress);
int counter = await contractInteraction.GetCounter();
Console.WriteLine($"Counter: {counter}");
}
}
尝试使用 Nethereum 库。虽然我无法测试它,但下面的代码可能会给你一些想法。
string url = "https://mainnet.infura.io/v3/YOUR_PROJECT_ID";
// Address of the contract
string contractAddress = "0x...";
// Contract ABI
string abi= @"[...ABI JSON...]";
var web3 = new Web3(url);
var contract = web3.Eth.GetContract(abi, contractAddress);
var function = contract.GetFunction("getCounter");
var result = await function.CallAsync<string>(<parameters if any>);
return result;