From 53df2ad1f826bc7c9405765ecbd767f939dee792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Galiano?= Date: Tue, 16 Jul 2019 23:36:40 -0300 Subject: [PATCH] Add support to collect data from tokens that are burnable and mintable through events --- abis/Burnable.json | 52 +++++++++++++++++++++++++++++++++++++ abis/Mintable.json | 52 +++++++++++++++++++++++++++++++++++++ schema.graphql | 55 ++++++++++++++++++++++++++++++++-------- src/mappings/registry.ts | 6 +++-- src/mappings/token.ts | 39 ++++++++++++++++++++++++---- subgraph.yaml | 38 ++++++++++++++++++++++++++- 6 files changed, 224 insertions(+), 18 deletions(-) create mode 100644 abis/Burnable.json create mode 100644 abis/Mintable.json diff --git a/abis/Burnable.json b/abis/Burnable.json new file mode 100644 index 0000000..b8abb15 --- /dev/null +++ b/abis/Burnable.json @@ -0,0 +1,52 @@ +[ + { + "constant": false, + "inputs": [ + { + "name": "value", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "burner", + "type": "address" + }, + { + "name": "value", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "burner", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event", + "_alias": "Burn" + } +] diff --git a/abis/Mintable.json b/abis/Mintable.json new file mode 100644 index 0000000..aeb9e1b --- /dev/null +++ b/abis/Mintable.json @@ -0,0 +1,52 @@ +[ + { + "constant": false, + "inputs": [ + { + "name": "to", + "type": "address" + }, + { + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "amount", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event", + "_alias": "Mint" + } +] diff --git a/schema.graphql b/schema.graphql index d1769ae..fe6a541 100644 --- a/schema.graphql +++ b/schema.graphql @@ -3,7 +3,7 @@ # type Token @entity { - id: ID! # Token address is used as ID + id: ID! # Same as token address " Token address " address: Bytes! @@ -45,7 +45,7 @@ type Token @entity { # totalBurned: BigDecimal - # events: [TokenEvent!]! @derivedFrom(field: "token") + events: [TokenEvent!]! @derivedFrom(field: "token") } @@ -53,28 +53,63 @@ type Token @entity { # Events # -interface TokenEvent { - id: ID! # Concatenation of block number and log ID - token: Bytes! # Used to derive relationships to Token +interface TokenEvent @entity { + id: ID! + token: Token! amount: BigInt! + sender: Bytes! } type BurnEvent implements TokenEvent @entity { id: ID! - token: Bytes! + + " Token address " + token: Token! + + " Quantity of tokens nurned " amount: BigInt! + + " Transaction sender address" + sender: Bytes! + + " Address of burner account " + burner: Bytes! } type MintEvent implements TokenEvent @entity { id: ID! - token: Bytes! + + " Token address " + token: Token! + + " Quantity of tokens minted " amount: BigInt! + + " Transaction sender address" + sender: Bytes! + + " Address of minter account " + minter: Bytes! + + " Address of destination account " + destination: Bytes! } type TransferEvent implements TokenEvent @entity { id: ID! - token: Bytes! - from: Bytes! - to: Bytes! + + " Token address " + token: Token! + + " Quantity of tokens transferred " amount: BigInt! + + " Transaction sender address" + sender: Bytes! + + " Address of source account " + source: Bytes! + + " Address of destination account " + destination: Bytes! } diff --git a/src/mappings/registry.ts b/src/mappings/registry.ts index 3fbfb84..b82ada1 100644 --- a/src/mappings/registry.ts +++ b/src/mappings/registry.ts @@ -2,12 +2,12 @@ import { Address, JSONValue, Value, log, ipfs } from '@graphprotocol/graph-ts' import { Token } from '../../generated/schema' import { Unknown } from '../../generated/TokenRegistry/TokenRegistry' -import { StandardToken } from '../../generated/TokenRegistry/templates' +import { BurnableToken, MintableToken, StandardToken } from '../../generated/TokenRegistry/templates' let REGISTRY_HASH = 'QmXuhRkxh7y6Gi1ZR8rEUWthcdKNWNbiEMpwzWpnMCRX6E' export function initRegistry(event: Unknown): void { - log.warning('Initializing token registry, block={}', [event.block.number.toString()]) + log.debug('Initializing token registry, block={}', [event.block.number.toString()]) ipfs.mapJSON(REGISTRY_HASH, 'createToken', Value.fromString('')) } @@ -47,6 +47,8 @@ export function createToken(value: JSONValue, userData: Value): void { // Start indexing token events StandardToken.create(address) + BurnableToken.create(address) + MintableToken.create(address) } else { log.warning('Token {} already in registry', [address.toHex()]) } diff --git a/src/mappings/token.ts b/src/mappings/token.ts index 0d98f30..8a2ec4e 100644 --- a/src/mappings/token.ts +++ b/src/mappings/token.ts @@ -1,16 +1,45 @@ import { log } from '@graphprotocol/graph-ts' import * as schema from '../../generated/schema' + import { Transfer } from '../../generated/TokenRegistry/templates/StandardToken/ERC20' +import { Burn } from '../../generated/TokenRegistry/templates/BurnableToken/Burnable' +import { Mint } from '../../generated/TokenRegistry/templates/MintableToken/Mintable' export function handleTransfer(event: Transfer): void { - log.warning('Handling token transfer, address={}', [event.address.toHex()]) + log.debug('Handling token transfer, address={}', [event.address.toHex()]) - let entity = new schema.TransferEvent(event.transaction.hash.toString() + '-' + event.logIndex.toString()) - entity.token = event.address - entity.from = event.params.from - entity.to = event.params.to + let entity = new schema.TransferEvent(event.transaction.hash.toHex() + '-' + event.logIndex.toString()) + entity.token = event.address.toHex() entity.amount = event.params.value + entity.sender = event.params.from + entity.source = event.params.from + entity.destination = event.params.to + + entity.save() +} + +export function handleBurn(event: Burn): void { + log.debug('Handling token burn, address={}', [event.address.toHex()]) + + let entity = new schema.BurnEvent(event.transaction.hash.toHex() + '-' + event.logIndex.toString()) + entity.token = event.address.toHex() + entity.amount = event.params.value + entity.sender = event.transaction.from + entity.burner = event.params.burner + + entity.save() +} + +export function handleMint(event: Mint): void { + log.debug('Handling token mint, address={}', [event.address.toHex()]) + + let entity = new schema.MintEvent(event.transaction.hash.toHex() + '-' + event.logIndex.toString()) + entity.token = event.address.toHex() + entity.amount = event.params.amount + entity.sender = event.transaction.from + entity.destination = event.params.to + entity.minter = event.transaction.from entity.save() } diff --git a/subgraph.yaml b/subgraph.yaml index 3748811..28cf559 100644 --- a/subgraph.yaml +++ b/subgraph.yaml @@ -6,8 +6,8 @@ dataSources: kind: ethereum/contract network: mainnet source: - address: '0x7f751820be4b1e44464268c425af6095995e045a' abi: TokenRegistry + address: '0x7f751820be4b1e44464268c425af6095995e045a' mapping: kind: ethereum/events apiVersion: 0.0.3 @@ -41,3 +41,39 @@ dataSources: eventHandlers: - event: Transfer(indexed address,indexed address,uint256) handler: handleTransfer + - name: BurnableToken + kind: ethereum/contract + network: mainnet + source: + abi: Burnable + mapping: + kind: ethereum/events + apiVersion: 0.0.3 + language: wasm/assemblyscript + file: ./src/mappings/token.ts + entities: + - BurnEvent + abis: + - name: Burnable + file: ./abis/Burnable.json + eventHandlers: + - event: Burn(indexed address,uint256) + handler: handleBurn + - name: MintableToken + kind: ethereum/contract + network: mainnet + source: + abi: Mintable + mapping: + kind: ethereum/events + apiVersion: 0.0.3 + language: wasm/assemblyscript + file: ./src/mappings/token.ts + entities: + - MintEvent + abis: + - name: Mintable + file: ./abis/Mintable.json + eventHandlers: + - event: Mint(indexed address,uint256) + handler: handleMint