Skip to content
This repository was archived by the owner on Jan 21, 2022. It is now read-only.

Commit 72686a1

Browse files
author
Raúl Kripalani
authored
Introduce the concept of 'entity' in decoded TX. (#65)
An entity groups related ERC standards, providing an abstraction on what kind of concept they refer to. In this way, different token interfaces can co-exist while making it easy to filter for all token transactions in a block, regardless of the underlying ERC interface (e.g. ERC20, ERC777 or ERC20+ERC777). Resolves #58.
1 parent 5ce6309 commit 72686a1

File tree

9 files changed

+66
-20
lines changed

9 files changed

+66
-20
lines changed

.prettierignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1+
src/abi/*.json
12
src/__tests__/data
2-
src/abi/
33
dist/

src/abi/README.md

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
## What's here?
2+
3+
This directory contains the ABIs (Application Binary Interfaces) for all the contract types ethql supports.
4+
5+
We classify supported ABIs in two types:
6+
7+
- Entity: introduces a new application-level concept.
8+
- Extension: enhances an existing entity with new or modified behaviour. Changes introduced could be public (visible on
9+
the ABI) or private.
10+
11+
## Supported ABIs
12+
13+
| Standard | Type | Entity | Specification | Comments |
14+
| -------- | --------- | ------ | ------------- | --------------------------------------------------------------- |
15+
| ERC20 | Entity |  Token | [link][1] | |
16+
| ERC223 | Extension |  Token | [link][2] | Private ERC20 implementation change. No action needed in ethql. |
17+
18+
## ethql naming scheme
19+
20+
When it comes to transaction decoding and transaction logs, ethql types names explicitly mention the ERC standard of
21+
entity they refer to. Normally this is the ERC that introduced the entity in the first place.
22+
23+
For example, in the case of ERC20 tokens: `ERC20TokenTransfer`, `ERC20TokenApproval`. This helps avoid ambiguity when
24+
more than one standard exists for the same entity class, e.g. ERC777 in the case of tokens.
25+
26+
Typed queries (e.g. block -> tokenTransfers) may not refer to specific standards, instead conflating transactions and
27+
logs pertaining to several standards that relate to the same entity.
28+
29+
[1]: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
30+
[2]: https://github.com/ethereum/EIPs/issues/223

src/schema/core.graphql

+5
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,12 @@ input TransactionFilter {
196196
contractCreation: Boolean
197197
}
198198

199+
enum Entity {
200+
token
201+
}
202+
199203
interface DecodedTransaction {
204+
entity: Entity
200205
standard: String
201206
operation: String
202207
}

src/schema/erc20.graphql

+5-12
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,12 @@
1-
# import Account, DecodedTransaction from "core.graphql"
2-
3-
type TokenContract {
4-
account: Account
5-
symbol: String
6-
totalSupply: Long
7-
}
1+
# import Account, DecodedTransaction, Entity from "core.graphql"
2+
# import * from "token.graphql"
83

94
interface ERC20Transaction {
105
tokenContract: TokenContract
116
}
127

13-
type TokenHolder {
14-
account: Account!
15-
tokenBalance: Long
16-
}
17-
188
type ERC20Transfer implements DecodedTransaction & ERC20Transaction {
9+
entity: Entity
1910
standard: String
2011
operation: String
2112
from: TokenHolder
@@ -25,6 +16,7 @@ type ERC20Transfer implements DecodedTransaction & ERC20Transaction {
2516
}
2617

2718
type ERC20TransferFrom implements DecodedTransaction & ERC20Transaction {
19+
entity: Entity
2820
standard: String
2921
operation: String
3022
from: TokenHolder
@@ -35,6 +27,7 @@ type ERC20TransferFrom implements DecodedTransaction & ERC20Transaction {
3527
}
3628

3729
type ERC20Approve implements DecodedTransaction {
30+
entity: Entity
3831
standard: String
3932
operation: String
4033
from: TokenHolder

src/schema/token.graphql

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
type TokenHolder {
2+
account: Account!
3+
tokenBalance: Long
4+
}
5+
6+
type TokenContract {
7+
account: Account
8+
symbol: String
9+
totalSupply: Long
10+
}

src/txdec/decoders/Erc20.ts renamed to src/txdec/decoders/Erc20Token.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,10 @@ type Erc20Bindings = {
7373
};
7474

7575
/**
76-
* ERC20 transaction decoder.
76+
* ERC20 token transaction decoder.
7777
*/
78-
class Erc20 implements TxDecoderDefinition<Erc20Bindings> {
78+
class Erc20Token implements TxDecoderDefinition<Erc20Bindings> {
79+
public readonly entity = 'token';
7980
public readonly standard = 'ERC20';
8081
public readonly decoder = createAbiDecoder(__dirname + '../../../abi/erc20.json');
8182

@@ -118,4 +119,4 @@ class Erc20 implements TxDecoderDefinition<Erc20Bindings> {
118119
};
119120
}
120121

121-
export default Erc20;
122+
export default Erc20Token;

src/txdec/engines/SimpleTxDecodingEngine.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class SimpleTxDecodingEngine implements TxDecodingEngine {
1717
* Decodes the transaction as a known type, or returns undefined if unable to.
1818
* @param tx The transaction to decode.
1919
*/
20-
public decodeTransaction<T extends DecodedTx>(tx: EthqlTransaction, context: EthqlContext): T | undefined {
20+
public decodeTransaction(tx: EthqlTransaction, context: EthqlContext): DecodedTx | undefined {
2121
const { inputData } = tx;
2222
if (!inputData || inputData === '0x') {
2323
return;
@@ -29,6 +29,7 @@ class SimpleTxDecodingEngine implements TxDecodingEngine {
2929
return {
3030
standard: txType.standard,
3131
operation: decoded.name,
32+
entity: txType.entity,
3233
__typename: `${txType.standard}${_.upperFirst(decoded.name)}`,
3334
...txType.transformers[decoded.name](decoded, tx, context),
3435
};

src/txdec/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import Erc20 from './decoders/Erc20';
1+
import Erc20Token from './decoders/Erc20Token';
22
import { SimpleTxDecodingEngine } from './engines/SimpleTxDecodingEngine';
33
import { TxDecodingEngine } from './types';
44

55
// Create the engine.
66
const engine = new SimpleTxDecodingEngine();
77

88
// Register all decoders.
9-
engine.register(new Erc20());
9+
engine.register(new Erc20Token());
1010

1111
// Export the engine, making only the decodeTransaction method visible.
1212
export default engine as Pick<TxDecodingEngine, 'decodeTransaction'>;

src/txdec/types.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import EthqlTransaction from '../model/core/EthqlTransaction';
22
import { EthqlContext } from '../model/EthqlContext';
33

4+
// Defines the entity to which the standard belongs.
5+
// As we support new standards, this union type will expand.
6+
type Entity = 'token' | undefined;
7+
48
/**
59
* A definition for a transaction decoder, where TBindings is a dictionary of ABI
610
* function names mapped to their decoded types, and transformers is a dictionary of
711
* functions that transform the raw transaction into a typed transaction, for each function
812
* in the ABI.
913
*/
1014
export interface TxDecoderDefinition<TBindings> {
15+
readonly entity: Entity;
1116
readonly standard: string;
1217
readonly decoder: any;
1318
readonly transformers: {
@@ -19,6 +24,7 @@ export interface TxDecoderDefinition<TBindings> {
1924
* A decoded transaction.
2025
*/
2126
export type DecodedTx = {
27+
entity: Entity;
2228
standard: string;
2329
operation: string;
2430
__typename: string;
@@ -28,5 +34,5 @@ export type DecodedTx = {
2834
* A decoding engine.
2935
*/
3036
export type TxDecodingEngine = {
31-
decodeTransaction<T extends DecodedTx>(tx: EthqlTransaction, context: EthqlContext): T;
37+
decodeTransaction(tx: EthqlTransaction, context: EthqlContext): DecodedTx;
3238
};

0 commit comments

Comments
 (0)