diff --git a/src/Contract.php b/src/Contract.php index 87ad1fc..7f47187 100644 --- a/src/Contract.php +++ b/src/Contract.php @@ -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(); } /** diff --git a/src/Contracts/Ethabi.php b/src/Contracts/Ethabi.php index 694a563..092426e 100644 --- a/src/Contracts/Ethabi.php +++ b/src/Contracts/Ethabi.php @@ -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; diff --git a/src/Contracts/SolidityType.php b/src/Contracts/SolidityType.php index 5adf572..b7498e6 100644 --- a/src/Contracts/SolidityType.php +++ b/src/Contracts/SolidityType.php @@ -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); diff --git a/src/Contracts/Types/Tuple.php b/src/Contracts/Types/Tuple.php new file mode 100644 index 0000000..7c52b68 --- /dev/null +++ b/src/Contracts/Types/Tuple.php @@ -0,0 +1,39 @@ +decodeParameters(['outputs'=>$types], $value); + } +} \ No newline at end of file