示例#1
0
def get_contract_params(web3, contract, events):
    output = {}
    for event in events:
        abi = getattr(contract.events, event)._get_event_abi()
        topic = construct_event_topic_set(abi, web3.codec)
        output[event] = (abi, topic[0])
    return output
async def process_storage_history(start_height=0):
    web3 = get_web3()
    contract = get_storage_contract(web3)
    abi = contract.events.NewHash._get_event_abi()
    topic = construct_event_topic_set(abi, web3.codec)

    start = max(start_height, settings.ethereum_min_height)
    last_height = start
    end_height = web3.eth.blockNumber
    count = 0

    async for i in get_logs(web3, contract, start, topics=topic):
        count += 1
        evt_data = get_event_data(web3.codec, abi, i)
        args = evt_data['args']
        height = evt_data['blockNumber']
        LOGGER.debug(f"{height}: {evt_data}")
        context = {
            "source_chain": 'ETH',
            "source_contract": settings.ethereum_event_contract,
            "tx_hash": evt_data.transactionHash.hex(),
            "height": evt_data.blockNumber,
            "submitter": args['hashSubmitter']
        }
        yield (context, args["hash"])

    LOGGER.info(f"Scanned {count} events")
示例#3
0
def get_netting_channel_closed_events(
    proxy_manager: ProxyManager,
    token_network_address: TokenNetworkAddress,
    netting_channel_identifier: ChannelID,
    contract_manager: ContractManager,
    from_block: BlockIdentifier = GENESIS_BLOCK_NUMBER,
    to_block: BlockIdentifier = BLOCK_ID_LATEST,
) -> List[Dict]:
    closed_event_abi = contract_manager.get_event_abi(CONTRACT_TOKEN_NETWORK,
                                                      ChannelEvent.CLOSED)

    topic_set = construct_event_topic_set(
        event_abi=closed_event_abi,
        abi_codec=proxy_manager.client.web3.codec,
        arguments={"channel_identifier": netting_channel_identifier},
    )

    return get_contract_events(
        proxy_manager=proxy_manager,
        abi=contract_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK),
        contract_address=Address(token_network_address),
        topics=topic_set,  # type: ignore
        from_block=from_block,
        to_block=to_block,
    )
示例#4
0
def construct_event_filter_params(
    event_abi: ABIEvent,
    abi_codec: ABICodec,
    contract_address: Optional[ChecksumAddress] = None,
    argument_filters: Optional[Dict[str, Any]] = None,
    topics: Optional[Sequence[HexStr]] = None,
    fromBlock: Optional[BlockIdentifier] = None,
    toBlock: Optional[BlockIdentifier] = None,
    address: Optional[ChecksumAddress] = None
) -> Tuple[List[List[Optional[HexStr]]], FilterParams]:
    filter_params: FilterParams = {}
    topic_set: Sequence[HexStr] = construct_event_topic_set(
        event_abi, abi_codec, argument_filters)

    if topics is not None:
        if len(topic_set) > 1:
            raise TypeError(
                "Merging the topics argument with topics generated "
                "from argument_filters is not supported.")
        topic_set = topics

    if len(topic_set) == 1 and is_list_like(topic_set[0]):
        # type ignored b/c list-like check on line 88
        filter_params['topics'] = topic_set[0]  # type: ignore
    else:
        filter_params['topics'] = topic_set

    if address and contract_address:
        if is_list_like(address):
            filter_params['address'] = [address] + [contract_address]
        elif is_string(address):
            filter_params['address'] = [address, contract_address]
        else:
            raise ValueError(
                "Unsupported type for `address` parameter: {0}".format(
                    type(address)))
    elif address:
        filter_params['address'] = address
    elif contract_address:
        filter_params['address'] = contract_address

    if 'address' not in filter_params:
        pass
    elif is_list_like(filter_params['address']):
        for addr in filter_params['address']:
            validate_address(addr)
    else:
        validate_address(filter_params['address'])

    if fromBlock is not None:
        filter_params['fromBlock'] = fromBlock

    if toBlock is not None:
        filter_params['toBlock'] = toBlock

    data_filters_set = construct_event_data_set(event_abi, abi_codec,
                                                argument_filters)

    return data_filters_set, filter_params
示例#5
0
 def load_from_ens(self):
     # track older registries to pull experiments
     resolver = contract('0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41')
     topics = construct_event_topic_set(
         filter_by_name('AddressChanged', resolver.abi)[0],
         web3.codec,
         {'node': web3.ens.namehash('v2.registry.ychad.eth')},
     )
     events = decode_logs(get_logs_asap(str(resolver), topics))
     logger.info('loaded %d registry versions', len(events))
     return [Contract(event['newAddress']) for event in events]
示例#6
0
def process_pool_history(pool, per_block, start_height, end_height):
    abi = pool['contract'].events.Transfer._get_event_abi()
    web3 = get_web3()
    topic = construct_event_topic_set(abi, web3.codec)
    weights = dict()
    balances = dict()
    reward_start = max(pool['start_height'], config['reward_start'],
                       start_height)
    last_height = reward_start
    end_height = min(web3.eth.blockNumber, end_height)

    def update_weights(since, current):
        for addr, value in balances.items():
            if value > 0:
                weights[addr] = weights.get(addr, 0) + (value *
                                                        (current - since))

    for i in get_logs(web3,
                      pool['contract'],
                      pool['start_height'],
                      topics=topic):
        evt_data = get_event_data(web3.codec, abi, i)
        args = evt_data['args']
        height = evt_data['blockNumber']
        if height > end_height:
            break

        if height > reward_start:
            update_weights(last_height, height)

        # to handle gaps in our staking contract's reward distribution,
        # a user's balance accumulates whenever they stake to the contract
        if args['src'] == '0xFe82ea0Ef14DfdAcd5dB1D49F563497A1a751bA1':
            balances[args.dst] = balances.get(args.dst, 0) - args.amt
        elif args.dst == '0xFe82ea0Ef14DfdAcd5dB1D49F563497A1a751bA1':
            balances[args['src']] = balances.get(args['src'], 0) + args.amt
        last_height = height

    height = end_height
    update_weights(last_height, height)
    total_weight = sum(weights.values())
    total_balance = sum([b for b in balances.values() if b > 0])
    weights = {a: w / total_weight for a, w in weights.items() if w > 0}
    print(weights)
    balparts = {a: w / total_balance for a, w in balances.items() if w > 0}
    print(balparts)

    total_blocks = height - reward_start
    reward_owed = {a: w * per_block * total_blocks for a, w in weights.items()}
    print(reward_owed)
    print("Total", sum(reward_owed.values()))
    return reward_owed, start_height, end_height
示例#7
0
async def process_contract_history(contract_address,
                                   start_height,
                                   platform="ETH",
                                   balances=None,
                                   last_seen=None):
    web3 = get_web3()
    contract = get_contract(contract_address, web3)
    abi = contract.events.Transfer._get_event_abi()
    topic = construct_event_topic_set(abi, web3.codec)
    if balances is None:
        balances = {
            settings.ethereum_deployer:
            settings.ethereum_total_supply * DECIMALS
        }
    last_height = start_height
    end_height = web3.eth.blockNumber

    changed_addresses = set()

    to_append = list()

    async for i in get_logs(web3, contract, start_height, topics=topic):
        evt_data = get_event_data(web3.codec, abi, i)
        args = evt_data['args']
        height = evt_data['blockNumber']

        if height != last_height:
            yield (last_height, (balances, platform, changed_addresses))
            changed_addresses = set()

            if last_seen is not None:
                last_seen.extend(to_append)

            to_append = list()

        if last_seen is not None:
            tx_hash = evt_data.transactionHash.hex()
            if tx_hash in last_seen:
                continue
            else:
                to_append.append(tx_hash)

        balances[args['_from']] = (balances.get(args['_from'], 0) -
                                   args['_value'])
        balances[args['_to']] = balances.get(args['_to'], 0) + args['_value']
        changed_addresses.add(args['_from'])
        changed_addresses.add(args['_to'])
        last_height = height

    if len(changed_addresses):
        yield (last_height, (balances, platform, changed_addresses))
示例#8
0
def process_pool_history(pool, per_block, start_height, end_height):
    abi = pool['contract'].events.Transfer._get_event_abi()
    web3 = get_web3()
    topic = construct_event_topic_set(abi, web3.codec)
    weights = dict()
    balances = dict()
    reward_start = max(pool['start_height'], config['reward_start'], start_height)
    last_height = reward_start
    end_height = min(web3.eth.blockNumber, end_height)

    def update_weights(since, current):
        for addr, value in balances.items():
            # skip LBP deployer address
            if addr == '0xC98A0A4d9D9F789b86f03AbfdcEaEE7e3538e3dF':
                continue
            if value > 0:
                weights[addr] = weights.get(addr, 0) + (value * (current-since))

    for i in get_logs(web3, pool['contract'], pool['start_height'], topics=topic):
        evt_data = get_event_data(web3.codec, abi, i)
        args = evt_data['args']
        height = evt_data['blockNumber']
        if height > end_height:
            break

        if height > reward_start:
            update_weights(last_height, height)

        # to handle gaps in our staking contract's reward distribution,
        # a user's balance accumulates whenever they stake to the contract
        if args['from'] == '0x0310DEE97b42063BbB46d02a674727C13eb79cFD':
            balances[args.to] = balances.get(args.to, 0) - args.value
        elif args.to == '0x0310DEE97b42063BbB46d02a674727C13eb79cFD':
            balances[args['from']] = balances.get(args['from'], 0) + args.value
        last_height = height
    
    height = end_height
    update_weights(last_height, height)
    total_weight = sum(weights.values())
    total_balance = sum([b for b in balances.values() if b > 0])
    weights = {a: w / total_weight for a, w in weights.items() if w > 0}
    print(weights)
    balparts = {a: w / total_balance for a, w in balances.items() if w > 0}
    print(balparts)

    total_blocks = height - reward_start
    reward_owed = {a: w*per_block*total_blocks for a, w in weights.items()}
    print(reward_owed)
    print("Total", sum(reward_owed.values()))
    return reward_owed, start_height, end_height
示例#9
0
def process_pool_history(pool, per_block, start_height, end_height):
    abi = pool['contract'].events.Transfer._get_event_abi()
    web3 = get_web3()
    topic = construct_event_topic_set(abi, web3.codec)
    weights = dict()
    balances = dict()
    reward_start = max(pool['start_height'], config['reward_start'],
                       start_height)
    last_height = reward_start
    end_height = min(web3.eth.blockNumber, end_height)

    def update_weights(since, current):
        for addr, value in balances.items():
            if value > 0:
                weights[addr] = weights.get(addr, 0) + (value *
                                                        (current - since))

    for i in get_logs(web3,
                      pool['contract'],
                      pool['start_height'],
                      topics=topic):
        evt_data = get_event_data(web3.codec, abi, i)
        args = evt_data['args']
        height = evt_data['blockNumber']
        if height > end_height:
            break

        if height > reward_start:
            update_weights(last_height, height)

        balances[args['from']] = balances.get(args['from'], 0) - args.value
        balances[args.to] = balances.get(args.to, 0) + args.value
        last_height = height

    height = end_height
    update_weights(last_height, height)
    total_weight = sum(weights.values())
    total_balance = sum([b for b in balances.values() if b > 0])
    weights = {a: w / total_weight for a, w in weights.items() if w > 0}
    print(weights)
    balparts = {a: w / total_balance for a, w in balances.items() if w > 0}
    print(balparts)

    total_blocks = height - reward_start
    reward_owed = {a: w * per_block * total_blocks for a, w in weights.items()}
    print(reward_owed)
    print("Total", sum(reward_owed.values()))
    return reward_owed, start_height, end_height
def get_token_transfers(token, start_block, end_block) -> pd.DataFrame:
    topics = construct_event_topic_set(
        filter_by_name('Transfer', token.abi)[0],
        web3.codec,
    )
    postgres.cache_token(token.address)
    decimals = contract(token.address).decimals()
    events = decode_logs(
        get_logs_asap(token.address,
                      topics,
                      from_block=start_block,
                      to_block=end_block))
    return pd.DataFrame(
        Parallel(1, 'threading')(
            delayed(_process_transfer_event)(event, token, decimals)
            for event in events))
 def prepare_events(contract):
     with open(contract['abi'], 'r') as file:
         abi = json.loads(file.read())
         for element in abi:
             if element['type'] == 'event':
                 topic = construct_event_topic_set(element)[0]
                 if element['name'] in contract['tracked_event_names']:
                     if topic not in tracked_events:
                         tracked_events[topic] = element
                         logger.info(
                             f'Added event {contract["abi"]} - {element["name"]}'
                         )
                     if 'addresses' not in tracked_events[topic]:
                         tracked_events[topic]['addresses'] = []
                     tracked_events[topic]['addresses'].append(
                         contract['address'])
示例#12
0
def get_protocol_fees(address):
    """
    Get all protocol fee payouts for a given vault.

    Fees can be found as vault share transfers to the rewards address.
    """
    vault = Vault.from_address(address)
    rewards = vault.vault.rewards()

    topics = construct_event_topic_set(
        filter_by_name('Transfer', vault.vault.abi)[0],
        web3.codec,
        {
            'sender': address,
            'receiver': rewards
        },
    )
    logs = decode_logs(get_logs_asap(address, topics))
    return {log.block_number: log['value'] / vault.scale for log in logs}
示例#13
0
    def unwrap(self) -> List[Wrapper]:
        registry = Registry()
        wrappers = [self.wrapper] if isinstance(self.wrapper,
                                                str) else self.wrapper
        topics = construct_event_topic_set(
            filter_by_name('Transfer', registry.vaults[0].vault.abi)[0],
            web3.codec,
            {'receiver': wrappers},
        )
        addresses = [str(vault.vault) for vault in registry.vaults]
        from_block = min(ThreadPoolExecutor().map(contract_creation_block,
                                                  addresses))

        # wrapper -> {vaults}
        deposits = defaultdict(set)
        for log in decode_logs(get_logs_asap(addresses, topics, from_block)):
            deposits[log['receiver']].add(log.address)

        return [
            Wrapper(name=vault.name, vault=str(vault.vault), wrapper=wrapper)
            for wrapper in wrappers for vault in registry.vaults
            if str(vault.vault) in deposits[wrapper]
        ]
示例#14
0
def process_contract_history(contract_address, start_height, end_height):
    web3 = get_web3()
    contract = get_contract(contract_address, web3)
    abi = contract.events.Transfer._get_event_abi()
    topic = construct_event_topic_set(abi, web3.codec)
    weights = dict()
    balances = dict()
    last_height = start_height
    end_height = min(web3.eth.blockNumber, end_height)

    for i in get_logs(web3, contract, start_height, topics=topic):
        evt_data = get_event_data(web3.codec, abi, i)
        args = evt_data['args']
        height = evt_data['blockNumber']
        if height > end_height:
            break

        balances[args['_from']] = balances.get(args['_from'],
                                               0) - args['_value']
        balances[args['_to']] = balances.get(args['_to'], 0) + args['_value']
        last_height = height

    height = end_height
    return balances
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.proxy_factory_contract = get_proxy_factory_contract(self.ethereum_client.w3)
     self.proxy_creation_topic = construct_event_topic_set(self.proxy_factory_contract.events.ProxyCreation().abi,
                                                           None)[0]
示例#16
0
def test_construct_event_topics(event_abi, arguments, expected):
    actual = construct_event_topic_set(event_abi, arguments)
    assert actual == expected
def test_construct_event_topics(web3, arguments, expected):
    actual = construct_event_topic_set(EVENT_1_ABI, web3.codec, arguments)
    assert actual == expected
def test_construct_event_topics(event_abi, arguments, expected):
    actual = construct_event_topic_set(event_abi, arguments)
    assert actual == expected
示例#19
0
            'indexed': True,
            'name': 'to',
            'type': 'address'
        },
        {
            'indexed': False,
            'name': 'value',
            'type': 'uint256'
        },
    ],
    'name':
    'Transfer',
    'type':
    'event',
}
TOPICS_IN = construct_event_topic_set(ABI, {'from': ZERO_ADDRESS})
TOPICS_OUT = construct_event_topic_set(ABI, {'to': ZERO_ADDRESS})

ts_cache = {}
pool = ThreadPoolExecutor(10)
label = colored('Ethereum', 'blue')


def fetch():
    start = Bridge.last_block('ethereum') or LTO_BLOCK
    print(label, 'fetching since', start)
    end = w3.eth.blockNumber
    txs = []
    logs_in = get_logs_multipart(w3, start, end, LTO_TOKEN, TOPICS_IN, 10000)
    logs_out = get_logs_multipart(w3, start, end, LTO_TOKEN, TOPICS_OUT, 10000)
    for batch in chain.from_iterable(zip(logs_in, logs_out)):
示例#20
0
def test_construct_event_topics_strict(w3_strict_abi, arguments, expected):
    actual = construct_event_topic_set(EVENT_1_ABI, w3_strict_abi.codec,
                                       arguments)
    assert actual == expected
示例#21
0
def test_construct_event_topics_strict_errors(w3_strict_abi, arguments, error):
    with pytest.raises(error):
        construct_event_topic_set(EVENT_2_ABI, w3_strict_abi.codec, arguments)
示例#22
0
def find_transfers(address, from_address, to_address, start_block, end_block):
    topics = construct_event_topic_set(abi, web3.codec, {
        "from": from_address,
        "to": to_address
    })
    return get_logs_asap(address, topics, start_block, end_block)