From 55a73c57977d67b2e3972675e5c053d2f1fb5774 Mon Sep 17 00:00:00 2001 From: Ian Norden Date: Sun, 26 Aug 2018 21:55:09 -0500 Subject: [PATCH] work on erc20 event_triggered functionality and generic helper for log unpacking and converting. helpers.ConvertToLog and helpers.createTopics have been adjusted to be variadic to work with event logs with any number of topics. Also uncovered issue with Dai and TrueUSD that means they doesn't really conform to the ERC20 standard. this is because they named their arguments to standard events like Approval and Trasnfer differently (e.g. Approval(src address, guy address, wad uint) and Approval(owner address, spender address, value uint) instead of the standard which is Approval(tokenOwner address, spender address, tokens uint)). This causes incompatibility with generic ERC20 entities and converters for these events. --- examples/constants/constants.go | 32 ++++ .../event_triggered/converter.go | 106 +++++++++++ .../event_triggered/converter_test.go | 173 ++++++++++++++++++ .../erc20_watcher/event_triggered/entity.go | 40 ++++ .../event_triggered_suite_test.go | 27 +++ .../event_triggered/integration_test.go | 15 ++ .../erc20_watcher/event_triggered/model.go | 35 ++++ .../event_triggered/repository.go | 58 ++++++ .../event_triggered/repository_test.go | 15 ++ .../event_triggered/transformer.go | 15 ++ .../event_triggered/transformer_test.go | 15 ++ .../every_block/integration_test.go | 6 +- .../erc20_watcher/every_block/transformer.go | 7 +- .../every_block/transformer_test.go | 3 +- .../erc20_watcher/every_block/transformers.go | 4 +- examples/{erc20_watcher => generic}/config.go | 9 +- examples/generic/helpers/helpers.go | 66 +++++++ 17 files changed, 613 insertions(+), 13 deletions(-) create mode 100644 examples/erc20_watcher/event_triggered/converter.go create mode 100644 examples/erc20_watcher/event_triggered/converter_test.go create mode 100644 examples/erc20_watcher/event_triggered/entity.go create mode 100644 examples/erc20_watcher/event_triggered/event_triggered_suite_test.go create mode 100644 examples/erc20_watcher/event_triggered/integration_test.go create mode 100644 examples/erc20_watcher/event_triggered/model.go create mode 100644 examples/erc20_watcher/event_triggered/repository.go create mode 100644 examples/erc20_watcher/event_triggered/repository_test.go create mode 100644 examples/erc20_watcher/event_triggered/transformer.go create mode 100644 examples/erc20_watcher/event_triggered/transformer_test.go rename examples/{erc20_watcher => generic}/config.go (82%) create mode 100644 examples/generic/helpers/helpers.go diff --git a/examples/constants/constants.go b/examples/constants/constants.go index 646f7b29..77a9aa5e 100644 --- a/examples/constants/constants.go +++ b/examples/constants/constants.go @@ -14,10 +14,42 @@ package constants +import ( + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/vulcanize/vulcanizedb/examples/generic/helpers" + "github.com/vulcanize/vulcanizedb/pkg/geth" + "log" +) + +var err error + //Contract Addresses var DaiContractAddress = "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359" var TusdContractAddress = "0x8dd5fbCe2F6a956C3022bA3663759011Dd51e73E" //Abis + +var ParsedDaiAbi abi.ABI + var DaiAbiString = `[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"stop","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"name_","type":"bytes32"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"stopped","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"push","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"move","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"start","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"},{"name":"guy","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"wad","type":"uint256"}],"name":"pull","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"symbol_","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"}]` + +var ParsedTusdAbi abi.ABI + var TusdAbiString = `[{"constant":true,"inputs":[],"name":"burnMin","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"delegateAllowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"burnFeeFlat","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_canReceiveMintWhiteList","type":"address"},{"name":"_canBurnWhiteList","type":"address"},{"name":"_blackList","type":"address"},{"name":"_noFeesList","type":"address"}],"name":"setLists","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"}],"name":"reclaimToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newContract","type":"address"}],"name":"delegateToNewContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_transferFeeNumerator","type":"uint80"},{"name":"_transferFeeDenominator","type":"uint80"},{"name":"_mintFeeNumerator","type":"uint80"},{"name":"_mintFeeDenominator","type":"uint80"},{"name":"_mintFeeFlat","type":"uint256"},{"name":"_burnFeeNumerator","type":"uint80"},{"name":"_burnFeeDenominator","type":"uint80"},{"name":"_burnFeeFlat","type":"uint256"}],"name":"changeStakingFees","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"canReceiveMintWhiteList","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"delegatedFrom","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"},{"name":"origSender","type":"address"}],"name":"delegateApprove","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"contractAddr","type":"address"}],"name":"reclaimContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"allowances","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"delegateBalanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"origSender","type":"address"}],"name":"delegateTransferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"sheet","type":"address"}],"name":"setBalanceSheet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"},{"name":"origSender","type":"address"}],"name":"delegateIncreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"burnFeeNumerator","outputs":[{"name":"","type":"uint80"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"canBurnWhiteList","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"burnMax","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mintFeeDenominator","outputs":[{"name":"","type":"uint80"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"staker","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"setDelegatedFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"noFeesList","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newMin","type":"uint256"},{"name":"newMax","type":"uint256"}],"name":"changeBurnBounds","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"delegateTotalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"balances","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"}],"name":"changeName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"mintFeeNumerator","outputs":[{"name":"","type":"uint80"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"transferFeeNumerator","outputs":[{"name":"","type":"uint80"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"},{"name":"origSender","type":"address"}],"name":"delegateDecreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"origSender","type":"address"}],"name":"delegateTransfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"reclaimEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newStaker","type":"address"}],"name":"changeStaker","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"wipeBlacklistedAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from_","type":"address"},{"name":"value_","type":"uint256"},{"name":"data_","type":"bytes"}],"name":"tokenFallback","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"burnFeeDenominator","outputs":[{"name":"","type":"uint80"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"delegate","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"blackList","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"transferFeeDenominator","outputs":[{"name":"","type":"uint80"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mintFeeFlat","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pendingOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sheet","type":"address"}],"name":"setAllowanceSheet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":false,"stateMutability":"nonpayable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newMin","type":"uint256"},{"indexed":false,"name":"newMax","type":"uint256"}],"name":"ChangeBurnBoundsEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"},{"indexed":false,"name":"balance","type":"uint256"}],"name":"WipedAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"newContract","type":"address"}],"name":"DelegatedTo","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"burner","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]` + +// Parsed abi initialization +func init() { + ParsedDaiAbi, err = geth.ParseAbi(DaiAbiString) + if err != nil { + log.Fatal("constants: unable to parse dai abi") + } + + ParsedTusdAbi, err = geth.ParseAbi(TusdAbiString) + if err != nil { + log.Fatal("constants: unable to parse true usd abi") + } +} + +// Hashed event signatures +var TransferEventSignature = helpers.GenerateSignature("Transfer(address,address,uint)") +var ApprovalEventSignature = helpers.GenerateSignature("Approval(address,address,uint)") diff --git a/examples/erc20_watcher/event_triggered/converter.go b/examples/erc20_watcher/event_triggered/converter.go new file mode 100644 index 00000000..45ec8834 --- /dev/null +++ b/examples/erc20_watcher/event_triggered/converter.go @@ -0,0 +1,106 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package event_triggered + +import ( + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/vulcanize/vulcanizedb/examples/generic" + "github.com/vulcanize/vulcanizedb/examples/generic/helpers" + "github.com/vulcanize/vulcanizedb/pkg/core" +) + +type ERC20ConverterInterface interface { + ToTransferEntity(watchedEvent core.WatchedEvent) (*TransferEntity, error) + ToTransferModel(entity TransferEntity) TransferModel + ToApprovalEntity(watchedEvent core.WatchedEvent) (*ApprovalEntity, error) + ToApprovalModel(entity ApprovalEntity) ApprovalModel +} + +type ERC20Converter struct { + config generic.ContractConfig +} + +func NewERC20Converter(config generic.ContractConfig) ERC20Converter { + return ERC20Converter{ + config: config, + } +} + +func (c ERC20Converter) ToTransferEntity(watchedEvent core.WatchedEvent) (*TransferEntity, error) { + result := &TransferEntity{} + contract := bind.NewBoundContract(common.HexToAddress(c.config.Address), c.config.ParsedAbi, nil, nil, nil) + event := helpers.ConvertToLog(watchedEvent) + err := contract.UnpackLog(result, "Transfer", event) + if err != nil { + return result, err + } + result.TokenName = c.config.Name + result.TokenAddress = common.HexToAddress(c.config.Address) + result.Block = watchedEvent.BlockNumber + result.TxHash = watchedEvent.TxHash + + return result, nil +} + +func (c ERC20Converter) ToTransferModel(transferEntity TransferEntity) TransferModel { + to := transferEntity.Dst.String() + from := transferEntity.Src.String() + tokens := transferEntity.Wad.String() + block := transferEntity.Block + tx := transferEntity.TxHash + return TransferModel{ + TokenName: c.config.Name, + TokenAddress: c.config.Address, + To: to, + From: from, + Tokens: tokens, + Block: block, + TxHash: tx, + } +} + +func (c ERC20Converter) ToApprovalEntity(watchedEvent core.WatchedEvent) (*ApprovalEntity, error) { + result := &ApprovalEntity{} + contract := bind.NewBoundContract(common.HexToAddress(c.config.Address), c.config.ParsedAbi, nil, nil, nil) + event := helpers.ConvertToLog(watchedEvent) + err := contract.UnpackLog(result, "Approval", event) + if err != nil { + return result, err + } + result.TokenName = c.config.Name + result.TokenAddress = common.HexToAddress(c.config.Address) + result.Block = watchedEvent.BlockNumber + result.TxHash = watchedEvent.TxHash + + return result, nil +} + +func (c ERC20Converter) ToApprovalModel(TransferEntity ApprovalEntity) ApprovalModel { + tokenOwner := TransferEntity.Src.String() + spender := TransferEntity.Guy.String() + tokens := TransferEntity.Wad.String() + block := TransferEntity.Block + tx := TransferEntity.TxHash + return ApprovalModel{ + TokenName: c.config.Name, + TokenAddress: c.config.Address, + Owner: tokenOwner, + Spender: spender, + Tokens: tokens, + Block: block, + TxHash: tx, + } +} diff --git a/examples/erc20_watcher/event_triggered/converter_test.go b/examples/erc20_watcher/event_triggered/converter_test.go new file mode 100644 index 00000000..cb2f1b2a --- /dev/null +++ b/examples/erc20_watcher/event_triggered/converter_test.go @@ -0,0 +1,173 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package event_triggered_test + +import ( + "github.com/ethereum/go-ethereum/common" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "github.com/vulcanize/vulcanizedb/examples/constants" + "github.com/vulcanize/vulcanizedb/examples/erc20_watcher/event_triggered" + "github.com/vulcanize/vulcanizedb/examples/generic" + "github.com/vulcanize/vulcanizedb/pkg/core" + "math/big" +) + +var expectedTransferModel = event_triggered.TransferModel{ + TokenName: "Dai", + TokenAddress: "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359", + To: "0x09BbBBE21a5975cAc061D82f7b843bCE061BA391", + From: "0x000000000000000000000000000000000000Af21", + Tokens: "1097077688018008265106216665536940668749033598146", + Block: 5488076, + TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae", +} + +var transferWad, approvalWad big.Int + +var expectedTransferEntity = event_triggered.TransferEntity{ + TokenName: "Dai", + TokenAddress: common.HexToAddress("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"), + Src: common.HexToAddress("0x000000000000000000000000000000000000Af21"), + Dst: common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391"), + Wad: &transferWad, + Block: 5488076, + TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae", +} + +var expectedApprovalModel = event_triggered.ApprovalModel{ + TokenName: "Dai", + TokenAddress: "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359", + Owner: "0x000000000000000000000000000000000000Af21", + Spender: "0x09BbBBE21a5975cAc061D82f7b843bCE061BA391", + Tokens: "1097077688018008265106216665536940668749033598146", + Block: 5488076, + TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae", +} + +var expectedApprovalEntity = event_triggered.ApprovalEntity{ + TokenName: "Dai", + TokenAddress: common.HexToAddress("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"), + Src: common.HexToAddress("0x000000000000000000000000000000000000Af21"), + Guy: common.HexToAddress("0x09BbBBE21a5975cAc061D82f7b843bCE061BA391"), + Wad: &approvalWad, + Block: 5488076, + TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae", +} + +var transferEvent = core.WatchedEvent{ + LogID: 1, + Name: "Dai", + BlockNumber: 5488076, + Address: constants.DaiContractAddress, + TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae", + Index: 110, + Topic0: constants.TransferEventSignature, + Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21", + Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391", + Topic3: "", + Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe", +} + +var approvalEvent = core.WatchedEvent{ + LogID: 1, + Name: "Dai", + BlockNumber: 5488076, + Address: constants.DaiContractAddress, + TxHash: "0x135391a0962a63944e5908e6fedfff90fb4be3e3290a21017861099bad6546ae", + Index: 110, + Topic0: constants.TransferEventSignature, + Topic1: "0x000000000000000000000000000000000000000000000000000000000000af21", + Topic2: "0x9dd48110dcc444fdc242510c09bbbbe21a5975cac061d82f7b843bce061ba391", + Topic3: "", + Data: "0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359000000000000000000000000000000000000000000000000392d2e2bda9c00000000000000000000000000000000000000000000000000927f41fa0a4a418000000000000000000000000000000000000000000000000000000000005adcfebe", +} + +var _ = Describe("Transfer Converter", func() { + + daiConverter := event_triggered.NewERC20Converter(generic.DaiConfig) + + It("converts a watched transfer event into a TransferEntity", func() { + + result, err := daiConverter.ToTransferEntity(transferEvent) + Expect(err).NotTo(HaveOccurred()) + + Expect(result.TokenName).To(Equal(expectedTransferEntity.TokenName)) + Expect(result.TokenAddress).To(Equal(expectedTransferEntity.TokenAddress)) + Expect(result.Dst).To(Equal(expectedTransferEntity.Dst)) + Expect(result.Src).To(Equal(expectedTransferEntity.Src)) + Expect(result.Wad).To(Equal(expectedTransferEntity.Wad)) + Expect(result.Block).To(Equal(expectedTransferEntity.Block)) + Expect(result.TxHash).To(Equal(expectedTransferEntity.TxHash)) + }) + + It("converts a TransferEntity to an TransferModel", func() { + + result, err := daiConverter.ToTransferEntity(transferEvent) + Expect(err).NotTo(HaveOccurred()) + + model := daiConverter.ToTransferModel(*result) + + Expect(model.TokenName).To(Equal(expectedTransferModel.TokenName)) + Expect(model.TokenAddress).To(Equal(expectedTransferModel.TokenAddress)) + Expect(model.To).To(Equal(expectedTransferModel.To)) + Expect(model.From).To(Equal(expectedTransferModel.From)) + Expect(model.Tokens).To(Equal(expectedTransferModel.Tokens)) + Expect(model.Block).To(Equal(expectedTransferModel.Block)) + Expect(model.TxHash).To(Equal(expectedTransferModel.TxHash)) + }) + +}) + +var _ = Describe("Approval Converter", func() { + + daiConverter := event_triggered.NewERC20Converter(generic.DaiConfig) + + It("converts a watched approval event into a ApprovalEntity", func() { + + result, err := daiConverter.ToApprovalEntity(approvalEvent) + Expect(err).NotTo(HaveOccurred()) + + Expect(result.TokenName).To(Equal(expectedApprovalEntity.TokenName)) + Expect(result.TokenAddress).To(Equal(expectedApprovalEntity.TokenAddress)) + Expect(result.Src).To(Equal(expectedApprovalEntity.Src)) + Expect(result.Guy).To(Equal(expectedApprovalEntity.Guy)) + Expect(result.Wad).To(Equal(expectedApprovalEntity.Wad)) + Expect(result.Block).To(Equal(expectedApprovalEntity.Block)) + Expect(result.TxHash).To(Equal(expectedApprovalEntity.TxHash)) + }) + + It("converts a ApprovalEntity to an ApprovalModel", func() { + + result, err := daiConverter.ToApprovalEntity(approvalEvent) + Expect(err).NotTo(HaveOccurred()) + + model := daiConverter.ToApprovalModel(*result) + + Expect(model.TokenName).To(Equal(expectedApprovalModel.TokenName)) + Expect(model.TokenAddress).To(Equal(expectedApprovalModel.TokenAddress)) + Expect(model.Owner).To(Equal(expectedApprovalModel.Owner)) + Expect(model.Spender).To(Equal(expectedApprovalModel.Spender)) + Expect(model.Tokens).To(Equal(expectedApprovalModel.Tokens)) + Expect(model.Block).To(Equal(expectedApprovalModel.Block)) + Expect(model.TxHash).To(Equal(expectedApprovalModel.TxHash)) + }) + +}) + +func init() { + transferWad.SetString("1097077688018008265106216665536940668749033598146", 10) + approvalWad.SetString("1097077688018008265106216665536940668749033598146", 10) +} diff --git a/examples/erc20_watcher/event_triggered/entity.go b/examples/erc20_watcher/event_triggered/entity.go new file mode 100644 index 00000000..f8e3114c --- /dev/null +++ b/examples/erc20_watcher/event_triggered/entity.go @@ -0,0 +1,40 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package event_triggered + +import ( + "github.com/ethereum/go-ethereum/common" + "math/big" +) + +type TransferEntity struct { + TokenName string + TokenAddress common.Address + Src common.Address + Dst common.Address + Wad *big.Int + Block int64 + TxHash string +} + +type ApprovalEntity struct { + TokenName string + TokenAddress common.Address + Src common.Address + Guy common.Address + Wad *big.Int + Block int64 + TxHash string +} diff --git a/examples/erc20_watcher/event_triggered/event_triggered_suite_test.go b/examples/erc20_watcher/event_triggered/event_triggered_suite_test.go new file mode 100644 index 00000000..f75089a9 --- /dev/null +++ b/examples/erc20_watcher/event_triggered/event_triggered_suite_test.go @@ -0,0 +1,27 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package event_triggered_test + +import ( + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +func TestLogKill(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "ERC20 Event Triggered test Suite") +} diff --git a/examples/erc20_watcher/event_triggered/integration_test.go b/examples/erc20_watcher/event_triggered/integration_test.go new file mode 100644 index 00000000..0531c04f --- /dev/null +++ b/examples/erc20_watcher/event_triggered/integration_test.go @@ -0,0 +1,15 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package event_triggered_test diff --git a/examples/erc20_watcher/event_triggered/model.go b/examples/erc20_watcher/event_triggered/model.go new file mode 100644 index 00000000..fda4771f --- /dev/null +++ b/examples/erc20_watcher/event_triggered/model.go @@ -0,0 +1,35 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package event_triggered + +type TransferModel struct { + TokenName string + TokenAddress string + To string + From string + Tokens string + Block int64 + TxHash string +} + +type ApprovalModel struct { + TokenName string + TokenAddress string + Owner string + Spender string + Tokens string + Block int64 + TxHash string +} diff --git a/examples/erc20_watcher/event_triggered/repository.go b/examples/erc20_watcher/event_triggered/repository.go new file mode 100644 index 00000000..3e63dd1c --- /dev/null +++ b/examples/erc20_watcher/event_triggered/repository.go @@ -0,0 +1,58 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package event_triggered + +import ( + "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" +) + +type Datastore interface { + CreateTransfer(model TransferModel, vulcanizeLogId int64) error + CreateApproval(model ApprovalModel, vulcanizeLogId int64) error +} + +type Repository struct { + *postgres.DB +} + +func (repository Repository) CreateTransfer(transferModel TransferModel, vulcanizeLogId int64) error { + _, err := repository.DB.Exec( + + `INSERT INTO TRANSFERS (vulcanize_log_id, token_address, to, from, tokens, block, tx) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ON CONFLICT (vulcanize_log_id) DO NOTHING`, + vulcanizeLogId, transferModel.TokenAddress, transferModel.To, transferModel.From, transferModel.Tokens, transferModel.Block, transferModel.TxHash) + + if err != nil { + return err + } + + return nil +} + +func (repository Repository) CreateApproval(approvalModel ApprovalModel, vulcanizeLogId int64) error { + _, err := repository.DB.Exec( + + `INSERT INTO APPROVALS (vulcanize_log_id, token_address, token_owner, token_spender, tokens, block, tx) + VALUES ($1, $2, $3, $4, $5, $6, $7) + ON CONFLICT (vulcanize_log_id) DO NOTHING`, + vulcanizeLogId, approvalModel.TokenAddress, approvalModel.Owner, approvalModel.Spender, approvalModel.Tokens, approvalModel.Block, approvalModel.TxHash) + + if err != nil { + return err + } + + return nil +} diff --git a/examples/erc20_watcher/event_triggered/repository_test.go b/examples/erc20_watcher/event_triggered/repository_test.go new file mode 100644 index 00000000..0531c04f --- /dev/null +++ b/examples/erc20_watcher/event_triggered/repository_test.go @@ -0,0 +1,15 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package event_triggered_test diff --git a/examples/erc20_watcher/event_triggered/transformer.go b/examples/erc20_watcher/event_triggered/transformer.go new file mode 100644 index 00000000..aa2b739d --- /dev/null +++ b/examples/erc20_watcher/event_triggered/transformer.go @@ -0,0 +1,15 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package event_triggered diff --git a/examples/erc20_watcher/event_triggered/transformer_test.go b/examples/erc20_watcher/event_triggered/transformer_test.go new file mode 100644 index 00000000..0531c04f --- /dev/null +++ b/examples/erc20_watcher/event_triggered/transformer_test.go @@ -0,0 +1,15 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package event_triggered_test diff --git a/examples/erc20_watcher/every_block/integration_test.go b/examples/erc20_watcher/every_block/integration_test.go index da449a1a..a91ddb85 100644 --- a/examples/erc20_watcher/every_block/integration_test.go +++ b/examples/erc20_watcher/every_block/integration_test.go @@ -18,8 +18,8 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/vulcanize/vulcanizedb/examples/constants" - "github.com/vulcanize/vulcanizedb/examples/erc20_watcher" "github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block" + "github.com/vulcanize/vulcanizedb/examples/generic" "github.com/vulcanize/vulcanizedb/examples/test_helpers" "github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" @@ -45,7 +45,7 @@ var _ = Describe("Everyblock transformers", func() { BeforeEach(func() { blockChain = fakes.NewMockBlockChain() - blockNumber = erc20_watcher.DaiConfig.FirstBlock + blockNumber = generic.DaiConfig.FirstBlock lastBlockNumber := blockNumber + 1 db = test_helpers.CreateNewDatabase() setLastBlockOnChain(blockChain, lastBlockNumber) @@ -59,7 +59,7 @@ var _ = Describe("Everyblock transformers", func() { }) It("creates a token_supply record for each block in the given range", func() { - initializer := every_block.ERC20TokenTransformerInitializer{Config: erc20_watcher.DaiConfig} + initializer := every_block.ERC20TokenTransformerInitializer{Config: generic.DaiConfig} transformer := initializer.NewERC20TokenTransformer(db, blockChain) transformer.Execute() diff --git a/examples/erc20_watcher/every_block/transformer.go b/examples/erc20_watcher/every_block/transformer.go index 7835ab32..4c88d733 100644 --- a/examples/erc20_watcher/every_block/transformer.go +++ b/examples/erc20_watcher/every_block/transformer.go @@ -17,7 +17,6 @@ package every_block import ( "fmt" "github.com/ethereum/go-ethereum/common" - "github.com/vulcanize/vulcanizedb/examples/erc20_watcher" "github.com/vulcanize/vulcanizedb/examples/generic" "github.com/vulcanize/vulcanizedb/libraries/shared" "github.com/vulcanize/vulcanizedb/pkg/core" @@ -30,15 +29,15 @@ type Transformer struct { Getter ERC20GetterInterface Repository ERC20RepositoryInterface Retriever generic.Retriever - Config erc20_watcher.ContractConfig + Config generic.ContractConfig } -func (t *Transformer) SetConfiguration(config erc20_watcher.ContractConfig) { +func (t *Transformer) SetConfiguration(config generic.ContractConfig) { t.Config = config } type ERC20TokenTransformerInitializer struct { - Config erc20_watcher.ContractConfig + Config generic.ContractConfig } func (i ERC20TokenTransformerInitializer) NewERC20TokenTransformer(db *postgres.DB, blockchain core.BlockChain) shared.Transformer { diff --git a/examples/erc20_watcher/every_block/transformer_test.go b/examples/erc20_watcher/every_block/transformer_test.go index 1634bf4f..224739e7 100644 --- a/examples/erc20_watcher/every_block/transformer_test.go +++ b/examples/erc20_watcher/every_block/transformer_test.go @@ -18,7 +18,6 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/vulcanize/vulcanizedb/examples/constants" - "github.com/vulcanize/vulcanizedb/examples/erc20_watcher" "github.com/vulcanize/vulcanizedb/examples/erc20_watcher/every_block" "github.com/vulcanize/vulcanizedb/examples/generic" "github.com/vulcanize/vulcanizedb/examples/mocks" @@ -29,7 +28,7 @@ import ( "strconv" ) -var testContractConfig = erc20_watcher.ContractConfig{ +var testContractConfig = generic.ContractConfig{ Address: constants.DaiContractAddress, Abi: constants.DaiAbiString, FirstBlock: int64(4752008), diff --git a/examples/erc20_watcher/every_block/transformers.go b/examples/erc20_watcher/every_block/transformers.go index be3113ac..ae06f1ad 100644 --- a/examples/erc20_watcher/every_block/transformers.go +++ b/examples/erc20_watcher/every_block/transformers.go @@ -15,12 +15,12 @@ package every_block import ( - "github.com/vulcanize/vulcanizedb/examples/erc20_watcher" + "github.com/vulcanize/vulcanizedb/examples/generic" "github.com/vulcanize/vulcanizedb/libraries/shared" ) func TransformerInitializers() []shared.TransformerInitializer { - config := erc20_watcher.DaiConfig + config := generic.DaiConfig initializer := ERC20TokenTransformerInitializer{config} return []shared.TransformerInitializer{ initializer.NewERC20TokenTransformer, diff --git a/examples/erc20_watcher/config.go b/examples/generic/config.go similarity index 82% rename from examples/erc20_watcher/config.go rename to examples/generic/config.go index 880d2143..26755bcf 100644 --- a/examples/erc20_watcher/config.go +++ b/examples/generic/config.go @@ -12,13 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -package erc20_watcher +package generic -import "github.com/vulcanize/vulcanizedb/examples/constants" +import ( + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/vulcanize/vulcanizedb/examples/constants" +) type ContractConfig struct { Address string Abi string + ParsedAbi abi.ABI FirstBlock int64 LastBlock int64 Name string @@ -27,6 +31,7 @@ type ContractConfig struct { var DaiConfig = ContractConfig{ Address: constants.DaiContractAddress, Abi: constants.DaiAbiString, + ParsedAbi: constants.ParsedDaiAbi, FirstBlock: int64(4752008), LastBlock: -1, Name: "Dai", diff --git a/examples/generic/helpers/helpers.go b/examples/generic/helpers/helpers.go new file mode 100644 index 00000000..706277ef --- /dev/null +++ b/examples/generic/helpers/helpers.go @@ -0,0 +1,66 @@ +// Copyright 2018 Vulcanize +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package helpers + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/vulcanize/vulcanizedb/pkg/core" +) + +func ConvertToLog(watchedEvent core.WatchedEvent) types.Log { + allTopics := []string{watchedEvent.Topic0, watchedEvent.Topic1, watchedEvent.Topic2, watchedEvent.Topic3} + var nonNilTopics []string + for _, topic := range allTopics { + if topic != "" { + nonNilTopics = append(nonNilTopics, topic) + } + } + return types.Log{ + Address: common.HexToAddress(watchedEvent.Address), + Topics: createTopics(nonNilTopics...), + Data: hexutil.MustDecode(watchedEvent.Data), + BlockNumber: uint64(watchedEvent.BlockNumber), + TxHash: common.HexToHash(watchedEvent.TxHash), + TxIndex: 0, + BlockHash: common.HexToHash("0x0"), + Index: uint(watchedEvent.Index), + Removed: false, + } +} + +func createTopics(topics ...string) []common.Hash { + var topicsArray []common.Hash + for _, topic := range topics { + topicsArray = append(topicsArray, common.HexToHash(topic)) + } + return topicsArray +} + +func BigFromString(n string) *big.Int { + b := new(big.Int) + b.SetString(n, 10) + return b +} + +func GenerateSignature(s string) string { + eventSignature := []byte(s) + hash := crypto.Keccak256Hash(eventSignature) + return hash.Hex() +}