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\Str;
|
||||
use Web3\Contracts\Types\Uinteger;
|
||||
use Web3\Contracts\Types\Tuple;
|
||||
use Web3\Validators\AddressValidator;
|
||||
use Web3\Validators\HexValidator;
|
||||
use Web3\Validators\StringValidator;
|
||||
@ -154,15 +155,7 @@ class Contract
|
||||
}
|
||||
$this->abi = $abiArray;
|
||||
$this->eth = new Eth($this->provider);
|
||||
$this->ethabi = new Ethabi([
|
||||
'address' => new Address,
|
||||
'bool' => new Boolean,
|
||||
'bytes' => new Bytes,
|
||||
'dynamicBytes' => new DynamicBytes,
|
||||
'int' => new Integer,
|
||||
'string' => new Str,
|
||||
'uint' => new Uinteger,
|
||||
]);
|
||||
$this->ethabi = Ethabi::factory();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,6 +13,14 @@ namespace Web3\Contracts;
|
||||
|
||||
use InvalidArgumentException;
|
||||
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\Formatters\IntegerFormatter;
|
||||
|
||||
@ -55,6 +63,20 @@ class Ethabi
|
||||
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
|
||||
*
|
||||
@ -235,11 +257,13 @@ class Ethabi
|
||||
$param = mb_strtolower(Utils::stripZero($param));
|
||||
|
||||
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]);
|
||||
} else {
|
||||
$result[$i] = $solidityTypes[$i]->decode($param, $offsets[$i], $types[$i]);
|
||||
}
|
||||
|
||||
$output_type_hint = $outputTypes['outputs'][$i] ?? false;
|
||||
$name = $outputTypes['outputs'][$i]['name'] ?? "";
|
||||
if (empty($name))
|
||||
$name = $i;
|
||||
$result[$name] = $solidityTypes[$i]->decode($param, $offsets[$i], $types[$i], $output_type_hint);
|
||||
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
@ -229,7 +229,7 @@ class SolidityType
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public function decode($value, $offset, $name)
|
||||
public function decode($value, $offset, $name, $output_type_hint = false)
|
||||
{
|
||||
if ($this->isDynamicArray($name)) {
|
||||
$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();
|
||||
$roundedLength = floor(($length + 31) / 32);
|
||||
$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);
|
||||
$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