forked from cerc-io/ipld-eth-server
retriever for generating list of all token holder addresses + updated transformer to use said addresses to populate balanceOf and allowance information and added database migrations for balance and allowance tables
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
// 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 generic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
|
||||
"log"
|
||||
)
|
||||
|
||||
// Retriever is used to iterate over addresses going into or out of a contract
|
||||
// address in an attempt to generate a list of token holder addresses
|
||||
|
||||
type RetrieverInterface interface {
|
||||
RetrieveSendingAddresses() ([]string, error)
|
||||
RetrieveReceivingAddresses() ([]string, error)
|
||||
RetrieveContractAssociatedAddresses() (map[common.Address]bool, error)
|
||||
}
|
||||
|
||||
type Retriever struct {
|
||||
Database *postgres.DB
|
||||
ContractAddress string
|
||||
}
|
||||
|
||||
type retrieverError struct {
|
||||
err string
|
||||
msg string
|
||||
address string
|
||||
}
|
||||
|
||||
// Retriever error method
|
||||
func (re *retrieverError) Error() string {
|
||||
return fmt.Sprintf(re.msg, re.address, re.err)
|
||||
}
|
||||
|
||||
// Used to create a new retriever error for a given error and fetch method
|
||||
func newRetrieverError(err error, msg string, address string) error {
|
||||
e := retrieverError{err.Error(), msg, address}
|
||||
log.Println(e.Error())
|
||||
return &e
|
||||
}
|
||||
|
||||
// Constant error definitions
|
||||
const (
|
||||
GetSenderError = "Error fetching addresses receiving from contract %s: %s"
|
||||
GetReceiverError = "Error fetching addresses sending to contract %s: %s"
|
||||
)
|
||||
|
||||
func NewRetriever(db *postgres.DB, address string) Retriever {
|
||||
return Retriever{
|
||||
Database: db,
|
||||
ContractAddress: address,
|
||||
}
|
||||
}
|
||||
|
||||
func (rt Retriever) RetrieveReceivingAddresses() ([]string, error) {
|
||||
|
||||
receiversFromContract := make([]string, 0)
|
||||
|
||||
err := rt.Database.DB.Select(
|
||||
&receiversFromContract,
|
||||
`SELECT tx_to FROM TRANSACTIONS
|
||||
WHERE tx_from = $1
|
||||
LIMIT 20`,
|
||||
rt.ContractAddress,
|
||||
)
|
||||
if err != nil {
|
||||
return []string{}, newRetrieverError(err, GetReceiverError, rt.ContractAddress)
|
||||
}
|
||||
return receiversFromContract, err
|
||||
}
|
||||
|
||||
func (rt Retriever) RetrieveSendingAddresses() ([]string, error) {
|
||||
|
||||
sendersToContract := make([]string, 0)
|
||||
|
||||
err := rt.Database.DB.Select(
|
||||
&sendersToContract,
|
||||
`SELECT tx_from FROM TRANSACTIONS
|
||||
WHERE tx_to = $1
|
||||
LIMIT 20`,
|
||||
rt.ContractAddress,
|
||||
)
|
||||
if err != nil {
|
||||
return []string{}, newRetrieverError(err, GetSenderError, rt.ContractAddress)
|
||||
}
|
||||
return sendersToContract, err
|
||||
}
|
||||
|
||||
func (rt Retriever) RetrieveContractAssociatedAddresses() (map[common.Address]bool, error) {
|
||||
|
||||
sending, err := rt.RetrieveSendingAddresses()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
receiving, err := rt.RetrieveReceivingAddresses()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contractAddresses := make(map[common.Address]bool)
|
||||
|
||||
for _, addr := range sending {
|
||||
contractAddresses[common.HexToAddress(addr)] = true
|
||||
}
|
||||
|
||||
for _, addr := range receiving {
|
||||
contractAddresses[common.HexToAddress(addr)] = true
|
||||
}
|
||||
|
||||
return contractAddresses, nil
|
||||
}
|
||||
Reference in New Issue
Block a user