Ethers.js может вызовать fetchmartitems () fine, но PHP (web3p/web3.php) не может декодировать возврат кортежа [] - как Php

Кемеровские программисты php общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Ethers.js может вызовать fetchmartitems () fine, но PHP (web3p/web3.php) не может декодировать возврат кортежа [] - как

Сообщение Anonymous »

У меня есть контракт на NFT Marketplace, работающий на местном хардхатском узле. Функция ниже возвращает массив структур: < /p>
struct MarketItem {
uint256 tokenId;
address payable seller;
address payable owner;
uint256 price;
bool sold;
}
< /code>
function fetchMarketItems() public view returns (MarketItem[] memory) {
// ...
}
< /code>
ABI excerpt:

{
"inputs": [],
"name": "fetchMarketItems",
"outputs": [
{
"components": [
{ "internalType": "uint256", "name": "tokenId", "type": "uint256" },
{ "internalType": "address payable", "name": "seller", "type": "address" },
{ "internalType": "address payable", "name": "owner", "type": "address" },
{ "internalType": "uint256", "name": "price", "type": "uint256" },
{ "internalType": "bool", "name": "sold", "type": "bool" }
],
"internalType": "struct NFTMarketplace.MarketItem[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
}
< /code>
What works (JS / ethers.js)
if (!NFTMarketplaceABI) await loadABI();
const provider = new ethers.providers.JsonRpcProvider(); // Hardhat default localhost
const contract = new ethers.Contract(
"0x5FbDB2315678afecb367f032d93F642f64180aa3",
NFTMarketplaceABI,
provider
);
const data = await contract.fetchMarketItems();
console.log(data); // OK: array of items
< /code>
What fails (PHP / web3p/web3.php)
Environment: PHP 8.x, Laravel, web3p/web3.php (Contract/HttpProvider/HttpRequestManager), Hardhat node accessible at http://172.17.0.1:8545 from inside Docker.
$provider = new HttpProvider(new HttpRequestManager('http://172.17.0.1:8545'));
$contractAddress = '0x5FbDB2315678afecb367f032d93F642f64180aa3';

$abiPath = app()->basePath('public/NFTMarketplace.json');
$abiJson = json_decode(file_get_contents($abiPath), true);
if (!isset($abiJson['abi'])) {
throw new \Exception('ABI not found');
}

$contract = new Contract($provider, $abiJson['abi']);
$contract->at($contractAddress);

// sanity check
$contract->eth->getCode($contractAddress, 'latest', function ($e, $code) {
if ($e !== null) throw new \Exception($e->getMessage());
if ($code === '0x' || $code === '0x0') throw new \Exception('Address is not a contract');
});

$items = [];
$errMsg = null;

$contract->call('fetchMarketItems', [], function ($err, $result) use (&$items, &$errMsg) {
if ($err !== null) { $errMsg = $err->getMessage(); return; }
$items = $result ?? [];
});

if ($errMsg) {
throw new \RuntimeException("fetchMarketItems failed: {$errMsg}");
}
< /code>
Actual result: the callback receives an error and $errMsg is set. Example message I see:
fetchMarketItems failed: unsupported or invalid solidity type "tuple[]" (message may vary; earlier I’ve also hit decode-related errors while stepping through the library’s ABI decoder).
Expected: an array of market items, same as in ethers.js.
What I’ve tried
Verified the contract address and eth_getCode (non-zero).
Confirmed the ABI file is the same one ethers.js uses.
Tried both 127.0.0.1:8545 and 172.17.0.1:8545 (Docker host).
Searched issues/docs for tuple[]/struct[] return support in web3p/web3.php.
Tested simpler functions (e.g., returns uint256) — those work.
Question
Does web3p/web3.php support decoding returns of dynamic arrays of structs (tuple[]) from Solidity? If yes, what is the correct way to call/define the ABI so that Contract->call('fetchMarketItems') returns decoded data? If not, what are practical workarounds in PHP (e.g., returning parallel arrays, using another ABI decoder/package, or different PHP Web3 library) to read struct[] results?
Notes
Node: Hardhat local chain
Contract: 0x5FbDB2315678afecb367f032d93F642f64180aa3
Framework: Laravel
Library: web3p/web3.php
Everything up to $contract->call('fetchMarketItems', ...) works fine — the provider connects, the ABI loads, eth_getCode returns bytecode (non-zero), and simple view calls (e.g., listingPrice()) decode correctly. The error only appears when calling fetchMarketItems (returns tuple[]).

Подробнее здесь: https://stackoverflow.com/questions/797 ... ails-to-de
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Php»