Merge 496680050c
into cede0cc410
This commit is contained in:
commit
f3c5751057
@ -32,6 +32,7 @@ use Web3\Validators\StringValidator;
|
|||||||
use Web3\Validators\TagValidator;
|
use Web3\Validators\TagValidator;
|
||||||
use Web3\Validators\QuantityValidator;
|
use Web3\Validators\QuantityValidator;
|
||||||
use Web3\Formatters\AddressFormatter;
|
use Web3\Formatters\AddressFormatter;
|
||||||
|
use Web3\Contracts\Types\Tuple;
|
||||||
|
|
||||||
class Contract
|
class Contract
|
||||||
{
|
{
|
||||||
@ -162,6 +163,7 @@ class Contract
|
|||||||
'int' => new Integer,
|
'int' => new Integer,
|
||||||
'string' => new Str,
|
'string' => new Str,
|
||||||
'uint' => new Uinteger,
|
'uint' => new Uinteger,
|
||||||
|
'tuple' => new Tuple,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,9 +238,13 @@ class Ethabi
|
|||||||
if (isset($outputTypes['outputs'][$i]['name']) && empty($outputTypes['outputs'][$i]['name']) === false) {
|
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]);
|
$result[$outputTypes['outputs'][$i]['name']] = $solidityTypes[$i]->decode($param, $offsets[$i], $types[$i]);
|
||||||
} else {
|
} else {
|
||||||
|
if($types[$i] == "tuple"){
|
||||||
|
$result[$i] = $solidityTypes[$i]->decodeTuple($outputTypes['outputs'][$i],$param);
|
||||||
|
}else{
|
||||||
$result[$i] = $solidityTypes[$i]->decode($param, $offsets[$i], $types[$i]);
|
$result[$i] = $solidityTypes[$i]->decode($param, $offsets[$i], $types[$i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,21 @@ namespace Web3\Contracts;
|
|||||||
|
|
||||||
use Web3\Utils;
|
use Web3\Utils;
|
||||||
use Web3\Formatters\IntegerFormatter;
|
use Web3\Formatters\IntegerFormatter;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
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\Uinteger;
|
||||||
|
use Web3\Contracts\Types\Tuple;
|
||||||
|
|
||||||
|
|
||||||
class SolidityType
|
class SolidityType
|
||||||
{
|
{
|
||||||
|
private array $types = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* construct
|
* construct
|
||||||
*
|
*
|
||||||
@ -23,6 +35,27 @@ class SolidityType
|
|||||||
*/
|
*/
|
||||||
// public function __construct() {}
|
// public function __construct() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set types
|
||||||
|
*/
|
||||||
|
private function setTypes()
|
||||||
|
{
|
||||||
|
if(!empty($this->types)){
|
||||||
|
return $this->types;
|
||||||
|
}
|
||||||
|
$this->types = [
|
||||||
|
'address' => new Address,
|
||||||
|
'bool' => new Boolean,
|
||||||
|
'bytes' => new Bytes,
|
||||||
|
'dynamicBytes' => new DynamicBytes,
|
||||||
|
'int' => new Integer,
|
||||||
|
'string' => new Str,
|
||||||
|
'uint' => new Uinteger,
|
||||||
|
'tuple' => new Tuple,
|
||||||
|
];
|
||||||
|
return $this->types;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get
|
* get
|
||||||
*
|
*
|
||||||
@ -270,4 +303,81 @@ class SolidityType
|
|||||||
|
|
||||||
return $this->outputFormat($param, $name);
|
return $this->outputFormat($param, $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* decode struct data
|
||||||
|
*
|
||||||
|
* @author abaowu <abaowu@gmail.com>
|
||||||
|
* @param array $type tuple struct
|
||||||
|
* @param mix $value tuple value
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function decodeTuple($type, $value)
|
||||||
|
{
|
||||||
|
$outputTypes = $type["components"];
|
||||||
|
$typesLength = count($outputTypes);
|
||||||
|
$solidityTypes = $this->getSolidityTypes($outputTypes);
|
||||||
|
$offsets = array_fill(0, $typesLength, 0);
|
||||||
|
|
||||||
|
for ($i=0; $i<$typesLength; $i++) {
|
||||||
|
$offsets[$i] = $solidityTypes[$i]->staticPartLength($outputTypes[$i]['type']);
|
||||||
|
}
|
||||||
|
for ($i=1; $i<$typesLength; $i++) {
|
||||||
|
$offsets[$i] += $offsets[$i - 1];
|
||||||
|
}
|
||||||
|
for ($i=0; $i<$typesLength; $i++) {
|
||||||
|
$offsets[$i] -= $solidityTypes[$i]->staticPartLength($outputTypes[$i]['type']);
|
||||||
|
}
|
||||||
|
$result = [];
|
||||||
|
$param = mb_strtolower(Utils::stripZero($value));
|
||||||
|
|
||||||
|
for ($i=0; $i<$typesLength; $i++) {
|
||||||
|
if (isset($outputTypes[$i]['name']) && empty($outputTypes[$i]['name']) === false) {
|
||||||
|
$result[$outputTypes[$i]['name']] = $solidityTypes[$i]->decode($param, $offsets[$i], $outputTypes[$i]['type']);
|
||||||
|
} else {
|
||||||
|
$result[$i] = $solidityTypes[$i]->decode($param, $offsets[$i], $outputTypes[$i]['type']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getSolidityTypes
|
||||||
|
*
|
||||||
|
* @param array $types
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getSolidityTypes($types)
|
||||||
|
{
|
||||||
|
if (!is_array($types)) {
|
||||||
|
throw new InvalidArgumentException('Types must be array');
|
||||||
|
}
|
||||||
|
$solidityTypes = array_fill(0, count($types), 0);
|
||||||
|
$this->setTypes();
|
||||||
|
|
||||||
|
foreach ($types as $key => $type) {
|
||||||
|
$match = [];
|
||||||
|
$type = $type['type'];
|
||||||
|
if (preg_match('/^([a-zA-Z]+)/', $type, $match) === 1) {
|
||||||
|
if (isset($this->types[$match[0]])) {
|
||||||
|
$className = $this->types[$match[0]];
|
||||||
|
|
||||||
|
if (call_user_func([$this->types[$match[0]], 'isType'], $type) === false) {
|
||||||
|
// check dynamic bytes
|
||||||
|
if ($match[0] === 'bytes') {
|
||||||
|
$className = $this->types['dynamicBytes'];
|
||||||
|
} else {
|
||||||
|
throw new InvalidArgumentException('Unsupport solidity parameter type: ' . $type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$solidityTypes[$key] = $className;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $solidityTypes;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
86
src/Contracts/Types/Tuple.php
Normal file
86
src/Contracts/Types/Tuple.php
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file is part of web3.php package.
|
||||||
|
*
|
||||||
|
* (c) abaowu <abaowu@gmail.com>
|
||||||
|
*
|
||||||
|
* @author abaowu <abaowu@gmail.com>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Web3\Contracts\Types;
|
||||||
|
|
||||||
|
use Web3\Contracts\SolidityType;
|
||||||
|
use Web3\Contracts\Types\IType;
|
||||||
|
|
||||||
|
class Tuple extends SolidityType implements IType
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* construct
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isType
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isType($name)
|
||||||
|
{
|
||||||
|
return (preg_match('/^tuple(\[([0-9]*)\])*$/', $name) === 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isDynamicType
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isDynamicType()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* inputFormat
|
||||||
|
* to do: iban
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @param string $name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function inputFormat($value, $name)
|
||||||
|
{
|
||||||
|
// $value = (string) $value;
|
||||||
|
|
||||||
|
// if (Utils::isAddress($value)) {
|
||||||
|
// $value = mb_strtolower($value);
|
||||||
|
|
||||||
|
// if (Utils::isZeroPrefixed($value)) {
|
||||||
|
// $value = Utils::stripZero($value);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// $value = IntegerFormatter::format($value);
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* outputFormat
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @param string $name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function outputFormat($value, $name)
|
||||||
|
{
|
||||||
|
// return '0x' . mb_substr($value, 24, 40);
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user