首页 > 解决方案 > Change method when http request returns something new (python)

问题描述

An inefficient version of what I'm trying to do is this:

while(True):
    dynamic_variable = http(request) # where http request is subject to change values
    method(dynamic_variable)

Where method(dynamic_variable isn't guaranteed to finish, and if http(request) returns a different value than method(dynamic_variable) becomes a useless function.

It seems like I should be able to change dynamic_variable more efficiently by having it "automatically" update whenever http(request) changes value.

I think what I want to do is called the "observer pattern" but I'm not quite fluent enough in code to know if that's the correct pattern or how to implement it.

A simple example would be much appreciated!


Edit:

from web3 import Web3
import json
from hexbytes import HexBytes

import numpy as np
import os
import time

INFURA_ROPSTEN_URL = "https://ropsten.infura.io/v3/<api_key>"

# metamask account information
PUBLIC_KEY = "0x3FaD9AccC3A39aDbd9887E82F94602cEA6c7F86f"
PRIVATE_KEY = "myprivatekey"

UNITS_ADDRESS = "units_address"
# from truffle build. For ABI
JSON_PATH = "../truffle/build/contracts/Units.json"

def set_up_web3():
    web3 = Web3(Web3.HTTPProvider(INFURA_ROPSTEN_URL))
    web3.eth.defaultAccount = PUBLIC_KEY
    return web3

def get_units_contract_object():
    with open(JSON_PATH, 'r') as json_file:
        abi = json.load(json_file)['abi']
    return web3.eth.contract(address=UNITS_ADDRESS,abi=abi)

def solve(web3, units):
    nonce = np.random.randint(0,1e10)
    while True:
        challenge_number_hex = HexBytes(units.functions.getChallengeNumber().call()).hex()
        my_digest_hex = web3.solidityKeccak(
                            ['bytes32','address','uint256'],
                            [challenge_number_hex, PUBLIC_KEY, nonce]).hex()
        my_digest_number = int(my_digest_hex,0)
        target = units.functions.getMiningTarget().call()
        if my_digest_number < target:
            return (nonce, my_digest_hex)
        else:
            nonce += 1

def build_transaction(units, nonce, digest_hex, txn_count):
    return units.functions.mint(
                    nonce,
                    digest_hex
            ).buildTransaction({
                "nonce" : txn_count,
        })

if __name__ == "__main__":    
    web3 = set_up_web3()

    txn_count = web3.eth.getTransactionCount(PUBLIC_KEY)
    units = get_units_contract_object()

    _cycle_goal = 20
    _prev_finish = time.time()
    _wait_time = 0
    while True:
        target = units.functions.getMiningTarget().call()
        nonce, digest_hex = solve(web3, units)

        mint_txn = build_transaction(units, nonce,digest_hex, txn_count)
        signed_txn = web3.eth.account.sign_transaction(mint_txn, private_key=PRIVATE_KEY)
        txn_address = web3.eth.sendRawTransaction(signed_txn.rawTransaction)
        txn_count += 1
        print(f"Solution found! nonce={nonce}, digest_hex={digest_hex}")

        _finished = time.time()
        _elapsed = _finished - _prev_finish
        _additional_wait = _cycle_goal - _elapsed
        _wait_time += _additional_wait
        print(f"Waiting {_wait_time}")
        _prev_finish = _finished
        time.sleep(_wait_time)

challenge_hex_number is the variable I want to update

标签: pythondynamic

解决方案


推荐阅读