Exemplo n.º 1
0
def test_getters():
    minimal_code = \
    """
    pragma solidity ^0.4.6;
    contract Test {
      uint256 public the_var = 5;
    }
    """
    from ethjsonrpc import EthJsonRpc
    c = EthJsonRpc('127.0.0.1', 9999)
    xx = c.eth_compileSolidity(minimal_code)
    compiled = xx['code']
    contract_tx = c.create_contract(
        c.eth_coinbase(),
        compiled,
        gas=3000000,
    )
    contract_address = str(c.get_contract_address(contract_tx))

    rr = c.call(
        address=contract_address,
        sig='the_var()',
        args=[],
        result_types=['uint256'],
    )

    assert rr[0] == 5, rr
    print('PASSED')
Exemplo n.º 2
0
def setup(f, host, port, add_dev_code, contract_dir, gas, gas_price,
          private_key):
    with open(f) as data_file:
        instructions = json.load(data_file)
    json_rpc = EthJsonRpc(host, port)
    coinbase = json_rpc.eth_coinbase()["result"]
    if private_key:
        print "Your address for your private key: {}".format(
            privtoaddr(private_key.decode('hex')).encode('hex'))
    else:
        print "Your coinbase: {}".format(coinbase)
    for instruction in instructions:
        print 'Your balance: {} Wei'.format(
            int(json_rpc.eth_getBalance(coinbase)['result'], 16))
        if instruction["type"] == "deployment":
            deploy_code(
                json_rpc, coinbase, instruction["file"],
                instruction["constructorParams"]
                if "constructorParams" in instruction else None,
                instruction["addresses"] if "addresses" in instruction else
                None, add_dev_code == "true", contract_dir, int(gas),
                int(gas_price), private_key)
        elif instruction["type"] == "transaction":
            do_transaction(json_rpc, coinbase, instruction["contract"],
                           instruction["name"], instruction["params"],
                           int(gas), int(gas_price), private_key)
        elif instruction["type"] == "assertion":
            do_assertion(json_rpc, instruction["contract"],
                         instruction["name"], instruction["params"],
                         instruction["return"])
    for contract_name, contract_address in addresses.iteritems():
        print 'Contract {} was created at address {}.'.format(
            contract_name, contract_address)
Exemplo n.º 3
0
class AddressToUrlTestCase(unittest.TestCase):

    def setUp(self):
        with open('compiled.evm') as f:
            compiled = f.read().rstrip()
        self.c = EthJsonRpc()
        self.c._call('evm_reset')
        self.cb = self.c.eth_coinbase()
        self.contract_addr = self.AddressToUrl(self.cb, compiled)

    def tearDown(self):
        pass

    def test_set(self):
        url = 'http://www.yahoo.com'
        self.set_url(self.cb, self.contract_addr, url)

        result = self.get_url(self.contract_addr, self.cb[2:])
        self.assertEqual(url, result)

    def test_set_clear(self):
        url = 'http://www.yahoo.com'
        self.set_url(self.cb, self.contract_addr, url)

        result = self.get_url(self.contract_addr, self.cb[2:])
        self.assertEqual(url, result)

        self.set_url(self.cb, self.contract_addr, '')

        result = self.get_url(self.contract_addr, self.cb[2:])
        self.assertEqual('', result)

    def test_get(self):
        result = self.get_url(self.contract_addr, self.cb[2:])
        self.assertEqual('', result)

################################################################################

    def AddressToUrl(self, sender, compiled):
        '''
        constructor
        '''
        sig = 'AddressToUrl()'
        args = []
        tx = self.c.create_contract(sender, compiled, 300000, sig, args)
        return self.c.get_contract_address(tx)

    def set_url(self, sender, contract_addr, ip):
        sig = 'set_url(string)'
        args = [ip]
        self.c.call_with_transaction(sender, contract_addr, sig, args)

    def get_url(self, contract_addr, addr):
        sig = 'get_url(address)'
        args = [addr]
        result_types = ['string']
        return self.c.call(contract_addr, sig, args, result_types)[0]
Exemplo n.º 4
0
class AddressToUrlTestCase(unittest.TestCase):
    def setUp(self):
        with open('compiled.evm') as f:
            compiled = f.read().rstrip()
        self.c = EthJsonRpc()
        self.c._call('evm_reset')
        self.cb = self.c.eth_coinbase()
        self.contract_addr = self.AddressToUrl(self.cb, compiled)

    def tearDown(self):
        pass

    def test_set(self):
        url = 'http://www.yahoo.com'
        self.set_url(self.cb, self.contract_addr, url)

        result = self.get_url(self.contract_addr, self.cb[2:])
        self.assertEqual(url, result)

    def test_set_clear(self):
        url = 'http://www.yahoo.com'
        self.set_url(self.cb, self.contract_addr, url)

        result = self.get_url(self.contract_addr, self.cb[2:])
        self.assertEqual(url, result)

        self.set_url(self.cb, self.contract_addr, '')

        result = self.get_url(self.contract_addr, self.cb[2:])
        self.assertEqual('', result)

    def test_get(self):
        result = self.get_url(self.contract_addr, self.cb[2:])
        self.assertEqual('', result)


################################################################################

    def AddressToUrl(self, sender, compiled):
        '''
        constructor
        '''
        sig = 'AddressToUrl()'
        args = []
        tx = self.c.create_contract(sender, compiled, 300000, sig, args)
        return self.c.get_contract_address(tx)

    def set_url(self, sender, contract_addr, ip):
        sig = 'set_url(string)'
        args = [ip]
        self.c.call_with_transaction(sender, contract_addr, sig, args)

    def get_url(self, contract_addr, addr):
        sig = 'get_url(address)'
        args = [addr]
        result_types = ['string']
        return self.c.call(contract_addr, sig, args, result_types)[0]
Exemplo n.º 5
0
def setup(host, port, contract, gas, gas_price, private_key):
    gas = int(gas)
    gas_price = int(gas_price)
    json_rpc = EthJsonRpc(host, port)
    coinbase = json_rpc.eth_coinbase()["result"]
    if private_key:
        print "Your address for your private key: {}".format(
            privtoaddr(private_key.decode('hex')).encode('hex'))
    else:
        print "Your coinbase: {}".format(coinbase)
    contract_abi = json.loads(
        '[{"inputs": [], "constant": true, "type": "function", "name": "startDate", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "CROWDFUNDING_PERIOD", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "emergencyCall", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [{"type": "address", "name": "singularDTVFundAddress"}, {"type": "address", "name": "singularDTVTokenAddress"}], "constant": false, "type": "function", "name": "setup", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "withdrawFunding", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "fundBalance", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "singularDTVFund", "outputs": [{"type": "address", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "baseValue", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "TOKEN_TARGET", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "singularDTVToken", "outputs": [{"type": "address", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "owner", "outputs": [{"type": "address", "name": ""}]}, {"inputs": [{"type": "uint256", "name": "valueInWei"}], "constant": false, "type": "function", "name": "changeBaseValue", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [{"type": "address", "name": ""}], "constant": true, "type": "function", "name": "investments", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "fund", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "stage", "outputs": [{"type": "uint8", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "updateStage", "outputs": [{"type": "uint8", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "valuePerShare", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "TOKEN_LOCKING_PERIOD", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "campaignEndedSuccessfully", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "workshopWaited2Years", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "CAP", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "withdrawForWorkshop", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "type": "constructor"}]'
    )
    translator = ContractTranslator(contract_abi)
    data = translator.encode("emergencyCall", ()).encode("hex")
    bc_return_val = json_rpc.eth_call(to_address=contract, data=data)["result"]
    result_decoded = translator.decode("emergencyCall",
                                       bc_return_val[2:].decode("hex"))[0]
    if result_decoded:
        if private_key:
            address = privtoaddr(private_key.decode('hex'))
            nonce = int(
                json_rpc.eth_getTransactionCount('0x' + address.encode('hex'))
                ["result"][2:], 16)
            tx = Transaction(nonce, gas_price, gas, contract, 0,
                             data.decode('hex'))
            tx.sign(private_key.decode('hex'))
            raw_tx = rlp.encode(tx).encode('hex')
            transaction_hash = json_rpc.eth_sendRawTransaction(
                "0x" + raw_tx)["result"]
        else:
            transaction_hash = json_rpc.eth_sendTransaction(
                coinbase,
                to_address=contract,
                data=data,
                gas=gas,
                gas_price=gas_price)["result"]
        wait_for_transaction_receipt(json_rpc, transaction_hash)
        print 'Transaction {} for contract {} completed.'.format(
            "emergencyCall", contract)
Exemplo n.º 6
0
class EthereumBlockchain:
    def __init__(self,
                 the_code = False,
                 the_sig = None,
                 the_args = None,
                 the_address = False,
                 rpc_host = DEFAULT_RPC_HOST,
                 rpc_port = DEFAULT_RPC_PORT,
                 background_thread_sleep_time = 1.0,
                 ):
        
        self.con = EthJsonRpc(rpc_host, rpc_port)
        
        self.the_code = the_code
        self.the_sig = the_sig
        self.the_args = the_args
        
        self.contract_address = the_address
        
        assert self.the_code or self.contract_address
        
        self.loop_once_started = False
        
        self.sig_to_topic_id_cache = {}
        
        self.send_transaction_queue = Queue()
        
        self.background_thread_sleep_time = background_thread_sleep_time

        self.pending_transactions = {}  ## {tx:callback}
        
        self.is_deployed = False
        
        if the_address:
            assert self.check_anything_deployed(the_address), ('NOTHING DEPLOYED AT SPECIFIED ADDRESS:', the_address)
            self.is_deployed = True
        elif the_code:
            if auto_deploy:
                self.deploy()

        
    #def setup_create_pending_transaction(func):
    #    self._create_pending_transaction = func
    
    #def setup_logic_callback(func):
    #    self._logic_callback = func
    
    def event_sig_to_topic_id(self, sig):
        """ Compute ethereum topic_ids from function signatures. """
        if sig in self.sig_to_topic_id_cache:
            return self.sig_to_topic_id_cache[sig]
        name = sig[:sig.find('(')]
        types = [x.strip().split()[0] for x in sig[sig.find('(')+1:sig.find(')')].split(',')]
        topic_id = ethereum.utils.int_to_hex(ethereum.abi.event_id(name,types))
        self.sig_to_topic_id_cache[sig] = topic_id
        return topic_id

    def setup_event_callbacks(self,
                              log_handlers,
                              pending_handlers,
                              ):
        self.log_handlers = log_handlers
        self.log_handlers_hashed = {((x == 'DEFAULT') and 'DEFAULT' or self.event_sig_to_topic_id(x)):y
                                    for x,y
                                    in log_handlers.items()}
        self.pending_handlers = pending_handlers
    
    def logic_callback(self, msg, *args, **kw):
        default_func = self.log_handlers_hashed.get('DEFAULT', False)
        
        if 'topics' not in msg:
            assert default_func is not False, ('Unknown topic_id and no DEFAULT handler.')
            print ('PROXY logic_callback()', '->', default_func, kw)
            default_func(msg, *args, **kw)
            return
        
        for topic in msg['topics']:
            func = self.log_handlers_hashed.get(topic, default_func)
            print ('PROXY logic_callback()', topic, '->', func)
            assert func is not False, ('Unknown topic_id and no DEFAULT handler.', topic, kw)
            func(msg, *args, **kw)
    
    def simulate_pending(self,
                         args_sig,
                         args,
                         *aa, **bb):
        """ 
        See: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#events 
        """
        ## TODO: support indexed topics?
        
        func = self.pending_handlers.get(args_sig, self.pending_handlers.get('DEFAULT', False))
        
        print ('Proxy: simulate_pending()', args_sig, '->', func)
        
        return func(args_sig, args, *aa, **bb)

    def get_block_by_hash_callback(self, block_hash):
        """
        Get block by blockHash.
        
        https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblockbyhash
        """
        print ('bcc.get_block_by_hash_callback()', block_hash)

        rh = self.con.eth_getBlockByHash(block_hash)
        
        for k in ['number', 'timestamp']:
            rh[k] = ethereum.utils.parse_int_or_hex(rh[k])
        
        return rh
        
    
    def get_logs_by_block_num_callback(self, block_num):
        """
        Get event logs for a particular block num. It's OK if the block_num has an unexpected hash, 
        that'll be taken care of by caller.
        
        https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getlogs
        """
        print ('bcc.get_logs_by_block_num_callback()', block_num)
        
        the_filter = self.con.eth_newFilter(from_block =  fixed_int_to_hex(block_num),
                                            to_block = fixed_int_to_hex(block_num),
                                            address = self.contract_address,
                                            )
        
        rr =  self.con.eth_getFilterLogs(str(the_filter))

        rr2 = []
        for msg in rr:
            #assert 'topics' in msg, list(sorted(msg.keys()))
            got_num = ethereum.utils.parse_int_or_hex(msg['blockNumber'])
            if got_num != block_num:
                continue
            msg['data'] = solidity_string_decode(msg['data'])
            msg['blockNumber'] = got_num
            msg["logIndex"] = ethereum.utils.parse_int_or_hex(msg['logIndex'])
            msg["transactionIndex"] = ethereum.utils.parse_int_or_hex(msg['transactionIndex'])
            #msg_data = loads_compact(msg['data'])
            #payload_decoded = loads_compact(msg_data['payload'])
            rr2.append(msg)
        rr = rr2
        
        return rr

    def get_latest_block_number(self):
        print ('bcc.get_latest_block_number()')
        bn = self.con.eth_blockNumber()
        return bn
    
    def get_latest_block_callback(self):
        """
        Returns the single latest block. Missing intermediate blocks will be automatically looked up by caller.
        """
        print ('bcc.get_latest_block_callback()')
        bn = self.get_latest_block_number()
        block = self.con.eth_getBlockByNumber(bn)
        return block

                
    def check_anything_deployed(self, address):
        """ Basic sanity check, checks if ANY code is deployed at provided address. """
        print ('bcc.check_anything_deployed()', address)
        if self.con.eth_getCode(address) == '0x0':
            return False
        return True
            
    def deploy(self,
               the_sig = False,
               the_args = False,
               block = False,
               deploy_from = False,
               callback = False,
               ):
        """ Deploy contract. Optional args_sig and args used to pass arguments to contract constructor."""
        print ('bcc.deploy()')

        if the_sig is not False:
            self.contract_sig = the_sig
        
        if the_args is not False:
            self.contract_args = the_args

        assert self.the_code

        if deploy_from is False:
            deploy_from = self.con.eth_coinbase()
        
        print ('DEPLOYING_CONTRACT...', 'deploy_from:', deploy_from, 'the_sig:', the_sig, 'the_args:', the_args)        
        # get contract address
        xx = self.con.eth_compileSolidity(self.the_code)
        #print ('GOT',xx)
        
        compiled = None
        
        try:
            compiled = xx['code']
        except KeyError:
            # geth seems to like putting the compiler output into an inner dict keyed by input filename,
            # e.g {'CCCoinToken.sol': {'code': '...', 'etc': '...'}
            for k, v in xx.iteritems():
                if isinstance(v, dict) and 'code' in v:
                    compiled = v['code']
                    break
        
        assert compiled
        
        contract_tx = self.con.create_contract(from_ = deploy_from,
                                               code = compiled,
                                               gas = 3000000,
                                               sig = self.contract_sig,
                                               args = self.contract_args,
                                               )

        if block:
            ## NOTE: @yusef feel free to switch back to this method if you want:
            #print('CONTRACT DEPLOYED, WAITING FOR CONFIRMATION')
            #wait_for_confirmation(self.c, contract_tx)
            
            print ('BLOCKING FOR RECEIPT..')
            while True:
                receipt = self.con.eth_getTransactionReceipt(contract_tx) ## blocks to ensure transaction is mined
                if receipt:
                    break
                sleep(self.blocking_sleep_time)
            print ('GOT RECEIPT')
        else:
            self.pending_transactions[contract_tx] = callback
        
        self.contract_address = str(self.con.get_contract_address(contract_tx))
        self.is_deployed = True
        print ('DEPLOYED', self.contract_address)
        return self.contract_address

    def send_transaction(self, *args, **kw):
        """
        1) If possible create simulated outputs of transactions, to use as pending state.
        2) Queue the transaction for blockchain commit.
        
        Used for e.g.:
        - addLog(bytes)
        - mintTokens(address, uint, uint, uint, uint, uint, uint)
        - withdrawTok(bytes)
        - lockupTok(bytes)
        """
        print ('bcc.send_transaction()')

        assert len(args) <= 2
        #assert self.loop_once_started, 'loop_once() not started?'

        ## Potentially slow blocking call to commit it to the blockchain:

        if kw.get('block'):
            ## Send transaction in blocking mode, and grab actual event logs that are committed:

            rh = self.inner_send_transaction(*args, **kw)
            pending_logs = rh['pending_logs']
            is_pending = False
            
        else:
            ## Run callbacks, return simulated event logs where possible:

            self.send_transaction_queue.put((0, args, kw))
            pending_logs = self.simulate_pending(*args, **kw)
            is_pending = True
        
        ## Run logic_callback() against pending transactions:
        
        for log in pending_logs:
            print ('CALLING', 'is_pending:', is_pending, 'is_noop:', log.get('is_noop', False))
                                
            self.logic_callback(log,
                                is_pending = is_pending,
                                is_noop = log.get('is_noop', False)
                                )

        return pending_logs
            
    def inner_send_transaction(self,
                               args_sig,
                               args,
                               callback = False,
                               send_from = False,
                               block = False,
                               gas_limit = False,
                               gas_price = 100,
                               value = 100000000000,
                               ):
        """
        1) Attempt to send transaction.
        2) Get first confirmation via transaction receipt.
        3) Re-check receipt again after N blocks pass.
        
        https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sendtransaction
        """
        print ('bcc.inner_send_transaction()')

        assert self.is_deployed, 'Must deploy contract first.'

        print ('SEND_TRANSACTION:', args_sig, args)

        if send_from is False:
            send_from = self.con.eth_coinbase()
        
        send_to = self.contract_address 

        print ('====TRANSACTION')
        print ('send_from', send_from)
        print ('send_to', send_to)
        print ('args_sig', args_sig)
        print ('args', args)
        #print ('gas', gas_limit)
        
        gas_limit = 1000000
        gas_price = self.con.DEFAULT_GAS_PRICE
        value = web3.utils.currency.to_wei(1,'ether')

        data = self.con._encode_function(args_sig, args)
        data_hex = '0x' + data.encode('hex')
        
        tx = self.con.eth_sendTransaction(from_address = send_from,
                                          to_address = send_to,
                                          data = data_hex,
                                          gas = gas_limit,
                                          gas_price = gas_price,
                                          value = value,
                                          )
        
        if block:
            print ('BLOCKING FOR RECEIPT..')
            while True:
                receipt = self.con.eth_getTransactionReceipt(tx) ## blocks to ensure transaction is mined
                if receipt:
                    break
                sleep(self.blocking_sleep_time)
            print ('GOT RECEIPT')
            #print ('GOT_RECEIPT', receipt)
            #if receipt['blockNumber']:
            #    self.latest_block_num = max(ethereum.utils.parse_int_or_hex(receipt['blockNumber']), self.latest_block_num)
        else:
            self.pending_transactions[tx] = callback
        
        #self.latest_block_num = self.con.eth_blockNumber()
        
        return {'tx':tx}

    def poll_outgoing_receipts(self):
        """
        Check for transaction receipts on transactions sent from this node.
        TODO - why not replace this with just watching for incoming transactions???
        """
        
        assert self.is_deployed, 'Must deploy contract first.'

        had_any_events = False
        if self.pending_transactions:
            had_any_events = True
        
        for tx, callback in self.pending_transactions.items():
            
            receipt = self.con.eth_getTransactionReceipt(tx)
            
            if receipt is not None and 'blockNumber' in receipt:
                actual_block_number = ethereum.utils.parse_int_or_hex(receipt['blockNumber'])
            else:
                ## TODO: wasn't confirmed after a long time.
                actual_block_number = False
            
            ## Now compare against the block_number where it was actually included:
            
            if actual_block_number is not False:
                if callback is not False:
                    callback(receipt)
                del self.pending_transactions[tx]
        
        return had_any_events
    
    
    def _start_background_thread(self,
                                 terminate_on_exception = False,
                                 ):
        last_event = False
        
        while True:
            try:
                had_any_events = self.loop_once_blockchain()
            except Exception as e:
                print ('-----LOOP_ONCE_EXCEPTION', e)
                #exit(-1)
                raise
                
                if terminate_on_exception:
                    raise
                continue
            
            if had_any_events:
                last_event = time()
            else:
                print ('NO_NEW_EVENTS', last_event and (time() - last_event))
            
            sleep(self.background_thread_sleep_time)
    
    def start_background_thread(self,
                                start_in_foreground = False,
                                terminate_on_exception = False,
                                ):
        """
        Start ContractWrapper loop_once() in background thread, which (in that thread!) calls back to self.process_event()
        """
        if start_in_foreground:
            self._start_background_thread(terminate_on_exception = terminate_on_exception)
        else:
            self.t = Thread(target = self._start_background_thread,
                            args = (terminate_on_exception,),
                            )
            self.t.daemon = True
            self.t.start()
    
            

    def loop_once_blockchain(self):
        ## Check for available write receipts:
        #self.poll_outgoing_receipts()

        self.loop_once_started = True
        
        ## Do write transactions transactions:
        
        while self.send_transaction_queue.qsize():
            print ('TRY_TO_SEND')
            tries, args, kw = self.send_transaction_queue.get()
            try:
                self.inner_send_transaction(*args, **kw)
            except Exception as e:
                print ('FAILED_TO_SEND', e, tries, args, kw)
                sleep(1) ## TODO
                self.send_transaction_queue.put((tries + 1, args, kw))
                break
Exemplo n.º 7
0
vibrationCountThreshold = 1000

while True:
    line = serialTTL.readline()
    data = line.split(',')
    vibration = data[0]
    temperature = data[1]

    if (vibration > vibrationThreshold):
        vibrationCount = vibrationCount + 1

    if (temperature > tempThreshold):
        tempCount = tempCount + 1

    ts = int(time.time())
    if (vibrationCount > vibrationCountThreshold):
        #Send a transaction to requestService function of
        #MachineService contract with Machine-ID
        c.call_with_transaction(c.eth_coinbase(), contract_addr,
                                'requestService(uint256,uint256,string)',
                                [ts, machineID, 'High vibrations'])
        vibrationCount = 0

    if (tempCount > tempCountThreshold):
        c.call_with_transaction(c.eth_coinbase(), contract_addr,
                                'requestService(uint256,uint256,string)',
                                [ts, machineID, 'High temperature'])
        tempCount = 0

    time.sleep(1)
Exemplo n.º 8
0
class LiteIDContract:
    def __init__(self, ip='127.0.0.1', port=8545, contract_id=None):
        self.connection = EthJsonRpc(ip, port)
        self.contract_id = contract_id
        self.abi_def = [{
            "constant":
            False,
            "inputs": [],
            "name":
            "dumpSaltedHashArray",
            "outputs": [{
                "name": "Hashes",
                "type": "bytes32[]"
            }, {
                "name": "Salts",
                "type": "bytes32[]"
            }, {
                "name": "Timestamps",
                "type": "uint256[]"
            }],
            "payable":
            False,
            "type":
            "function"
        }, {
            "constant":
            False,
            "inputs": [{
                "name": "Hash",
                "type": "bytes32"
            }, {
                "name": "Salt",
                "type": "bytes32"
            }],
            "name":
            "addHash",
            "outputs": [],
            "payable":
            False,
            "type":
            "function"
        }, {
            "inputs": [{
                "name": "Hash",
                "type": "bytes32"
            }, {
                "name": "Salt",
                "type": "bytes32"
            }],
            "payable":
            False,
            "type":
            "constructor"
        }]

    @staticmethod
    def _calculate_hash(data_to_hash):
        salt = SHA256.new()
        salt.update(bytes(random.getrandbits(256)))
        original_hash = SHA256.new()
        original_hash.update(data_to_hash)
        salted_hash = SHA256.new()
        salted_hash.update(original_hash.digest() + salt.digest())
        salt = salt.hexdigest().decode("hex")
        original_hash = original_hash.hexdigest().decode("hex")
        salted_hash = salted_hash.hexdigest().decode("hex")
        return salted_hash, salt, original_hash, data_to_hash

    def unlock_account(self, account, password):
        self.connection._call('personal_unlockAccount',
                              params=[account, password, 36000])

    def add_hash(self, data):
        if self.contract_id is None:
            raise IOError
        salted_hash, salt, original_hash, _ = self._calculate_hash(data)
        tx = self.connection.call_with_transaction(
            self.connection.eth_coinbase(), self.contract_id,
            'addHash(bytes32,bytes32)', [salted_hash, salt])
        print("Waiting for addHash to be mined")
        while self.connection.eth_getTransactionReceipt(tx) is None:
            time.sleep(1)
        return original_hash

    def create_contract(self, data):
        if not hasattr(self, 'byte_code'):
            contract_file = open(__file__[:-11] + '\LiteID-Contract.sol')
            code_data = self.connection.eth_compileSolidity(
                contract_file.read())
            self.byte_code = code_data['ID']['code']
            self.abi_def = code_data['ID']['info']['abiDefinition']
        salted_hash, salt, original_hash, _ = self._calculate_hash(data)
        tx_id = self.connection.create_contract(self.connection.eth_coinbase(),
                                                self.byte_code,
                                                300000,
                                                sig='addHash(bytes32,bytes32)',
                                                args=[salted_hash, salt])
        print("Waiting for contract to be mined")
        while self.connection.eth_getTransactionReceipt(tx_id) is None:
            time.sleep(1)
        self.contract_id = self.connection.eth_getTransactionReceipt(
            tx_id)['contractAddress']
        return self.contract_id

    def dump_hashes(self):
        return_types = list()
        for item in self.abi_def:
            try:
                if item['name'] == 'dumpSaltedHashArray':
                    for i in item['outputs']:
                        return_types.append(i['type'])
            except KeyError:
                pass
        return_types = ['bytes32[]', 'bytes32[]', 'uint256[]']
        return self.connection.call(self.contract_id, 'dumpSaltedHashArray()',
                                    [], return_types)
Exemplo n.º 9
0
class Deploy:
    def __init__(self, protocol, host, port, add_dev_code, verify_code,
                 contract_dir, gas, gas_price, private_key):
        self.pp = PreProcessor()
        self.s = t.state()
        self.s.block.number = 1150000  # Homestead
        t.gas_limit = int(gas)
        self.json_rpc = EthJsonRpc(protocol=protocol, host=host, port=port)
        if private_key:
            self.user_address = '0x' + privtoaddr(
                private_key.decode('hex')).encode('hex')
        else:
            self.user_address = self.json_rpc.eth_coinbase()["result"]
        self.add_dev_code = add_dev_code == 'true'
        self.verify_code = verify_code == 'true'
        self.contract_dir = contract_dir
        self.gas = int(gas)
        self.gas_price = int(gas_price)
        self.private_key = private_key
        self.contract_addresses = {}
        self.contract_abis = {}

    def wait_for_transaction_receipt(self, transaction_hash):
        while self.json_rpc.eth_getTransactionReceipt(
                transaction_hash)['result'] is None:
            logging.info(
                'Waiting for transaction receipt {}'.format(transaction_hash))
            time.sleep(5)

    def replace_address(self, a):
        return self.contract_addresses[a] if isinstance(
            a, basestring) and a in self.contract_addresses else a

    def get_nonce(self):
        return int(
            self.json_rpc.eth_getTransactionCount(
                self.user_address)["result"][2:], 16)

    def get_raw_transaction(self, data, contract_address=''):
        nonce = self.get_nonce()
        tx = Transaction(nonce, self.gas_price, self.gas, contract_address, 0,
                         data.decode('hex'))
        tx.sign(self.private_key.decode('hex'))
        return rlp.encode(tx).encode('hex')

    def code_is_valid(self, contract_address, compiled_code):
        deployed_code = self.json_rpc.eth_getCode(contract_address)["result"]
        locally_deployed_code_address = self.s.evm(
            compiled_code.decode("hex")).encode("hex")
        locally_deployed_code = self.s.block.get_code(
            locally_deployed_code_address).encode("hex")
        return deployed_code == "0x" + locally_deployed_code

    @staticmethod
    def compile_code(code, language):
        combined = languages[language].combined(code)
        compiled_code = combined[-1][1]["bin_hex"]
        abi = combined[-1][1]["abi"]
        return compiled_code, abi

    @staticmethod
    def replace_library_placeholders(bytecode, addresses):
        if addresses:
            for library_name, library_address in addresses.iteritems():
                bytecode = bytecode.replace(
                    "__{}{}".format(library_name,
                                    "_" * (38 - len(library_name))),
                    library_address[2:])
        return bytecode

    def deploy_code(self, file_path, params, addresses):
        if addresses:
            addresses = dict([(k, self.replace_address(v))
                              for k, v in addresses.iteritems()])
        language = "solidity" if file_path.endswith(".sol") else "serpent"
        code = self.pp.process(file_path,
                               add_dev_code=self.add_dev_code,
                               contract_dir=self.contract_dir,
                               addresses=addresses)
        # compile code
        bytecode, abi = self.compile_code(code, language)
        # replace library placeholders
        bytecode = self.replace_library_placeholders(bytecode, addresses)
        if params:
            translator = ContractTranslator(abi)
            # replace constructor placeholders
            params = [self.replace_address(p) for p in params]
            bytecode += translator.encode_constructor_arguments(params).encode(
                "hex")
        logging.info(
            'Try to create contract with length {} based on code in file: {}'.
            format(len(bytecode), file_path))
        if self.private_key:
            raw_tx = self.get_raw_transaction(bytecode)
            tx_response = self.json_rpc.eth_sendRawTransaction("0x" + raw_tx)
            while "error" in tx_response:
                logging.info('Deploy failed with error {}. Retry!'.format(
                    tx_response['error']))
                time.sleep(5)
                tx_response = self.json_rpc.eth_sendRawTransaction("0x" +
                                                                   raw_tx)
        else:
            tx_response = self.json_rpc.eth_sendTransaction(
                self.user_address,
                data=bytecode,
                gas=self.gas,
                gas_price=self.gas_price)
            while "error" in tx_response:
                logging.info('Deploy failed with error {}. Retry!'.format(
                    tx_response['error']))
                time.sleep(5)
                tx_response = self.json_rpc.eth_sendTransaction(
                    self.user_address,
                    data=bytecode,
                    gas=self.gas,
                    gas_price=self.gas_price)
        transaction_hash = tx_response['result']
        self.wait_for_transaction_receipt(transaction_hash)
        contract_address = self.json_rpc.eth_getTransactionReceipt(
            transaction_hash)["result"]["contractAddress"]
        # Verify deployed code with locally deployed code
        if self.verify_code and not self.code_is_valid(contract_address,
                                                       bytecode):
            logging.info('Deploy of {} failed. Retry!'.format(file_path))
            self.deploy_code(file_path, params, addresses)
        contract_name = file_path.split("/")[-1].split(".")[0]
        self.contract_addresses[contract_name] = contract_address
        self.contract_abis[contract_name] = abi
        logging.info('Contract {} was created at address {}.'.format(
            file_path, contract_address))

    def send_transaction(self, contract, name, params):
        contract_address = self.replace_address(contract)
        contract_abi = self.contract_abis[contract]
        translator = ContractTranslator(contract_abi)
        data = translator.encode(name,
                                 [self.replace_address(p)
                                  for p in params]).encode("hex")
        logging.info('Try to send {} transaction to contract {}.'.format(
            name, contract))
        if self.private_key:
            raw_tx = self.get_raw_transaction(data, contract_address)
            tx_response = self.json_rpc.eth_sendRawTransaction("0x" + raw_tx)
            while 'error' in tx_response:
                logging.info('Transaction failed with error {}. Retry!'.format(
                    tx_response['error']))
                time.sleep(5)
                tx_response = self.json_rpc.eth_sendRawTransaction("0x" +
                                                                   raw_tx)
        else:
            tx_response = self.json_rpc.eth_sendTransaction(
                self.user_address,
                to_address=contract_address,
                data=data,
                gas=self.gas,
                gas_price=self.gas_price)
            while 'error' in tx_response:
                logging.info('Transaction failed with error {}. Retry!'.format(
                    tx_response['error']))
                time.sleep(5)
                tx_response = self.json_rpc.eth_sendTransaction(
                    self.user_address,
                    to_address=contract_address,
                    data=data,
                    gas=self.gas,
                    gas_price=self.gas_price)
        transaction_hash = tx_response['result']
        self.wait_for_transaction_receipt(transaction_hash)
        logging.info('Transaction {} for contract {} completed.'.format(
            name, contract))

    def assert_call(self, contract, name, params, return_value):
        contract_address = self.replace_address(contract)
        return_value = self.replace_address(return_value)
        contract_abi = self.contract_abis[contract]
        translator = ContractTranslator(contract_abi)
        data = translator.encode(name,
                                 [self.replace_address(p)
                                  for p in params]).encode("hex")
        logging.info('Try to assert return value of {} in contract {}.'.format(
            name, contract))
        bc_return_val = self.json_rpc.eth_call(to_address=contract_address,
                                               data=data)["result"]
        result_decoded = translator.decode(name,
                                           bc_return_val[2:].decode("hex"))
        result_decoded = result_decoded if len(
            result_decoded) > 1 else result_decoded[0]
        assert result_decoded == return_value
        logging.info(
            'Assertion successful for return value of {} in contract {}.'.
            format(name, contract))

    def process(self, f):
        with open(f) as data_file:
            instructions = json.load(data_file)
            logging.info('Your address: {}'.format(self.user_address))
            for instruction in instructions:
                logging.info('Your balance: {} Wei'.format(
                    int(
                        self.json_rpc.eth_getBalance(
                            self.user_address)['result'], 16)))
                if instruction["type"] == "deployment":
                    self.deploy_code(
                        instruction["file"],
                        instruction["params"]
                        if "params" in instruction else None,
                        instruction["addresses"]
                        if "addresses" in instruction else None,
                    )
                elif instruction["type"] == "transaction":
                    self.send_transaction(
                        instruction["contract"],
                        instruction["name"],
                        instruction["params"]
                        if "params" in instruction else [],
                    )
                elif instruction["type"] == "assertion":
                    self.assert_call(
                        instruction["contract"], instruction["name"],
                        instruction["params"] if "params" in instruction else
                        [], instruction["return"])
            for contract_name, contract_address in self.contract_addresses.iteritems(
            ):
                logging.info('Contract {} was created at address {}.'.format(
                    contract_name, contract_address))
Exemplo n.º 10
0
contract_address = '0x016D9579a34F7855D5A954d127469260e7F3A5a4'
machineID = 123

# Connect to Blockchain network  -- Ganache
# 
c = EthJsonRpc('192.168.1.4', 8101)
tempCount = 0
tempThreshold = 20 #Celcius
tempCountThreshold = 10
while True:
    f = open(device_file, 'r')
    lines = f.readlines()
    
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temperature = float(temp_string)/1000.0
print "Temp:", temperature, "C"
if(temperature>tempThreshold):
        tempCount = tempCount + 1
ts = int(time.time())
     	print ("ts: ", ts)
if(tempCount>tempCountThreshold):
        c.call_with_transaction(c.eth_coinbase(), contract_address, 'requestService(uint256,uint256,string)', [ts, machineID, 'High'])
        tempCount = 0
    time.sleep(1):
Exemplo n.º 11
0
from ethjsonrpc import EthJsonRpc  # to use Parity-specific methods, import ParityEthJsonRpc

base_address = "0xbb1588c5debc2871cd8852c4bd6c6e4cb1d9fe15"
c = EthJsonRpc('127.0.0.1', 8545)
print(c.net_version())
print(c.web3_clientVersion())
print(c.net_listening())
print(c.net_peerCount())
print(c.eth_mining())
print(c.eth_gasPrice())

contract_addr = "0xc1bba31875a1a66eb4794e6e4dd07811fb58b5c5"
my_addr = str(c.eth_coinbase())
print my_addr
tx = c.call_with_transaction(my_addr, contract_addr, 'pushByte(string)',
                             ['Hello, world'])
print(tx)

results = c.call(contract_addr, 'getdata()', [], ['string'])
print(results)
vibrationCountThreshold = 1000

while True:
  line = serialTTL.readline()
  data = line.split(',')
  vibration = data[0]  
  temperature = data[1]
  
  if(vibration>vibrationThreshold):
    vibrationCount = vibrationCount+1

  if(temperature>tempThreshold):
    tempCount = tempCount+1

  ts = int(time.time())
  if(vibrationCount>vibrationCountThreshold):
     #Send a transaction to requestService function of 
     #MachineService contract with Machine-ID
    c.call_with_transaction(c.eth_coinbase(), 
    contract_addr, 'requestService(uint256,uint256,string)', 
    [ts, machineID, 'High vibrations'])
    vibrationCount = 0    

  if(tempCount>tempCountThreshold):
    c.call_with_transaction(c.eth_coinbase(), 
    contract_addr, 'requestService(uint256,uint256,string)', 
    [ts, machineID, 'High temperature'])
    tempCount = 0

  time.sleep(1)    
Exemplo n.º 13
0
import json
from ethjsonrpc import EthJsonRpc

eth = EthJsonRpc("ethereum", 8545)

with open("VarStore.sol") as f:
    contract = eth.eth_compileSolidity(f.read())
transaction = eth.create_contract(eth.eth_coinbase(),
                                  contract['VarStore']['code'],
                                  gas=300000)
contract["transaction"] = transaction
contract["account"] = eth.eth_coinbase()
print json.dumps(contract)
Exemplo n.º 14
0
        s = rpcaddr.split(":")
        netaddr = s[0]
        port = int(s[1])
    else:
        netaddr = rpcaddr
        port = ETH_PORT
    return (netaddr, port)


if __name__ == "__main__":
    # parse arguments
    parser = argparse.ArgumentParser(description='.')
    parser.add_argument("rpcaddr",
                        help="RPC address of an ethereum node",
                        default="127.0.0.1:8545")
    parser.add_argument("-w",
                        "--wallet",
                        help="etherbase/wallet address",
                        default="0")
    args = parser.parse_args()

    netaddr, port = parseRpcAddr(args.rpcaddr)
    eth_client = EthJsonRpc(netaddr, port)
    if args.wallet == "0":
        wallet = eth_client.eth_coinbase()
    else:
        wallet = args.wallet

    balance = eth_client.eth_getBalance(wallet)
    print balance
def main():

    CONTRACT = sys.argv[1]
    #
    # just load contract code from file (e.g. contract.sol)
    #
    assert os.path.isfile(CONTRACT) and 'contract file not found ({})'.format(
        CONTRACT)
    with open(CONTRACT, 'r') as f:
        CONTRACT_CODE = f.read()

    #
    # now, just connect to our own blockchain node via rpc interface
    #
    try:
        rpc = EthJsonRpc(RPC_HOST, RPC_PORT)
        print('-' * 80)
        print('client software: {}'.format(rpc.web3_clientVersion()))
        print('block: {}'.format(rpc.eth_blockNumber()))
        print('address: {}'.format(rpc.eth_coinbase()))
    except:
        print('unable to connect to rpc server at {}:{}'.format(
            RPC_HOST, RPC_PORT))
        sys.exit(-1)

    #
    # compile contract
    #
    print('-' * 80)
    print('compiling contract...')
    compiled = rpc.eth_compileSolidity(CONTRACT_CODE)
    contract_bin = compiled['code']

    #
    # create contract
    #
    print('-' * 80)
    lastBlock = rpc.eth_blockNumber()
    contract_tx = rpc.create_contract(rpc.eth_coinbase(),
                                      contract_bin,
                                      gas=GAS)
    print('contract sent, waiting for it to be mined...')
    #
    # get current block count
    #
    numTry = 0
    contract_addr = None
    while True:
        curBlock = rpc.eth_blockNumber()
        if curBlock > lastBlock:
            lastBlock = curBlock
            numTry += 1
            try:
                contract_addr = rpc.get_contract_address(contract_tx)
                if rpc.eth_getCode(contract_addr) == '0x0':
                    raise Exception()
                print('contract mined (block: {})'.format(curBlock))
                break
            except:
                print('new block detected, but contract not mined')
                if numTry == WAIT_BLOCKS:
                    print('publishing contract failed')
                    sys.exit(-1)
        time.sleep(1)
    #
    # return contract addr
    #
    print('-' * 80)
    print('contract_address:\n\n\n--> {} <--\n\n'.format(contract_addr))
    print('-' * 80)
Exemplo n.º 16
0
        return self.connection.call(self.contract_id, 'dumpSaltedHashArray()',
                                    [], return_types)


if __name__ == "__main__":
    a = LiteIDContract(
        contract_id=u'0xB2a045bb7D0eb64BD044763ae572077E5182247B')
    a.unlockAccount("0x2fe84be2806ecef45adef9699d5a6f1939d0a377", "mypassword")
    #a.create_contranct("lol")

    a.addHash("hi")

    c = EthJsonRpc('127.0.0.1', 8545)

    tx = c.call_with_transaction(
        c.eth_coinbase(), a.contract_id, 'addHash(bytes32,bytes32)', [
            '79d3b5b20c84c399e403048359def1398b729ac9a2d88485972be2e691af46de'.
            decode("hex"),
            '5e408dafb1164edde8e95527f9a4bd2abb3bd55fb4e32f8f5ea806a683fccbd6'.
            decode("hex")
        ])

    while c.eth_getTransactionReceipt(tx) is None:
        pass

    print "Contranct id: {}".format(a.contract_id)

    for item in a.dump_hashes():
        print item

# Salted Hash: 0x62335b41ea49e29b99bd8767324dc4b5e3453a77c74883078ebcafc7589f0605
Exemplo n.º 17
0
class Ipv4TestCase(unittest.TestCase):

    def setUp(self):
        with open('compiled.evm') as f:
            compiled = f.read().rstrip()
        self.c = EthJsonRpc()
        self.c._call('evm_reset')
        self.cb = self.c.eth_coinbase()
        self.contract_addr = self.AddressToIPv4(self.cb, compiled)

    def tearDown(self):
        pass

################################################################################

    def test_read(self):
        result = self.get_ip(self.contract_addr, self.cb[2:])
        unchained_ip = self.ip_from_chain(result)
        self.assertEqual('0.0.0.0', unchained_ip)

    def test_set_read(self):
        ip = u'192.168.1.1'
        chained_ip = self.ip_to_chain(ip)
        self.set_ip(self.cb, self.contract_addr, chained_ip)

        result = self.get_ip(self.contract_addr, self.cb[2:])
        unchained_ip = self.ip_from_chain(result)
        self.assertEqual(ip, unchained_ip)

    def test_set_delete_read(self):
        ip = u'192.168.1.1'
        chained_ip = self.ip_to_chain(ip)
        self.set_ip(self.cb, self.contract_addr, chained_ip)

        self.delete_ip(self.cb, self.contract_addr)

        result = self.get_ip(self.contract_addr, self.cb[2:])
        unchained_ip = self.ip_from_chain(result)
        self.assertEqual('0.0.0.0', unchained_ip)


################################################################################

    def ip_to_chain(self, ip):
        return int(IPv4Address(ip))

    def ip_from_chain(self, ip):
        return str(IPv4Address(ip))

################################################################################

    def AddressToIPv4(self, sender, compiled):
        '''
        constructor
        '''
        sig = 'AddressToIPv4()'
        args = []
        tx = self.c.create_contract(sender, compiled, sig, args)
        return self.c.get_contract_address(tx)

    def set_ip(self, sender, contract_addr, ip):
        sig = 'set_ip(uint32)'
        args = [ip]
        self.c.call_with_transaction(sender, contract_addr, sig, args)

    def delete_ip(self, sender, contract_addr):
        sig = 'delete_ip()'
        args = []
        self.c.call_with_transaction(sender, contract_addr, sig, args)

    def get_ip(self, contract_addr, addr):
        sig = 'get_ip(address)'
        args = [addr]
        result_types = ['uint32']
        return self.c.call(contract_addr, sig, args, result_types)[0]
        ReturnValues="UPDATED_NEW")


args = parse_args()

cloudwatch = boto3.resource('cloudwatch', region_name=PRIMARY_REGION)
dynamodb = boto3.resource('dynamodb', region_name=PRIMARY_REGION)
eth_client = EthJsonRpc(args.rpc_address, args.rpc_port)

new_block_metric = cloudwatch.Metric(CLOUDWATCH_NAMESPACE, CLOUDWATCH_METRIC)
block_count_table_name = "quorum-net-%s-blocks-by-region" % (args.network_id)
block_count_table = dynamodb.Table(block_count_table_name)

while True:
    try:
        coinbase = eth_client.eth_coinbase()
        block_filter = eth_client.eth_newBlockFilter()
        break
    except:
        print "Error contacting geth node. Waiting %d seconds and retrying." % (
            SLEEP_SECONDS)
        time.sleep(SLEEP_SECONDS)

while True:
    new_blocks = eth_client.eth_getFilterChanges(block_filter)
    for block_hash in new_blocks:
        block = eth_client.eth_getBlockByHash(block_hash)
        miner = block['miner']
        if miner == coinbase:
            emit_block_creation_metric(new_block_metric)
            update_dynamodb_block_count(block_count_table)
def main():
    #
    # check
    #
    assert os.path.isfile(CONTRACT) and 'contract file not found'

    #
    # now, just connect to our own blockchain node via rpc interface
    #
    try:
        rpc = EthJsonRpc(RPC_HOST, RPC_PORT)
        print('-' * 80)
        print('client software: {}'.format(rpc.web3_clientVersion()))
        print('block: {}'.format(rpc.eth_blockNumber()))
        print('address: {}'.format(rpc.eth_coinbase()))
    except:
        print('unable to connect to rpc server at {}:{}'.format(
            RPC_HOST, RPC_PORT))
        sys.exit(-1)

    #
    # compile contract
    #
    print('-' * 80)
    print('compiling contract...')
    os.system('solcjs --bin {} > /dev/null'.format(CONTRACT))
    with open(CONTRACT_COMPILED, 'r') as f:
        contract_bin = f.read()
    print(contract_bin)

    #
    # create contract
    #
    print('-' * 80)
    lastBlock = rpc.eth_blockNumber()
    contract_tx = rpc.create_contract(
        rpc.eth_coinbase(), contract_bin,
        gas=GAS)  #send to address 0 by default to create contract
    print('contract sent, waiting for it to be mined...')
    #
    # get current block count
    #
    numTry = 0
    contract_addr = None
    while True:
        curBlock = rpc.eth_blockNumber()
        if curBlock > lastBlock:
            lastBlock = curBlock
            numTry += 1
            try:
                contract_addr = rpc.get_contract_address(contract_tx)
                if rpc.eth_getCode(
                        contract_addr
                ) == '0x0':  #it means the binary code of the contract is stil under compiling
                    raise Exception()
                print('contract mined (block: {})'.format(curBlock))
                break
            except:
                print('new block detected, but contract not mined')
                print('number of trying: {}'.format(numTry))
                if numTry == WAIT_BLOCKS:
                    print('publishing contract failed')
                    sys.exit(-1)
        time.sleep(1)
    #
    # return contract addr
    #
    print('-' * 80)
    print('contract_address:\n\n\n--> {} <--\n\n'.format(contract_addr))
    print('-' * 80)
def main():
    #
    # receive contract addr
    #
    if len(sys.argv) != 3:
        print('Usage:\npython user.py <contract addr> <account addr>')
        sys.exit(-1)
    contract_addr = sys.argv[1]
    account_addr = sys.argv[2]

    #
    # create rpc interface
    #
    try:
        print('-' * 80)
        rpc = EthJsonRpc(RPC_HOST, RPC_PORT)
        print('client software: {}'.format(rpc.web3_clientVersion()))
        print('block: {}'.format(rpc.eth_blockNumber()))
        print('address: {}'.format(rpc.eth_coinbase()))
    except:
        print('unable to connect to rpc server at {}:{}'.format(
            RPC_HOST, RPC_PORT))
        sys.exit(-1)

    #
    # check contract is online
    #
    print('-' * 80)
    if rpc.eth_getCode(contract_addr) == '0x0':
        print('!!! contract code not available on blockchain !!!')
        sys.exit(-1)
    print('found contract on blockchain!')

    #
    # console
    #
    topics = []
    print('-' * 80)
    print('starting chat command line...')
    while True:
        #
        # simply read input
        #
        sys.stdout.write('>> ')
        command = sys.stdin.readline()

        #
        # quit?
        #
        if 'q' in command:
            sys.exit(0)

        #
        # show help
        #
        elif command == '\n' or 'help' in command:
            print('commands: help, send, status, topics, search, listen')

        #
        # compose new message
        #
        elif 'send' in command:
            print('-' * 80)
            print('[composing new message]')
            sys.stdout.write('message....: ')
            msg = sys.stdin.readline().strip()
            sys.stdout.write('image file.: ')
            img = sys.stdin.readline().strip()
            sys.stdout.write('custom tags: ')
            tag = sys.stdin.readline().strip()
            print('-' * 80)
            print('sending...')
            # loading image
            try:
                image = Image.open(img)
            except Exception as e:
                print('loading {} failed'.format(img))
                continue
            # prediction
            print('precessing image...')
            label = ImageClassifier.predict(img)
            if label is None:
                print('classification failed')
                continue
            print('label: {}'.format(label))
            tag += ' #' + label
            bs = ImageHelper.imgToBytes(image)
            tx = rpc.call_with_transaction(
                account_addr,
                contract_addr,
                'setNewUserState(string,bytes,string)', [msg, bs, tag],
                gas=GAS)
            print('done, transaction id: {}'.format(tx))

        #
        # get own last post
        #
        elif 'status' in command:
            print('-' * 80)
            print('[receiving last post]')
            userMessage, userImage, userTags = rpc.call(
                contract_addr, 'getUserState(address)', [account_addr],
                ['string', 'bytes', 'string'])
            if not userMessage:
                print('nothing posted yet')
                continue
            print('  content: {}'.format(userMessage))
            print('  tags...: {}'.format(userTags))
            ImageHelper.bytesToImg(userImage).show()

        #
        # set tag filters
        #
        elif 'topics' in command:
            topics = [t.strip() for t in command.split()[1:]]
            if len(topics) == 0:
                print('please provide actual topics after <topics> command')
                continue
            print('filter set for messages on topics: {}'.format(topics))

        #
        # search complete blockchain for messages with certain tags
        #
        elif 'search' in command:
            if len(topics) == 0:
                print('call topics first')
                continue
            curBlock = rpc.eth_blockNumber()
            for i in range(curBlock + 1):
                for trans in rpc.eth_getBlockByNumber(i)['transactions']:
                    res = Decoder.decodeABI(trans['input'])
                    if res is None:
                        continue
                    msg, code, tags = res
                    if all(t not in tags for t in topics):
                        continue
                    print('-' * 80)
                    print('message from user {} (block {}):'.format(
                        trans['from'], i))
                    print('  content: {}'.format(msg))
                    print('  tags...: {}'.format(tags))
                    ImageHelper.bytesToImg(code).show(title='{}'.format(tags))

        #
        # start listening for messages
        #
        elif 'listen' in command:
            if len(topics) == 0:
                print('call topics first')
                continue
            global LISTENING
            LISTENING = True
            curBlock = rpc.eth_blockNumber()
            while LISTENING:
                newBlock = rpc.eth_blockNumber()
                if newBlock > curBlock:
                    print('new block detected ({})'.format(newBlock))
                    curBlock = newBlock
                    for trans in rpc.eth_getBlockByNumber(
                            newBlock)['transactions']:
                        res = Decoder.decodeABI(trans['input'])
                        if res is None:
                            continue
                        msg, code, tags = res
                        if all(t not in tags for t in topics):
                            continue
                        print('-' * 80)
                        print('message from user {} (block {}):'.format(
                            trans['from'], newBlock))
                        print('  content: {}'.format(msg))
                        print('  tags...: {}'.format(tags))
                        ImageHelper.bytesToImg(code).show(
                            title='{}'.format(tags))
                time.sleep(1)

        #
        # default response
        #
        else:
            print('command not recognized')
Exemplo n.º 21
0
while True:
    ##    f = open(device_file, 'r')
    ##    lines = f.readlines()
    ##
    ##    while lines[0].strip()[-3:] != 'YES':
    ##        time.sleep(0.2)
    ##        lines = read_temp_raw()
    ##    equals_pos = lines[1].find('t=')
    ##    if(equals_pos != -1):
    ##        temp_string = lines[1][equals_pos+2:]
    ##        temperature = float(temp_string)/1000.0
    ##        print "Temp:", temperature, "C"
    humidity, temperature = Adafruit_DHT.read_retry(11, 4)
    print("Temperature")
    print(temperature)
    if (temperature > tempThreshold):
        tempCount = tempCount + 1
        ts = int(time.time())
        print("ts: ", ts)
    if (tempCount > tempCountThreshold):
        print("temp gt threshol")
        #c.call_with_transaction(c.eth_coinbase(), contract_address, 'requestService(uint256,uint256,string)', [ts, machineID1, "Temperature is crossed Treshold"])
        c.call_with_transaction(
            c.eth_coinbase(), contract_address,
            'requestService(uint256,uint256,string)',
            [ts, machineID1, "Please update your Software"])
        print("aftre transaction")
        tempCount = 0
    time.sleep(1)
Exemplo n.º 22
0
class ContractWrapper:
    def __init__(
        self,
        the_code=False,
        the_sig=None,
        the_args=None,
        the_address=False,
        events_callback=False,
        deploy_callback=False,
        blocking_sleep_time=0.1,
        rpc_host=DEFAULT_RPC_HOST,
        rpc_port=DEFAULT_RPC_PORT,
        settings_confirm_states={},
        contract_address=False,
        start_at_current_block=False,
        auto_deploy=True,
        contract_thread_sleep_time=1.0,
        reorg_callback=False,
    ):
        """
        Simple contract wrapper, assists with deploying contract, sending transactions, and tracking event logs.
        
        Args:
        - the_code: solidity code for contract that should be deployed, prior to any operations.
        - the_address: address of already-deployed main contract.
        - contract_address: contract address, from previous `deploy()` call.
        - the_sig: optional constructor signature.
        - the_args: optional constructor args.
        - events_callback: callback for event messages e.g. `TheLog()`, `MintEvent()`, `LockupTokEvent()`, `TransferTokEvent()`.
        - deploy_callback: callback for contract deploys.
        - blocking_sleep_time: time to sleep when blocking and polling for a transaction receipt.
        """

        self.block_details = {}

        self.reorg_callback = reorg_callback
        self.confirmation_tracker = {
        }  ## {'block_hash':{'prev_block_hash':xx, 'block_num':yy}}

        self.done_block_nums = {}  ## {confirm_state:set()}
        self.done_transactions = {}  ## {confirm_state:set()}
        self.prev_block_num = {}  ## {confirm_state:set()}

        self.blocking_sleep_time = blocking_sleep_time

        self.c = EthJsonRpc(rpc_host, rpc_port)

        self.contract_thread_sleep_time = contract_thread_sleep_time

        self.start_at_current_block = start_at_current_block

        self.current_block_at_init = self.c.eth_blockNumber()

        if self.start_at_current_block:
            self.last_incoming_block = max(0, self.current_block_at_init - 1)
        else:
            self.last_incoming_block = 0

        self.starting_block_num = self.last_incoming_block

        self.msgs = {}  ## {block_num:[msg, msg, msg]}

        self.the_code = the_code
        self.the_sig = the_sig
        self.the_args = the_args

        self.contract_address = the_address

        assert self.the_code or self.contract_address

        self.loop_block_num = -1

        self.confirm_states = settings_confirm_states

        self.events_callback = events_callback

        self.pending_transactions = {}  ## {tx:callback}
        self.pending_logs = {}
        self.latest_block_num = -1

        self.latest_block_num_done = 0

        self.send_transaction_queue = Queue()

        self.is_deployed = False

        if auto_deploy:
            if the_address:
                assert self.check_anything_deployed(the_address), (
                    'NOTHING DEPLOYED AT SPECIFIED ADDRESS:', the_address)
                self.is_deployed = True
            elif the_code:
                self.deploy()

    def check_anything_deployed(self, address):
        """ Basic sanity check, checks if ANY code is deployed at provided address. """
        if self.c.eth_getCode(address) == '0x0':
            return False
        return True

    def deploy(
        self,
        the_sig=False,
        the_args=False,
        block=False,
        deploy_from=False,
        callback=False,
    ):
        """ Deploy contract. Optional args_sig and args used to pass arguments to contract constructor."""

        if the_sig is not False:
            self.the_sig = the_sig

        if the_args is not False:
            self.the_args = the_args

        assert self.the_code

        if deploy_from is False:
            deploy_from = self.c.eth_coinbase()

        print('DEPLOYING_CONTRACT...', 'deploy_from:', deploy_from, 'the_sig:',
              the_sig, 'the_args:', the_args)
        # get contract address
        xx = self.c.eth_compileSolidity(self.the_code)
        #print ('GOT',xx)
        compiled = get_compiled_code(xx)

        contract_tx = self.c.create_contract(
            from_=deploy_from,
            code=compiled,
            gas=3000000,
            sig=self.the_sig,
            args=self.the_args,
        )

        if block:
            ## NOTE: @yusef feel free to switch back to this method if you want:
            #print('CONTRACT DEPLOYED, WAITING FOR CONFIRMATION')
            #wait_for_confirmation(self.c, contract_tx)

            print('BLOCKING FOR RECEIPT..')
            while True:
                receipt = self.c.eth_getTransactionReceipt(
                    contract_tx)  ## blocks to ensure transaction is mined
                if receipt:
                    break
                sleep(self.blocking_sleep_time)
            print('GOT RECEIPT')
        else:
            self.pending_transactions[contract_tx] = (callback,
                                                      self.latest_block_num)

        self.contract_address = str(self.c.get_contract_address(contract_tx))
        self.is_deployed = True
        print('DEPLOYED', self.contract_address)
        return self.contract_address

    def loop_once(self):
        assert self.is_deployed, 'Must deploy contract first.'

        had_any_events = False

        if self.c.eth_syncing():
            print('BLOCKCHAIN_STILL_SYNCING')
            return False

        if self.events_callback is not False:
            had_any_events = self.poll_incoming()

        had_any_events = self.poll_outgoing() or had_any_events

        num_fails = 0

        while self.send_transaction_queue.qsize():
            print('TRY_TO_SEND')
            tries, args, kw = self.send_transaction_queue.get()
            try:
                self._send_transaction(*args, **kw)
            except Exception as e:
                print('FAILED_TO_SEND', e, tries, args, kw)
                sleep(1)  ## TODO
                self.send_transaction_queue.put((tries + 1, args, kw))
                break

        return had_any_events

    def check_for_reorg(
        self,
        block_num,
    ):
        """ Check for reorg since last check, and reorgs during our reorg rewinding... """
        print('START check_for_reorg', block_num)

        return
        block_num = ethereum.utils.parse_int_or_hex(block_num)

        while True:

            cur_num = block_num
            had_reorg = False

            while True:
                if cur_num == self.starting_block_num:
                    break

                assert cur_num >= self.starting_block_num, (
                    cur_num, self.starting_block_num)

                ## Get info for prev and current:

                for x_block_num in [block_num, block_num - 1]:
                    if x_block_num not in self.block_details:
                        rh = self.c.eth_getBlockByNumber(x_block_num)

                        ## Strip down to just a couple fields:
                        block_h = {
                            'timestamp':
                            ethereum.utils.parse_int_or_hex(rh['timestamp']),
                            'hash':
                            rh['hash'],
                            'parentHash':
                            rh['parentHash'],
                            'blockNumber':
                            x_block_num,
                        }
                        self.block_details[x_block_num] = block_h

                ## Check for reorg:

                block_h = self.block_details[block_num]

                if block_h['parentHash'] != self.block_details[
                        block_h['blockNumber'] - 1]['hash']:
                    print('!!! REORG', block_num, '->', cur_num)
                    cur_num -= 1
                    self.latest_done_block = cur_num
                    had_reorg = True
                    continue
                break

            ## Rewind state if had_reorg:

            if had_reorg and (self.reorg_callback is not False):
                self.reorg_callback(cur_num)
                self.last_incoming_block = cur_num - 1

            ## If had_reorg, loop again - to detect another reorg that occured while we tracked down the reorg...

            if not had_reorg:
                break

        return had_reorg

    def poll_incoming(self, chunk_size=50):
        """
        https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newfilter

        - track buffer of events from old blocks
        - track pointer to last processed block
        """

        assert self.is_deployed, 'Must deploy contract first.'

        #self.latest_block_num = self.c.eth_blockNumber()

        from_block = self.last_incoming_block + 1

        params = {
            'from_block': fixed_int_to_hex(from_block),
            'to_block': 'latest',  #fixed_int_to_hex(from_block + chunk_size),
            'address': self.contract_address,
        }

        print('eth_newFilter', 'from_block:', from_block, 'params:', params)

        self.the_filter = str(self.c.eth_newFilter(**params))

        num_blocks = len(self.msgs)

        xx_msgs = self.c.eth_getFilterLogs(self.the_filter)

        for msg in xx_msgs:
            msg['blockNumber'] = ethereum.utils.parse_int_or_hex(
                msg['blockNumber'])
            if msg['blockNumber'] not in self.msgs:
                self.msgs[msg['blockNumber']] = []
            self.msgs[msg['blockNumber']].append(msg)

        if num_blocks == len(self.msgs):
            ## Nothing new
            assert not len(xx_msgs), len(xx_msgs)
            return False

        for do_state, state_num_blocks in self.confirm_states.items():

            longest_confirm_state = max(self.confirm_states.values())
            newest_block_num = max(max(self.msgs), self.last_incoming_block)

            ## Oldest to newest:

            for nn in xrange(
                    max(1, self.last_incoming_block - state_num_blocks),
                    newest_block_num + 1,
            ):

                if self.check_for_reorg(nn):
                    ## Just wait for next call to poll_incoming() before resuming.
                    return False

                if nn in self.msgs:
                    for msg in self.msgs[nn]:
                        print('EMIT', do_state, nn, msg['data'])
                        self.events_callback(msg=msg,
                                             receipt=False,
                                             received_via=do_state)

            ## Clear out old buffer:

            for nn in self.msgs.keys():
                if nn < newest_block_num - longest_confirm_state - 1:
                    del self.msgs[nn]

        self.last_incoming_block = newest_block_num

        return True

        if False:
            ## START CHECKS

            if do_state not in self.done_transactions:
                self.done_transactions[do_state] = set()
                self.done_block_nums[do_state] = set()

            msg_block_num = ethereum.utils.parse_int_or_hex(msg['blockNumber'])

            if cm == 0:
                assert msg_block_num not in self.done_block_nums[do_state], (
                    'Seen block twice?',
                    msg_block_num,
                )
                self.done_block_nums[do_state].add(msg_block_num)

            if do_state in self.prev_block_num:
                assert msg_block_num >= self.prev_block_num[do_state], (
                    'REORG?',
                    msg_block_num,
                    self.prev_block_num[do_state],
                )
            self.prev_block_num[do_state] = msg_block_num

            assert msg['transactionHash'] not in self.done_transactions[
                do_state], (
                    'Seen transaction twice?',
                    msg_block_num,
                    msg['transactionHash'],
                )
            self.done_transactions[do_state].add(msg['transactionHash'])

            ## END CHECKS

        return had_any_events

    def _start_contract_thread(
        self,
        terminate_on_exception=False,
    ):
        while True:
            try:
                had_any_events = self.loop_once()
            except Exception as e:
                print('-----LOOP_ONCE_EXCEPTION', e)
                #exit(-1)
                raise

                if terminate_on_exception:
                    raise
                continue

            if not had_any_events:
                print('NO_NEW_EVENTS')

            sleep(self.contract_thread_sleep_time)

    def start_contract_thread(
        self,
        start_in_foreground=False,
        terminate_on_exception=False,
    ):
        """
        Start ContractWrapper loop_once() in background thread, which (in that thread!) calls back to self.process_event()
        """
        if start_in_foreground:
            self._start_contract_thread(
                terminate_on_exception=terminate_on_exception)
        else:
            self.t = Thread(
                target=self._start_contract_thread,
                args=(terminate_on_exception, ),
            )
            self.t.daemon = True
            self.t.start()

    def send_transaction(self, *args, **kw):
        assert len(args) <= 2
        if kw.get('block'):
            self.send_transaction(*args, **kw)
        else:
            self.send_transaction_queue.put((0, args, kw))

    def _send_transaction(
        self,
        args_sig,
        args,
        callback=False,
        send_from=False,
        block=False,
        gas_limit=False,
        gas_price=100,
        value=100000000000,
    ):
        """
        1) Attempt to send transaction.
        2) Get first confirmation via transaction receipt.
        3) Re-check receipt again after N blocks pass.
        
        https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sendtransaction
        """

        assert self.is_deployed, 'Must deploy contract first.'

        print('SEND_TRANSACTION:', args_sig, args)

        if send_from is False:
            send_from = self.c.eth_coinbase()

        send_to = self.contract_address

        print('====TRANSACTION')
        print('send_from', send_from)
        print('send_to', send_to)
        print('args_sig', args_sig)
        print('args', args)
        #print ('gas', gas_limit)

        gas_limit = 1000000
        gas_price = self.c.DEFAULT_GAS_PRICE
        value = web3.utils.currency.to_wei(1, 'ether')

        data = self.c._encode_function(args_sig, args)
        data_hex = '0x' + data.encode('hex')

        tx = self.c.eth_sendTransaction(
            from_address=send_from,
            to_address=send_to,
            data=data_hex,
            gas=gas_limit,
            gas_price=gas_price,
            value=value,
        )

        if block:
            print('BLOCKING FOR RECEIPT..')
            while True:
                receipt = self.c.eth_getTransactionReceipt(
                    tx)  ## blocks to ensure transaction is mined
                if receipt:
                    break
                sleep(self.blocking_sleep_time)
            print('GOT RECEIPT')
            #print ('GOT_RECEIPT', receipt)
            #if receipt['blockNumber']:
            #    self.latest_block_num = max(ethereum.utils.parse_int_or_hex(receipt['blockNumber']), self.latest_block_num)
        else:
            self.pending_transactions[tx] = (callback, self.latest_block_num)

        self.latest_block_num = self.c.eth_blockNumber()

        return tx

    def poll_outgoing(self):
        """
        Confirm outgoing transactions.
        """

        assert self.is_deployed, 'Must deploy contract first.'

        had_any_events = False
        if self.pending_transactions:
            had_any_events = True

        for tx, (callback,
                 attempt_block_num) in self.pending_transactions.items():

            ## Compare against the block_number where it attempted to be included:

            if (attempt_block_num <= self.latest_block_num -
                    self.confirm_states['BLOCKCHAIN_CONFIRMED']):
                continue

            receipt = self.c.eth_getTransactionReceipt(tx)

            if receipt is not None and 'blockNumber' in receipt:
                actual_block_number = ethereum.utils.parse_int_or_hex(
                    receipt['blockNumber'])
            else:
                ## TODO: wasn't confirmed after a long time.
                actual_block_number = False

            ## Now compare against the block_number where it was actually included:

            if (actual_block_number is not False) and (
                    actual_block_number >= self.latest_block_num -
                    self.confirm_states['BLOCKCHAIN_CONFIRMED']):
                if callback is not False:
                    callback(receipt)
                del self.pending_transactions[tx]

        return had_any_events

    def read_transaction(self, args_sig, value):
        rr = self.c.call(self.c.eth_coinbase(), self.contract_address,
                         args_sig, value)
        return rr

    def sign(self, user_address, value):
        rr = self.c.eth_sign(self.c.eth_coinbase(), self.contract_address,
                             user_address, value)
        return rr
Exemplo n.º 23
0
import json
from ethjsonrpc import EthJsonRpc

eth = EthJsonRpc("ethereum", 8545)

with open("VarStore.sol") as f:
    contract = eth.eth_compileSolidity(f.read())
transaction = eth.create_contract(eth.eth_coinbase(),
                                  contract['VarStore']['code'], gas=300000)
contract["transaction"] = transaction
contract["account"] = eth.eth_coinbase()
print json.dumps(contract)