Skip to content

Commit

Permalink
Add Array / Tuple encoder
Browse files Browse the repository at this point in the history
  • Loading branch information
sc0Vu committed Jan 25, 2024
1 parent 8b4c5bf commit 4266d7b
Show file tree
Hide file tree
Showing 13 changed files with 728 additions and 201 deletions.
422 changes: 264 additions & 158 deletions src/Contracts/Ethabi.php

Large diffs are not rendered by default.

42 changes: 21 additions & 21 deletions src/Contracts/SolidityType.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,31 +193,31 @@ public function isDynamicType()
* encode
*
* @param mixed $value
* @param string $name
* @param mixed $name
* @return string
*/
public function encode($value, $name)
{
if ($this->isDynamicArray($name)) {
$length = count($value);
$nestedName = $this->nestedName($name);
$result = [];
$result[] = IntegerFormatter::format($length);

foreach ($value as $val) {
$result[] = $this->encode($val, $nestedName);
}
return $result;
} elseif ($this->isStaticArray($name)) {
$length = $this->staticArrayLength($name);
$nestedName = $this->nestedName($name);
$result = [];

foreach ($value as $val) {
$result[] = $this->encode($val, $nestedName);
}
return $result;
}
// if ($this->isDynamicArray($name)) {
// $length = count($value);
// $nestedName = $this->nestedName($name);
// $result = [];
// $result[] = IntegerFormatter::format($length);

// foreach ($value as $val) {
// $result[] = $this->encode($val, $nestedName);
// }
// return $result;
// } elseif ($this->isStaticArray($name)) {
// $length = $this->staticArrayLength($name);
// $nestedName = $this->nestedName($name);
// $result = [];

// foreach ($value as $val) {
// $result[] = $this->encode($val, $nestedName);
// }
// return $result;
// }
return $this->inputFormat($value, $name);
}

Expand Down
27 changes: 11 additions & 16 deletions src/Contracts/TypedDataEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@
use Web3\Utils;
use Web3\Formatters\IntegerFormatter;
use Web3\Contracts\Ethabi;
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;

class TypedDataEncoder
{
Expand Down Expand Up @@ -51,15 +44,7 @@ class TypedDataEncoder
*/
public function __construct()
{
$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 = new Ethabi();
}

/**
Expand Down Expand Up @@ -95,6 +80,16 @@ public function __set($name, $value)
return false;
}

/**
* getEthabi
*
* @return \Web3\Contracts\Ethabi
*/
public function getEthabi()
{
return $this->ethabi;
}

/**
* encodeField
*
Expand Down
2 changes: 1 addition & 1 deletion src/Contracts/Types/Address.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function __construct()
*/
public function isType($name)
{
return (preg_match('/^address(\[([0-9]*)\])*$/', $name) === 1);
return (preg_match('/^address/', $name) === 1);
}

/**
Expand Down
124 changes: 124 additions & 0 deletions src/Contracts/Types/BaseArray.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php

/**
* This file is part of web3.php package.
*
* (c) Kuan-Cheng,Lai <alk03073135@gmail.com>
*
* @author Peter Lai <alk03073135@gmail.com>
* @license MIT
*/

namespace Web3\Contracts\Types;

use InvalidArgumentException;
use Web3\Utils;
use Web3\Contracts\SolidityType;
use Web3\Contracts\Types\IType;
use Web3\Formatters\IntegerFormatter;

class BaseArray extends SolidityType implements IType
{
/**
* construct
*
* @return void
*/
public function __construct()
{
//
}

/**
* isType
*
* @param string $name
* @return bool
*/
public function isType($name)
{
return (preg_match('/(\[([0-9]*)\])/', $name) === 1);
}

/**
* isDynamicType
*
* @return bool
*/
public function isDynamicType()
{
return true;
}

/**
* encodeElements
*
* @param mixed $value
* @param string $name
* @return array
*/
public function encodeElements($value, $name)
{
if (!is_array($value)) {
throw new InvalidArgumentException('Encode value must be array');
}
$results = [];
$itemsAreDynamic = false;
foreach ($value as $key => $val) {
$results[] = $name['coders']['solidityType']->encode($val, $name['coders']);
if ($name['coders']['dynamic']) {
$itemsAreDynamic = true;
}
}
if (!$itemsAreDynamic) {
return $results;
}
$headLength = 32 * count($value);
$tailOffsets = [0];
foreach ($results as $key => $val) {
if ($key === count($results) - 1) {
break;
}
$tailOffsets[] = (int) mb_strlen($val) / 2;
}
$headChunks = [];
foreach ($tailOffsets as $offset) {
$headChunks[] = IntegerFormatter::format($headLength + $offset);
}
return array_merge($headChunks, $results);
}

/**
* inputFormat
*
* @param mixed $value
* @param string $name
* @return string
*/
public function inputFormat($value, $name)
{
return implode('', $this->encodeElements($value, $name));
}

/**
* outputFormat
*
* @param mixed $value
* @param string $name
* @return string
*/
public function outputFormat($value, $name)
{
$checkZero = str_replace('0', '', $value);

if (empty($checkZero)) {
return '0';
}
if (preg_match('/^bytes([0-9]*)/', $name, $match) === 1) {
$size = intval($match[1]);
$length = 2 * $size;
$value = mb_substr($value, 0, $length);
}
return '0x' . $value;
}
}
2 changes: 1 addition & 1 deletion src/Contracts/Types/Boolean.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function __construct()
*/
public function isType($name)
{
return (preg_match('/^bool(\[([0-9]*)\])*$/', $name) === 1);
return (preg_match('/^bool/', $name) === 1);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Contracts/Types/Bytes.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function __construct()
*/
public function isType($name)
{
return (preg_match('/^bytes([0-9]{1,})(\[([0-9]*)\])*$/', $name) === 1);
return (preg_match('/^bytes([0-9]{1,})/', $name) === 1);
}

/**
Expand Down
87 changes: 87 additions & 0 deletions src/Contracts/Types/DynamicArray.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

/**
* This file is part of web3.php package.
*
* (c) Kuan-Cheng,Lai <alk03073135@gmail.com>
*
* @author Peter Lai <alk03073135@gmail.com>
* @license MIT
*/

namespace Web3\Contracts\Types;

use InvalidArgumentException;
use Web3\Utils;
use Web3\Contracts\Types\BaseArray;
use Web3\Formatters\IntegerFormatter;

class DynamicArray extends BaseArray
{
/**
* construct
*
* @return void
*/
public function __construct()
{
//
}

/**
* isType
*
* @param string $name
* @return bool
*/
public function isType($name)
{
return (preg_match('/(\[\])/', $name) === 1);
}

/**
* isDynamicType
*
* @return bool
*/
public function isDynamicType()
{
return true;
}

/**
* inputFormat
*
* @param mixed $value
* @param string $name
* @return string
*/
public function inputFormat($value, $name)
{
$results = $this->encodeElements($value, $name);
$encodeSize = IntegerFormatter::format(count($value));
return $encodeSize . implode('', $results);
}

/**
* outputFormat
*
* @param mixed $value
* @param string $name
* @return string
*/
public function outputFormat($value, $name)
{
$checkZero = str_replace('0', '', $value);

if (empty($checkZero)) {
return '0';
}
if (preg_match('/^bytes([0-9]*)/', $name, $match) === 1) {
$size = intval($match[1]);
$length = 2 * $size;
$value = mb_substr($value, 0, $length);
}
return '0x' . $value;
}
}
2 changes: 1 addition & 1 deletion src/Contracts/Types/Integer.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function __construct()
*/
public function isType($name)
{
return (preg_match('/^int([0-9]{1,})?(\[([0-9]*)\])*$/', $name) === 1);
return (preg_match('/^int([0-9]{1,})?/', $name) === 1);
}

/**
Expand Down
Loading

0 comments on commit 4266d7b

Please sign in to comment.