Adds ability to pass requested data layout to decoders and tuple support.
This commit is contained in:
parent
cede0cc410
commit
c8e955a723
@ -26,6 +26,7 @@ use Web3\Contracts\Types\DynamicBytes;
|
|||||||
use Web3\Contracts\Types\Integer;
|
use Web3\Contracts\Types\Integer;
|
||||||
use Web3\Contracts\Types\Str;
|
use Web3\Contracts\Types\Str;
|
||||||
use Web3\Contracts\Types\Uinteger;
|
use Web3\Contracts\Types\Uinteger;
|
||||||
|
use Web3\Contracts\Types\Tuple;
|
||||||
use Web3\Validators\AddressValidator;
|
use Web3\Validators\AddressValidator;
|
||||||
use Web3\Validators\HexValidator;
|
use Web3\Validators\HexValidator;
|
||||||
use Web3\Validators\StringValidator;
|
use Web3\Validators\StringValidator;
|
||||||
@ -154,15 +155,7 @@ class Contract
|
|||||||
}
|
}
|
||||||
$this->abi = $abiArray;
|
$this->abi = $abiArray;
|
||||||
$this->eth = new Eth($this->provider);
|
$this->eth = new Eth($this->provider);
|
||||||
$this->ethabi = new Ethabi([
|
$this->ethabi = Ethabi::factory();
|
||||||
'address' => new Address,
|
|
||||||
'bool' => new Boolean,
|
|
||||||
'bytes' => new Bytes,
|
|
||||||
'dynamicBytes' => new DynamicBytes,
|
|
||||||
'int' => new Integer,
|
|
||||||
'string' => new Str,
|
|
||||||
'uint' => new Uinteger,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,6 +13,14 @@ namespace Web3\Contracts;
|
|||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
use Web3\Contracts\Types\Address;
|
||||||
|
use Web3\Contracts\Types\Boolean;
|
||||||
|
use Web3\Contracts\Types\Bytes;
|
||||||
|
use Web3\Contracts\Types\DynamicBytes;
|
||||||
|
use Web3\Contracts\Types\Integer;
|
||||||
|
use Web3\Contracts\Types\Str;
|
||||||
|
use Web3\Contracts\Types\Tuple;
|
||||||
|
use Web3\Contracts\Types\Uinteger;
|
||||||
use Web3\Utils;
|
use Web3\Utils;
|
||||||
use Web3\Formatters\IntegerFormatter;
|
use Web3\Formatters\IntegerFormatter;
|
||||||
|
|
||||||
@ -55,6 +63,20 @@ class Ethabi
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function factory()
|
||||||
|
{
|
||||||
|
return new Ethabi([
|
||||||
|
'address' => new Address,
|
||||||
|
'bool' => new Boolean,
|
||||||
|
'bytes' => new Bytes,
|
||||||
|
'dynamicBytes' => new DynamicBytes,
|
||||||
|
'int' => new Integer,
|
||||||
|
'string' => new Str,
|
||||||
|
'uint' => new Uinteger,
|
||||||
|
'tuple' => new Tuple
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set
|
* set
|
||||||
*
|
*
|
||||||
@ -235,11 +257,13 @@ class Ethabi
|
|||||||
$param = mb_strtolower(Utils::stripZero($param));
|
$param = mb_strtolower(Utils::stripZero($param));
|
||||||
|
|
||||||
for ($i=0; $i<$typesLength; $i++) {
|
for ($i=0; $i<$typesLength; $i++) {
|
||||||
if (isset($outputTypes['outputs'][$i]['name']) && empty($outputTypes['outputs'][$i]['name']) === false) {
|
|
||||||
$result[$outputTypes['outputs'][$i]['name']] = $solidityTypes[$i]->decode($param, $offsets[$i], $types[$i]);
|
$output_type_hint = $outputTypes['outputs'][$i] ?? false;
|
||||||
} else {
|
$name = $outputTypes['outputs'][$i]['name'] ?? "";
|
||||||
$result[$i] = $solidityTypes[$i]->decode($param, $offsets[$i], $types[$i]);
|
if (empty($name))
|
||||||
}
|
$name = $i;
|
||||||
|
$result[$name] = $solidityTypes[$i]->decode($param, $offsets[$i], $types[$i], $output_type_hint);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
|
@ -229,7 +229,7 @@ class SolidityType
|
|||||||
* @param string $name
|
* @param string $name
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function decode($value, $offset, $name)
|
public function decode($value, $offset, $name, $output_type_hint = false)
|
||||||
{
|
{
|
||||||
if ($this->isDynamicArray($name)) {
|
if ($this->isDynamicArray($name)) {
|
||||||
$arrayOffset = (int) Utils::toBn('0x' . mb_substr($value, $offset * 2, 64))->toString();
|
$arrayOffset = (int) Utils::toBn('0x' . mb_substr($value, $offset * 2, 64))->toString();
|
||||||
@ -263,7 +263,7 @@ class SolidityType
|
|||||||
$length = (int) Utils::toBn('0x' . mb_substr($value, $dynamicOffset * 2, 64))->toString();
|
$length = (int) Utils::toBn('0x' . mb_substr($value, $dynamicOffset * 2, 64))->toString();
|
||||||
$roundedLength = floor(($length + 31) / 32);
|
$roundedLength = floor(($length + 31) / 32);
|
||||||
$param = mb_substr($value, $dynamicOffset * 2, ( 1 + $roundedLength) * 64);
|
$param = mb_substr($value, $dynamicOffset * 2, ( 1 + $roundedLength) * 64);
|
||||||
return $this->outputFormat($param, $name);
|
return $this->outputFormat($param, $name, $output_type_hint);
|
||||||
}
|
}
|
||||||
$length = $this->staticPartLength($name);
|
$length = $this->staticPartLength($name);
|
||||||
$param = mb_substr($value, $offset * 2, $length * 2);
|
$param = mb_substr($value, $offset * 2, $length * 2);
|
||||||
|
39
src/Contracts/Types/Tuple.php
Normal file
39
src/Contracts/Types/Tuple.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Web3\Contracts\Types;
|
||||||
|
|
||||||
|
use Web3\Contracts\Ethabi;
|
||||||
|
use Web3\Contracts\SolidityType;
|
||||||
|
use Web3\Contracts\Types\IType;
|
||||||
|
|
||||||
|
class Tuple extends SolidityType implements IType
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isType($name)
|
||||||
|
{
|
||||||
|
return (preg_match('/^tuple(\[([0-9]*)\])*$/', $name) === 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isDynamicType()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function inputFormat($value, $name)
|
||||||
|
{
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function outputFormat($value, $name, $output_type_hint)
|
||||||
|
{
|
||||||
|
$ethabi = Ethabi::factory();
|
||||||
|
$types = $output_type_hint['components'] ?? false;
|
||||||
|
if (!is_array($types)) {
|
||||||
|
throw new InvalidArgumentException('Output type is required for tuple.');
|
||||||
|
}
|
||||||
|
return $ethabi->decodeParameters(['outputs'=>$types], $value);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user