/
ContractEvent.php
130 lines (105 loc) · 3.06 KB
/
ContractEvent.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?php
namespace Enjin\BlockchainTools\Ethereum\ABI\Contract;
use Enjin\BlockchainTools\Ethereum\ABI\ContractEventDecoder;
use Enjin\BlockchainTools\Ethereum\ABI\DataBlockDecoder;
use Enjin\BlockchainTools\Ethereum\ABI\Serializer;
use Enjin\BlockchainTools\HexConverter;
use InvalidArgumentException;
use kornrunner\Keccak;
class ContractEvent
{
/**
* @var string
*/
protected $name;
/**
* @var bool
*/
protected $anonymous;
/**
* @var array
*/
protected $inputs = [];
protected $topic;
/**
* @var Serializer
*/
protected $serializer;
public function __construct(array $event, Serializer $serializer = null)
{
$this->name = $event['name'];
$this->anonymous = $event['anonymous'] ?? false;
$this->serializer = $serializer ?: Serializer::makeDefault();
$inputs = $event['inputs'] ?? [];
foreach ($inputs as $input) {
$inputName = $input['name'];
$this->inputs[$inputName] = $input;
}
}
public function name(): string
{
return $this->name;
}
public function input(string $name): ContractEventInput
{
if (!array_key_exists($name, $this->inputs)) {
throw new InvalidArgumentException('invalid input name: ' . $name . ' for Contract Event: ' . $this->name());
}
return new ContractEventInput($this->inputs[$name]);
}
public function inputs(): array
{
return array_map(function (array $input) {
return new ContractEventInput($input);
}, $this->inputs);
}
public function anonymous(): bool
{
return $this->anonymous;
}
public function signature(): string
{
$args = [];
/** @var ContractEventInput $input */
foreach ($this->inputs() as $input) {
$args[] = $input->type();
}
return $this->name() . '(' . implode(',', $args) . ')';
}
public function signatureTopic(): string
{
if (!$this->topic) {
$hash = Keccak::hash($this->signature(), 256);
$this->topic = HexConverter::prefix($hash);
}
return $this->topic;
}
public function decodeInput(array $topics, string $data): DataBlockDecoder
{
$decoder = new ContractEventDecoder($this->serializer);
return $decoder->decodeInput($this, $topics, $data);
}
public function serializer(): Serializer
{
return $this->serializer;
}
public function toArray(): array
{
return [
'name' => $this->name,
'type' => 'event',
'anonymous' => $this->anonymous,
'inputs' => $this->contractValuesToArray($this->inputs()),
];
}
protected function contractValuesToArray(array $values): array
{
$mapped = array_map(function (ContractFunctionValueType $item) {
return [
'name' => $item->name(),
'type' => $item->type(),
];
}, $values);
return array_values($mapped);
}
}