From ed7ec5665ad475cc8086cc64f72bbfff8648eab9 Mon Sep 17 00:00:00 2001 From: Anthony Guerrera Date: Sun, 23 May 2021 15:56:51 +1000 Subject: [PATCH 1/5] Fixes dynamic length event data processing The current source does not currently process events containing dynamic bytes properly. These changes add a corrected offset when handling dynamic bytes. --- src/Abi.php | 2 +- src/DataType/EthBytes.php | 2 +- src/Event.php | 6 ++++-- src/RLP/Rlp.php | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Abi.php b/src/Abi.php index 3e3870f..b2e6259 100644 --- a/src/Abi.php +++ b/src/Abi.php @@ -109,7 +109,7 @@ public static function decode(array $params, string $msgData) } elseif ($lengthType === 'dynamic') { // Dynamic length type. - $offsetInChars = 2 * Rlp::getByteValueAtOffsetPos($msgData, $pos); + $offsetInChars = 2 * Rlp::getByteValueAt($msgData, $pos); $rlpDecoded = Rlp::decode(substr($msgData, $offsetInChars)); if (count($rlpDecoded) === 1) { diff --git a/src/DataType/EthBytes.php b/src/DataType/EthBytes.php index cb97aed..7928100 100644 --- a/src/DataType/EthBytes.php +++ b/src/DataType/EthBytes.php @@ -32,7 +32,7 @@ class EthBytes extends EthD */ public function validate($val, array $params) { - if (!ctype_xdigit($this->removeHexPrefix($val))) { + if (!ctype_xdigit($this->removeHexPrefix($val)) && $this->removeHexPrefix($val) != '') { throw new \InvalidArgumentException( 'Value of dynamic ABI type is not a valid hex string.' ); diff --git a/src/Event.php b/src/Event.php index ce0eddc..3abcf64 100644 --- a/src/Event.php +++ b/src/Event.php @@ -39,13 +39,15 @@ public function decode(FilterChange $filterChange) { // Removing topic[0]. Topic[1-n] are indexed values. $indexedValues = array_slice($filterChange->topics, 1); + $offset = 0; - foreach ($this->inputs as $i => $param) { + foreach ($this->inputs as $i => $param) { if ($param->indexed) { - $values[$param->name] = $indexedValues[$i]->convertByAbi($param->type); + $values[$param->name] = $indexedValues[$i - $offset]->convertByAbi($param->type); } else { $abiDecode[] = $param; + $offset++; } } diff --git a/src/RLP/Rlp.php b/src/RLP/Rlp.php index 8fa4eb1..8a657eb 100644 --- a/src/RLP/Rlp.php +++ b/src/RLP/Rlp.php @@ -282,7 +282,7 @@ private static function charLength(string $hex) return 2 * hexdec($hex); } - protected static function getByteValueAt(string $msgData, int $pos) + public static function getByteValueAt(string $msgData, int $pos) { return self::byteLength(substr($msgData, $pos, 64)); } From 4d5375536a937bdc36abda7e73e94c19d7f9e471 Mon Sep 17 00:00:00 2001 From: Anthony Guerrera Date: Sun, 23 May 2021 16:01:34 +1000 Subject: [PATCH 2/5] Adds missing eth_getLogs action Adds a missing action so the eth_getLogs method is handled correctly. Fixes typo in \Ethereum\Datatype\\ -> \Ethereum\DataType\ so classes are correctly assigned. --- src/Ethereum.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Ethereum.php b/src/Ethereum.php index 28df205..352c26d 100644 --- a/src/Ethereum.php +++ b/src/Ethereum.php @@ -7,6 +7,7 @@ use Exception; use Ethereum\DataType\EthD; use Ethereum\DataType\EthD32; +use Ethereum\DataType\EthB; use Ethereum\EcRecover; use Ethereum\DataType\FilterChange; @@ -286,7 +287,7 @@ private function createReturnValue($value, string $return_type_class, string $me elseif (!$is_primitive) { if ($array_val) { - if ($method === 'eth_getFilterChanges') { + if ($method === 'eth_getFilterChanges' || $method === 'eth_getLogs') { // Only be [FilterChange| D32] $return = $this->handleFilterChangeValues($value); } @@ -428,7 +429,7 @@ protected static function handleFilterChangeValues(array $values) { if (substr($type, 0, 1) === '[') { // param is an array. E.g topics. - $className = '\Ethereum\Datatype\\' . str_replace(['[', ']'], '', $type); + $className = '\Ethereum\DataType\\' . str_replace(['[', ']'], '', $type); $sub = []; foreach ($val[$key] as $subVal) { $sub[] = new $className($subVal); @@ -438,7 +439,7 @@ protected static function handleFilterChangeValues(array $values) { // @todo We'll need to decode the ABI of the values too! } else { - $className = '\Ethereum\Datatype\\' . $type; + $className = '\Ethereum\DataType\\' . $type; $processed[] = isset($val[$key]) ? new $className($val[$key]) : null; } } From 1eac37366fb8fad90d6b108641a56071fc19ac5e Mon Sep 17 00:00:00 2001 From: Anthony Guerrera Date: Sun, 23 May 2021 16:04:21 +1000 Subject: [PATCH 3/5] Optional eventHandle bool arg for processLog Only call the user function when eventHandle is true. Allows for $event to be passed without being used in a call. --- src/SmartContract.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/SmartContract.php b/src/SmartContract.php index c0eeb33..e9688ff 100644 --- a/src/SmartContract.php +++ b/src/SmartContract.php @@ -101,7 +101,7 @@ public function __call(string $method, array $args) * * @return \Ethereum\EmittedEvent with emitted Data. */ - public function processLog(FilterChange $filterChange) { + public function processLog(FilterChange $filterChange, $eventHandle = true) { if ($filterChange->address->hexVal() !== $this->contractAddress) { return null; @@ -114,8 +114,10 @@ public function processLog(FilterChange $filterChange) { // We have a relevant event. $event = new EmittedEvent($this->events[$topic], $filterChange, $transaction); // Process onEventName handler. - if (method_exists($this, $event->getHandler())) { - call_user_func([$this, $event->getHandler()], $event); + if ($eventHandle) { + if (method_exists($this, $event->getHandler())) { + call_user_func([$this, $event->getHandler()], $event); + } } return $event; } From c40eb10d928d9fa2475dca481caefe959e701b93 Mon Sep 17 00:00:00 2001 From: Anthony Guerrera Date: Sun, 23 May 2021 16:21:04 +1000 Subject: [PATCH 4/5] Removed whitespaces --- src/Event.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Event.php b/src/Event.php index 3abcf64..5271591 100644 --- a/src/Event.php +++ b/src/Event.php @@ -41,7 +41,7 @@ public function decode(FilterChange $filterChange) { $indexedValues = array_slice($filterChange->topics, 1); $offset = 0; - foreach ($this->inputs as $i => $param) { + foreach ($this->inputs as $i => $param) { if ($param->indexed) { $values[$param->name] = $indexedValues[$i - $offset]->convertByAbi($param->type); } From f9d08993ea1aa5f8beab835fe4dd1842880575d5 Mon Sep 17 00:00:00 2001 From: Anthony Guerrera Date: Wed, 16 Jun 2021 18:58:48 +1000 Subject: [PATCH 5/5] Updated processLog comment micro-change --- src/SmartContract.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SmartContract.php b/src/SmartContract.php index e9688ff..f86e62b 100644 --- a/src/SmartContract.php +++ b/src/SmartContract.php @@ -97,6 +97,9 @@ public function __call(string $method, array $args) /** * @param \Ethereum\DataType\FilterChange $filterChange + * + * @param boolean $eventHandle + * * @throws \Exception * * @return \Ethereum\EmittedEvent with emitted Data.