def test_execution_of_call_with_single_bytes32(deploy_client,
                                               deployed_contracts,
                                               deploy_coinbase,
                                               deploy_future_block_call):
    client_contract = deployed_contracts.TestCallExecution

    call = deploy_future_block_call(client_contract.setBytes32)

    value = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'
    signature = call.registerData.encoded_abi_signature
    data = abi.encode_single(abi.process_type('bytes32'), value)
    txn_data = ''.join((utils.encode_hex(signature), utils.encode_hex(data)))

    data_txn_hash = deploy_client.send_transaction(
        to=call._meta.address,
        data=txn_data,
    )
    data_txn_receipt = deploy_client.wait_for_transaction(data_txn_hash)

    assert client_contract.v_bytes32() is None

    call_txn_hash = call.execute()
    deploy_client.wait_for_transaction(call_txn_hash)

    assert client_contract.v_bytes32() == value
def test_enumerate_upcoming_tree_positions(deploy_client, deployed_contracts):
    alarm = deployed_contracts.Alarm
    client_contract = deployed_contracts.SpecifyBlock

    anchor_block = deploy_client.get_block_number()

    blocks = (1, 4, 4, 8, 15, 25, 25, 25, 30, 40, 50, 60)

    call_keys = []

    for n in blocks:
        txn_hash = client_contract.scheduleIt.sendTransaction(alarm._meta.address, anchor_block + 100 + n)
        wait_for_transaction(deploy_client, txn_hash)

        last_call_key = alarm.getLastCallKey()
        assert last_call_key is not None

        call_keys.append(last_call_key)

    expected_calls = tuple(utils.encode_hex(c) for c in call_keys[1:10])

    actual_calls = tuple(
        utils.encode_hex(c)
        for c in enumerate_upcoming_calls(alarm, anchor_block + 100 + 4)
    )
    assert actual_calls == expected_calls
def create_node_configuration(miner=True,
                              port=30301,
                              rpcport=8101,
                              host='127.0.0.1',
                              node_key_seed=0):
    """
    Create configuration (ports, keys, etc...) for one node.

    :param miner: if True, setup to be a mining node
    :param port: the p2p port to assign
    :param rpcport: the port to assign
    :param host: the host for the node to run on
    :return: node configuration dict
    """
    node = dict()
    if miner:
        node['minerthreads'] = 1  # conservative
        node['unlock'] = 0
    node['nodekey'] = sha3('node:{}'.format(node_key_seed).encode())
    node['nodekeyhex'] = encode_hex(node['nodekey'])
    node['pub'] = encode_hex(privtopub_enode(node['nodekey']))
    node['address'] = privatekey_to_address(node['nodekey'])
    node['host'] = host
    node['port'] = port
    node['rpcport'] = rpcport
    node['enode'] = 'enode://{pub}@{host}:{port}'.format(**node)
    return node
def test_cancellable_after_call_window_if_missed(deploy_client,
                                                 deployed_contracts,
                                                 deploy_future_block_call,
                                                 deploy_coinbase,
                                                 denoms):
    client_contract = deployed_contracts.TestCallExecution

    call = deploy_future_block_call(
        scheduler_address=deploy_coinbase,
        target_block=deploy_client.get_block_number() + 400,
    )

    assert call.state() == State.Pending

    deploy_client.wait_for_block(call.targetBlock() + call.gracePeriod())

    assert call.state() == State.Missed

    assert call.isCancellable() is True
    # true for non-scheduler account
    assert call.isCancellable(_from=utils.encode_hex(accounts[1])) is True

    cancel_txn_hash = call.cancel()
    cancel_txn_receipt = deploy_client.wait_for_transaction(cancel_txn_hash)

    assert call.isCancellable() is False
    assert call.isCancellable(_from=utils.encode_hex(accounts[1])) is False
def test_execution_of_call_with_many_values(deploy_client,
                                            deployed_contracts,
                                            deploy_coinbase,
                                            deploy_future_block_call,
                                            CallLib):
    client_contract = deployed_contracts.TestCallExecution

    call = deploy_future_block_call(client_contract.setMany)

    values = (
        1234567890,
        -1234567890,
        987654321,
        '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13',
        'd3cda913deb6f67967b99d67acdfa1712c293601',
        'abcdefg',
    )
    types = (
        'uint256',
        'int256',
        'uint256',
        'bytes20',
        'address',
        'bytes',
    )

    signature = call.registerData.encoded_abi_signature
    data = ''.join((
        abi.encode_single(abi.process_type(t), v)
        for t, v in zip(types, values)
    ))
    txn_data = ''.join((utils.encode_hex(signature), utils.encode_hex(data)))

    data_txn_hash = deploy_client.send_transaction(
        to=call._meta.address,
        data=txn_data,
    )
    data_txn_receipt = deploy_client.wait_for_transaction(data_txn_hash)


    assert client_contract.vm_a() == 0
    assert client_contract.vm_b() == 0
    assert client_contract.vm_c() == 0
    assert client_contract.vm_d() == None
    assert client_contract.vm_e() == '0x0000000000000000000000000000000000000000'
    assert client_contract.vm_f() == ''

    call_txn_hash = call.execute()
    txn_r = deploy_client.wait_for_transaction(call_txn_hash)

    call_logs = CallLib.CallExecuted.get_transaction_logs(call_txn_hash)
    call_data = [CallLib.CallExecuted.get_log_data(l) for l in call_logs]

    assert client_contract.vm_a() == values[0]
    assert client_contract.vm_b() == values[1]
    assert client_contract.vm_c() == values[2]
    assert client_contract.vm_d() == values[3]
    assert client_contract.vm_e() == '0xd3cda913deb6f67967b99d67acdfa1712c293601'
    assert client_contract.vm_f() == values[5]
示例#6
0
def generate_accounts(seeds):
    """Create private keys and addresses for all seeds.
    """
    return {
        seed: dict(
            privatekey=encode_hex(sha3(seed)),
            address=encode_hex(privatekey_to_address(sha3(seed)))
        ) for seed in seeds}
示例#7
0
 def getWork(self):
     print 'Sending work...'
     h = self.chain.chain.head_candidate
     return [
         encode_hex(h.header.mining_hash),
         encode_hex(h.header.seed),
         encode_hex(zpad(int_to_big_endian(2**256 // h.header.difficulty), 32))
     ]
示例#8
0
 def __str__(self):
     return '<HashTimeLocked id={} amount={} token={} target={} expire={} hashlock={}>'.format(
         self.identifier,
         self.amount,
         encode_hex(self.token),
         encode_hex(self.target),
         self.expiration,
         encode_hex(self.hashlock),
     )
 def to_dict(self):
     d = {}
     for name, _ in self.__class__.fields:
         d[name] = getattr(self, name)
         if name in ('to', 'data'):
             d[name] = '0x' + encode_hex(d[name])
     d['sender'] = '0x' + encode_hex(self.sender)
     d['hash'] = '0x' + encode_hex(self.hash)
     return d
示例#10
0
def get_proof(lst, proof_for, root=None):
    proof = [proof_for]
    root_hash = merkleroot(lst, proof)

    if root and root != root_hash:
        raise ValueError('root hashes did not match {} {}'.format(
            encode_hex(root_hash),
            encode_hex(root)
        ))

    return proof
示例#11
0
文件: test.py 项目: LianaHus/dapp-bin
def test():
    # Test the arbiter mechanism
    t.gas_price = 0
    t.gas_limit = 100000000
    s = t.state()
    c = s.abi_contract('arbitration.se')
    o = []
    s.block.log_listeners.append(lambda x: o.append(c._translator.listen(x)))
    x = c.mk_contract(t.a1, t.a2, [t.a3, t.a4, t.a5], 1000, "horse" * 10, value=100000)
    assert c.get_contract_value(x) == 99000
    assert c.get_contract_recipients(x) == [t.a1.encode('hex'), t.a2.encode('hex')]
    assert c.get_contract_arbiters(x) == [utils.encode_hex(a) for a in [t.a3, t.a4, t.a5]]
    assert c.get_contract_arbiterFee(x) == 1000
    assert c.get_contract_description(x) == "horse" * 10
    assert o[-1]["value"] == 99000
    assert o[-1]["arbiters"] == [utils.encode_hex(a) for a in [t.a3, t.a4, t.a5]]
    assert not c.vote(x, True, sender=t.k6)
    assert c.vote(x, False, sender=t.k5)
    assert not c.vote(x, True, sender=t.k5)
    prebals = [s.block.get_balance(y) for y in (t.a1, t.a2, t.a3, t.a4, t.a5, t.a6)]
    assert c.vote(x, False, sender=t.k4)
    assert o[-1]["_event_type"] == "PaidOut"
    assert o[-1]["recipient"] == utils.encode_hex(t.a2), (o[-1]["recipient"], utils.encode_hex(t.a1), utils.encode_hex(t.a2))
    postbals = [s.block.get_balance(x) for x in (t.a1, t.a2, t.a3, t.a4, t.a5, t.a6)]
    diffs = [b - a for a, b in zip(prebals, postbals)]
    assert diffs == [0, 99000, 0, 500, 500, 0]
    # Test the arbiter registry
    c = s.abi_contract('arbiter_reg.se')
    assert not c.register(sender=t.k1, value=10**14)
    assert c.register(sender=t.k1, value=10**16)
    assert c.register(sender=t.k2, value=10**17)
    assert c.get_addresses(0) == [t.a1.encode('hex'), t.a2.encode('hex')]
    assert c.get_addresses(1) == [t.a2.encode('hex')]
    assert c.get_addresses(50) == []
    assert c.get_tot_fee(t.a1) == 10**16, c.get_tot_fee(t.a1)
    assert c.get_tot_fee(t.a2) == 10**17
    s.mine(100)
    f1 = c.get_tot_fee(t.a1)
    f2 = c.get_tot_fee(t.a2)
    assert f1 < 10**16 and f2 < 10**17
    assert -1 <= f1 - f2 / 10 <= 1 # Accomodate a very small difference
    assert c.register(sender=t.k1, value=10**16)
    assert c.register(sender=t.k2, value=10**15)
    assert c.register(sender=t.k2, value=10**16)
    assert c.register(sender=t.k2, value=10**17 - 10**16 - 10**15)
    new_f1 = c.get_tot_fee(t.a1)
    new_f2 = c.get_tot_fee(t.a2)
    assert new_f1 - f1 == 10**16
    assert new_f2 - f2 == 10**17
    assert not c.set_description("The quick brown fox jumps over t", sender=t.k3)
    assert c.set_description("The quick brown fox jumps over t", sender=t.k1)
    assert c.get_description(t.a1) == "The quick brown fox jumps over t", c.get_description(t.a1)
    assert c.set_description("The quick brown fox jumps over the yellow doge", sender=t.k1)
    assert c.get_description(t.a1) == "The quick brown fox jumps over the yellow doge"
示例#12
0
def get_proof(lst, proof_for, root=None):
    tree = Merkletree(lst)

    root_hash = tree.merkleroot
    if root and root != root_hash:
        raise ValueError('root hashes did not match {} {}'.format(
            encode_hex(root_hash),
            encode_hex(root)
        ))

    return tree.make_proof(proof_for)
示例#13
0
def test_interop():
    if 'solidity' not in tester.languages:
        return
    s = tester.state()
    c1 = s.abi_contract(serpent_contract)
    c2 = s.abi_contract(solidity_contract, language='solidity')  # should be zoo
    assert c1.sub1() == 5
    assert c2.sub2() == 7
    assert c2.sub3(utils.encode_hex(c2.address)) == utils.encode_hex(c2.address)
    assert c1.main(c2.address) == 14
    assert c2.main(c1.address) == 10
示例#14
0
def warn_invalid(block, errortype='other'):
    try:
        make_request('http://badblocks.ethereum.org', {
            "block": utils.encode_hex(rlp.encode(block)),
            "errortype": errortype,
            "hints": {
                "receipts": [utils.encode_hex(rlp.encode(x)) for x in
                             block.get_receipts()],
                "vmtrace": "NOT YET IMPLEMENTED"
            }
        })
    except:
        sys.stderr.write('Failed to connect to badblocks.ethdev.com\n')
示例#15
0
def test_currency_apis():
    s = tester.state()
    c1 = s.abi_contract(serpent_currency, sender=tester.k0)
    c2 = s.abi_contract(solidity_currency, language='solidity', sender=tester.k0)
    o = []
    s.block.log_listeners.append(lambda x: o.append(c._translator.listen(x)))
    for c in (c1, c2):
        o = []
        assert c.coinBalanceOf(tester.a0) == 1000000
        assert c.sendCoin(1000, tester.a2, sender=tester.k0) is True
        assert c.sendCoin(999001, tester.a2, sender=tester.k0) is False
        assert c.sendCoinFrom(tester.a2, 500, tester.a3, sender=tester.k0) is False
        c.approveOnce(tester.a0, 500, sender=tester.k2)
        assert c.sendCoinFrom(tester.a2, 400, tester.a3, sender=tester.k0) is True
        assert c.sendCoinFrom(tester.a2, 400, tester.a3, sender=tester.k0) is False
        assert c.sendCoinFrom(tester.a2, 100, tester.a3, sender=tester.k0) is True
        assert c.sendCoinFrom(tester.a2, 100, tester.a3, sender=tester.k0) is False
        c.approve(tester.a0, sender=tester.k2)
        assert c.sendCoinFrom(tester.a2, 100, tester.a3, sender=tester.k0) is True
        c.disapprove(tester.a0, sender=tester.k2)
        assert c.sendCoinFrom(tester.a2, 100, tester.a3, sender=tester.k0) is False
        assert c.coinBalance(sender=tester.k0) == 999000
        assert c.coinBalanceOf(tester.a2) == 400
        assert c.coinBalanceOf(tester.a3) == 600
        assert o == [{"_event_type": b"CoinSent", "from": utils.encode_hex(tester.a0),
                      "value": 1000, "to": utils.encode_hex(tester.a2)},
                     {"_event_type": b"CoinSent", "from": utils.encode_hex(tester.a2),
                      "value": 400, "to": utils.encode_hex(tester.a3)},
                     {"_event_type": b"CoinSent", "from": utils.encode_hex(tester.a2),
                      "value": 100, "to": utils.encode_hex(tester.a3)},
                     {"_event_type": b"CoinSent", "from": utils.encode_hex(tester.a2),
                      "value": 100, "to": utils.encode_hex(tester.a3)}]
示例#16
0
 def to_dict(self):
     """Serialize the header to a readable dictionary."""
     d = {}
     for field in ('prevhash', 'uncles_hash', 'extra_data', 'nonce',
                   'mixhash'):
         d[field] = '0x' + encode_hex(getattr(self, field))
     for field in ('state_root', 'tx_list_root', 'receipts_root',
                   'coinbase'):
         d[field] = encode_hex(getattr(self, field))
     for field in ('number', 'difficulty', 'gas_limit', 'gas_used',
                   'timestamp'):
         d[field] = utils.to_string(getattr(self, field))
     d['bloom'] = encode_hex(int256.serialize(self.bloom))
     assert len(d) == len(BlockHeader.fields)
     return d
def test_registration_of_many_values_via_fallback(deploy_client,
                                                  deployed_contracts,
                                                  deploy_coinbase,
                                                  deploy_future_block_call):
    client_contract = deployed_contracts.TestCallExecution

    call = deploy_future_block_call(
        client_contract.setMany,
        target_block=deploy_client.get_block_number() + 40,
    )

    values = (
        1234567890,
        -1234567890,
        987654321,
        '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13',
        '0xd3cda913deb6f67967b99d67acdfa1712c293601',
        'abcdef',
    )
    call_data = utils.encode_hex(client_contract.setMany.abi_args_signature(values))

    deploy_client.send_transaction(
        to=call._meta.address,
        data=call_data,
    )

    expected = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\x96\x02\xd2\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xb6i\xfd.\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\xdeh\xb1\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xcd\xa9\x13\xde\xb6\xf6yg\xb9\x9dg\xac\xdf\xa1q,)6\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06abcdef\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    actual = call.callData()

    assert expected == actual
示例#18
0
def patch_send_transaction(client, nonce_offset=0):
    """Check if the remote supports pyethapp's extended jsonrpc spec for local tx signing.
    If not, replace the `send_transaction` method with a more generic one.
    """
    patch_necessary = False
    try:
        client.call('eth_nonce', encode_hex(client.sender), 'pending')
    except:
        patch_necessary = True

    def send_transaction(sender, to, value=0, data='', startgas=GAS_LIMIT,
                         gasprice=GAS_PRICE, nonce=None):
        """Custom implementation for `pyethapp.rpc_client.JSONRPCClient.send_transaction`.
        This is necessary to support other remotes that don't support pyethapp's extended specs.
        @see https://github.com/ethereum/pyethapp/blob/develop/pyethapp/rpc_client.py#L359
        """
        pending_transactions_hex = client.call(
            'eth_getTransactionCount',
            encode_hex(sender),
            'pending',
        )
        pending_transactions = int(pending_transactions_hex, 16)
        nonce = pending_transactions + nonce_offset

        tx = Transaction(nonce, gasprice, startgas, to, value, data)
        assert hasattr(client, 'privkey') and client.privkey
        tx.sign(client.privkey)
        result = client.call('eth_sendRawTransaction', rlp.encode(tx).encode('hex'))
        return result[2 if result.startswith('0x') else 0:]

    if patch_necessary:
        client.send_transaction = send_transaction
示例#19
0
    def unlock(self, our_address, unlock_proofs):
        # force a list to get the length (could be a generator)
        unlock_proofs = list(unlock_proofs)
        log.info(
            '%s locks to unlock',
            len(unlock_proofs),
            contract=pex(self.address),
        )

        for merkle_proof, locked_encoded, secret in unlock_proofs:
            if isinstance(locked_encoded, messages.Lock):
                raise ValueError('unlock must be called with a lock encoded `.as_bytes`')

            merkleproof_encoded = ''.join(merkle_proof)

            transaction_hash = self.proxy.unlock.transact(
                locked_encoded,
                merkleproof_encoded,
                secret,
                startgas=self.startgas,
                gasprice=self.gasprice,
            )
            self.client.poll(transaction_hash.decode('hex'), timeout=self.poll_timeout)
            # TODO: check if the ChannelSecretRevealed event was emitted and if
            # it wasn't raise an error

            # if log.getEffectiveLevel() >= logging.INFO:  # only decode the lock if need to
            lock = messages.Lock.from_bytes(locked_encoded)
            log.info(
                'unlock called',
                contract=pex(self.address),
                lock=lock,
                secret=encode_hex(secret),
            )
示例#20
0
    def unlock(self, our_address, unlock_proofs):
        # force a list to get the length (could be a generator)
        unlock_proofs = list(unlock_proofs)
        log.info('{} locks to unlock'.format(len(unlock_proofs)), contract=pex(self.address))

        for merkle_proof, locked_encoded, secret in unlock_proofs:
            if isinstance(locked_encoded, messages.Lock):
                raise ValueError('unlock must be called with a lock encoded `.as_bytes`')

            merkleproof_encoded = ''.join(merkle_proof)

            self.proxy.unlock(
                locked_encoded,
                merkleproof_encoded,
                secret,
            )
            self.tester_state.mine(number_of_blocks=1)

            lock = messages.Lock.from_bytes(locked_encoded)
            log.info(
                'unlock called',
                contract=pex(self.address),
                lock=lock,
                secret=encode_hex(secret),
            )
示例#21
0
    def add_asset(self, asset_address):
        """ The equivalent of instatiating a new `ChannelManagerContract`
        contract that will manage channels for a given asset in the blockchain.

        Raises:
            ValueError: If asset_address is not a valid address or is already registered.
        """
        if asset_address in self.address_asset:
            raise ValueError('duplicated address {}'.format(encode_hex(asset_address)))

        asset = AssetMock(address=asset_address)
        manager = ChannelManagerMock(asset_address)

        self.address_asset[asset_address] = asset
        self.asset_manager[asset_address] = manager

        data = {
            '_event_type': 'AssetAdded',
            'asset_address': asset_address,
            'channel_manager_address': manager.address,
        }
        event = ethereum_event(ASSETADDED_EVENTID, ASSETADDED_EVENT, data, self.address)

        for filter_ in BlockChainServiceMock.filters[self.address]:
            filter_.event(event)

        BlockChainServiceMock.address_asset[asset_address] = asset
        BlockChainServiceMock.address_manager[manager.address] = manager
        BlockChainServiceMock.asset_manager[asset_address] = manager
示例#22
0
def run_test(name):

    pairs = load_tests()[name]

    def _dec(x):
        if utils.is_string(x) and x.startswith(b'0x'):
            return utils.decode_hex(x[2:])
        return x

    pairs['in'] = [(_dec(k), _dec(v)) for k, v in pairs['in']]
    deletes = [(k, v) for k, v in pairs['in'] if v is None]

    N_PERMUTATIONS = 100
    for i, permut in enumerate(itertools.permutations(pairs['in'])):
        if i > N_PERMUTATIONS:
            break
        db = RefcountDB(EphemDB())
        db.ttl = 0
        t = pruning_trie.Trie(db)
        for k, v in permut:
            # logger.debug('updating with (%s, %s)' %(k, v))
            if v is not None:
                t.update(k, v)
            else:
                t.delete(k)
        db.commit_refcount_changes(0)
        db.cleanup(0)
        # make sure we have deletes at the end
        for k, v in deletes:
            t.delete(k)
        t.clear_all()
        db.commit_refcount_changes(1)
        db.cleanup(1)
        assert len(db.kv) == 0
        assert pairs['root'] == b'0x' + utils.encode_hex(t.root_hash), (i, list(permut) + deletes)
示例#23
0
 def block(self, hash):
     try:
         if len(hash) == 32:
             hash = '0x' + encode_hex(hash)
         return self.get_json(hash)
     except KeyError:
         return None
示例#24
0
    def new_netting_channel(self, peer1, peer2, settle_timeout):
        """ Creates a new netting contract between peer1 and peer2.

        Raises:
            ValueError: If peer1 or peer2 is not a valid address.
        """
        if not isaddress(peer1):
            raise ValueError('The pee1 must be a valid address')

        if not isaddress(peer2):
            raise ValueError('The peer2 must be a valid address')

        if peer1 == peer2:
            raise ValueError('Cannot open a channel with itself')

        pair = tuple(sorted((peer1, peer2)))
        if pair in self.pair_channel:
            raise ValueError('({}, {}) already have a channel'.format(
                encode_hex(peer1),
                encode_hex(peer2)
            ))

        channel = NettingChannelMock(
            self.asset_address(),
            peer1,
            peer2,
            settle_timeout,
        )
        self.pair_channel[pair] = channel
        self.participant_channels[peer1].append(channel)
        self.participant_channels[peer2].append(channel)

        BlockChainServiceMock.address_contract[channel.address] = channel

        data = {
            '_event_type': 'ChannelNew',
            'netting_channel': channel.address,
            'participant1': peer1,
            'participant2': peer2,
            'settle_timeout': settle_timeout,
        }
        event = ethereum_event(CHANNELNEW_EVENTID, CHANNELNEW_EVENT, data, self.address)

        for filter_ in BlockChainServiceMock.filters[self.address]:
            filter_.event(event)

        return channel.address
示例#25
0
    def find_channel_by_address(self, netting_channel_address_bin):
        for manager in self.managers_by_address.itervalues():
            channel = manager.address_channel.get(netting_channel_address_bin)

            if channel is not None:
                return channel

        raise ValueError('unknow channel {}'.format(encode_hex(netting_channel_address_bin)))
    def find_channel_by_address(self, netting_channel_address_bin):
        for graph in self.token_to_channelgraph.values():
            channel = graph.address_to_channel.get(netting_channel_address_bin)

            if channel is not None:
                return channel

        raise ValueError('unknown channel {}'.format(encode_hex(netting_channel_address_bin)))
示例#27
0
    def get_deploy_data(cls, *args):
        data = cls._config.code
        if args:
            if cls._config.constructor is None:
                raise ValueError("This contract does not appear to have a constructor")
            data += ethereum_utils.encode_hex(cls._config.constructor.abi_args_signature(args))

        return data
示例#28
0
 def get_call_data(self, args):
     """
     TODO: this needs tests.
     """
     prefix = self.encoded_abi_signature
     suffix = self.abi_args_signature(args)
     data = prefix + suffix
     return ethereum_utils.encode_hex(data)
示例#29
0
 def inc_refcount(self, k, v):
     # raise Exception("WHY AM I CHANGING A REFCOUNT?!:?")
     try:
         node_object = rlp.decode(self.db.get(b'r:'+k))
         refcount = utils.decode_int(node_object[0])
         self.journal.append([node_object[0], k])
         if refcount >= DEATH_ROW_OFFSET:
             refcount = 0
         new_refcount = utils.encode_int(refcount + 1)
         self.db.put(b'r:'+k, rlp.encode([new_refcount, v]))
         if self.logging:
             sys.stderr.write('increasing %s %r to: %d\n' % (utils.encode_hex(k), v, refcount + 1))
     except:
         self.db.put(b'r:'+k, rlp.encode([ONE_ENCODED, v]))
         self.journal.append([ZERO_ENCODED, k])
         if self.logging:
             sys.stderr.write('increasing %s %r to: %d\n' % (utils.encode_hex(k), v, 1))
示例#30
0
    def get_state_for(self, node_address_bin):
        if self.our_state.address == node_address_bin:
            return self.our_state

        if self.partner_state.address == node_address_bin:
            return self.partner_state

        raise Exception('Unknow address {}'.format(encode_hex(node_address_bin)))
示例#31
0
def test_closewithouttransfer_settle(deposit, settle_timeout, tester_state,
                                     tester_events, tester_nettingcontracts,
                                     tester_token):

    privatekey0, privatekey1, nettingchannel = tester_nettingcontracts[0]
    address0 = privatekey_to_address(privatekey0)
    address1 = privatekey_to_address(privatekey1)
    unknow_key = tester.k3

    initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0)
    initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1)

    with pytest.raises(TransactionFailed):
        nettingchannel.closeWithoutTransfers(sender=unknow_key)

    # this method needs to be implemented, the name could be changed
    previous_events = list(tester_events)
    nettingchannel.closeWithoutTransfers(sender=privatekey0)
    assert len(previous_events) + 1 == len(tester_events)

    block_number = tester_state.block.number

    close_event = tester_events[-1]
    assert close_event == {
        '_event_type': 'ChannelClosed',
        'closingAddress': encode_hex(address0),
        'blockNumber': block_number,
    }

    assert nettingchannel.closed() == block_number
    assert nettingchannel.closingAddress() == encode_hex(address0)

    tester_state.mine(number_of_blocks=settle_timeout + 1)

    previous_events = list(tester_events)
    nettingchannel.settle(sender=privatekey0)
    block_number = tester_state.block.number

    assert len(previous_events) + 3 == len(tester_events)

    transfer0_event = tester_events[-3]
    assert transfer0_event == {
        '_from': nettingchannel.address,
        '_to': encode_hex(address0),
        '_value': deposit,
    }

    transfer1_event = tester_events[-2]
    assert transfer1_event == {
        '_from': nettingchannel.address,
        '_to': encode_hex(address1),
        '_value': deposit,
    }

    settle_event = tester_events[-1]
    assert settle_event == {
        '_event_type': 'ChannelSettled',
        'blockNumber': block_number,
    }

    assert tester_token.balanceOf(
        address0, sender=privatekey0) == initial_balance0 + deposit
    assert tester_token.balanceOf(
        address1, sender=privatekey1) == initial_balance1 + deposit
    assert tester_token.balanceOf(nettingchannel.address,
                                  sender=privatekey1) == 0
示例#32
0
def test_close_settle(deposit, settle_timeout, tester_state, tester_channels,
                      tester_events, tester_token):

    privatekey0_raw, privatekey1_raw, nettingchannel, channel0, channel1 = tester_channels[
        0]
    privatekey0 = PrivateKey(privatekey0_raw, ctx=GLOBAL_CTX, raw=True)
    privatekey1 = PrivateKey(privatekey1_raw, ctx=GLOBAL_CTX, raw=True)
    address0 = privatekey_to_address(privatekey0_raw)
    address1 = privatekey_to_address(privatekey1_raw)
    unknow_key = tester.k3

    initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0_raw)
    initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1_raw)

    transfer_amount0 = 10
    direct_transfer0 = channel0.create_directtransfer(
        transfer_amount0,
        1  # TODO: fill in identifier
    )
    direct_transfer0.sign(privatekey0, address0)

    transfer_amount1 = 30
    direct_transfer1 = channel1.create_directtransfer(
        transfer_amount1,
        1  # TODO: fill in identifier
    )
    direct_transfer1.sign(privatekey1, address1)

    with pytest.raises(TransactionFailed):
        nettingchannel.close(
            str(direct_transfer0.packed().data),
            str(direct_transfer1.packed().data),
            sender=unknow_key,
        )

    previous_events = list(tester_events)
    nettingchannel.close(
        str(direct_transfer0.packed().data),
        str(direct_transfer1.packed().data),
        sender=privatekey0_raw,
    )
    assert len(previous_events) + 1 == len(tester_events)

    block_number = tester_state.block.number

    close_event = tester_events[-1]
    assert close_event == {
        '_event_type': 'ChannelClosed',
        'closingAddress': encode_hex(address0),
        'blockNumber': block_number,
    }

    assert nettingchannel.closed(sender=privatekey0_raw) == block_number
    assert nettingchannel.closingAddress(
        sender=privatekey0_raw) == encode_hex(address0)

    tester_state.mine(number_of_blocks=settle_timeout + 1)

    previous_events = list(tester_events)
    nettingchannel.settle(sender=privatekey0_raw)
    assert len(previous_events) + 3 == len(tester_events)

    block_number = tester_state.block.number

    transfer0_event = tester_events[-3]
    assert transfer0_event == {
        '_event_type': 'Transfer',
        '_from': nettingchannel.address,
        '_to': encode_hex(address0),
        '_value': deposit - transfer_amount0 + transfer_amount1,
    }

    transfer1_event = tester_events[-2]
    assert transfer1_event == {
        '_event_type': 'Transfer',
        '_from': nettingchannel.address,
        '_to': encode_hex(address1),
        '_value': deposit + transfer_amount0 - transfer_amount1,
    }

    settle_event = tester_events[-1]
    assert settle_event == {
        '_event_type': 'ChannelSettled',
        'blockNumber': block_number,
    }

    assert tester_token.balanceOf(
        address0, sender=privatekey0_raw
    ) == initial_balance0 + deposit - transfer_amount0 + transfer_amount1  # noqa
    assert tester_token.balanceOf(
        address1, sender=privatekey1_raw
    ) == initial_balance1 + deposit + transfer_amount0 - transfer_amount1  # noqa
    assert tester_token.balanceOf(nettingchannel.address,
                                  sender=privatekey1_raw) == 0
示例#33
0
文件: client.py 项目: p0n1/mythril
def _encode_hex(v):
    """
    encodes hash as hex
    """
    return '0x' + utils.encode_hex(v)
示例#34
0
    -2].gas_used - s.last_tx.intrinsic_gas_used
print("500 bytes increment: %d" % (g2 - g1))
print("500 bytes increment: %d" % (g4 - g3))
print("25 items increment: %d" % (g3 - g1))
print("25 items increment: %d" % (g4 - g2))

# configure_logging(config_string=config_string)
s.send(
    t.k0, c, 0,
    b'\xf8\xc7\x01\xa055555555555555555555555555555555\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x88\xa7\x85r\x1b3\x17\xcaP\x96\xca\xd3S\xfcgM\xec\xe0\xf5!\xc8\xb4m\xd9\xb7E\xf3\x81d\x87\x93VD\xe0Ej\xcd\xec\x80\x11\x86(qZ\x9b\x80\xbf\xce\xe5*\r\x9d.o\xcd\x11s\xc5\xbc\x8c\xcb\xb9\xa9 '
)
g = s.state.receipts[-1].gas_used - s.state.receipts[
    -2].gas_used - s.last_tx.intrinsic_gas_used
print("Casper prepare: %d" % g)

# Create transaction

t = transactions.Transaction(0, 30 * 10**9, 2999999, '', 0, rlp_decoder)
t.startgas = t.intrinsic_gas_used + 50000 + 200 * len(rlp_decoder)
t.v = 27
t.r = 45
t.s = 79
print("RLP decoder")
print("Instructions for launching:")
print('First send %d wei to %s' %
      (t.startgas * t.gasprice, utils.checksum_encode(t.sender)))
print('Publish this tx to create the contract: 0x' +
      utils.encode_hex(rlp.encode(t)))
print('This is the contract address: ' +
      utils.checksum_encode(utils.mk_contract_address(t.sender, 0)))
示例#35
0
def tester_deploy_contract(tester_chain,
                           private_key,
                           contract_name,
                           contract_path,
                           constructor_parameters=None):

    all_contracts = _solidity.compile_file(contract_path, libraries=dict())

    contract_key = solidity_get_contract_key(all_contracts, contract_path,
                                             contract_name)
    contract = all_contracts[contract_key]
    contract_interface = contract['abi']

    log.info('Deploying "{}" contract'.format(os.path.basename(contract_path)))

    dependencies = deploy_dependencies_symbols(all_contracts)
    deployment_order = dependencies_order_of_build(contract_key, dependencies)

    log.info('Deploying dependencies: {}'.format(str(deployment_order)))
    deployment_order.pop()  # remove `contract_name` from the list
    libraries = dict()

    for deploy_contract in deployment_order:
        dependency_contract = all_contracts[deploy_contract]

        hex_bytecode = _solidity.solidity_resolve_symbols(
            dependency_contract['bin_hex'],
            libraries,
        )
        bytecode = unhexlify(hex_bytecode)

        dependency_contract['bin_hex'] = hex_bytecode
        dependency_contract['bin'] = bytecode

        log.info('Creating contract {}'.format(deploy_contract))
        contract_address = tester_chain.contract(bytecode,
                                                 language='evm',
                                                 sender=private_key)
        tester_chain.mine(number_of_blocks=1)

        if len(tester_chain.head_state.get_code(contract_address)) == 0:
            raise Exception('Contract code empty')

        libraries[deploy_contract] = encode_hex(contract_address)

    hex_bytecode = _solidity.solidity_resolve_symbols(contract['bin_hex'],
                                                      libraries)
    bytecode = unhexlify(hex_bytecode)

    contract['bin_hex'] = hex_bytecode
    contract['bin'] = bytecode

    if constructor_parameters:
        translator = ContractTranslator(contract_interface)
        parameters = translator.encode_constructor_arguments(
            constructor_parameters)
        bytecode = contract['bin'] + parameters
    else:
        bytecode = contract['bin']

    log.info('Creating contract {}'.format(contract_name))
    contract_address = tester_chain.contract(bytecode,
                                             language='evm',
                                             sender=private_key)
    tester_chain.mine(number_of_blocks=1)

    if len(tester_chain.head_state.get_code(contract_address)) == 0:
        raise Exception('Contract code empty')

    return contract_address
def valueconv(k, v):
    if k in ['r', 's']:
        return '0x' + encode_hex(utils.int_to_big_endian(v))
    return v
示例#37
0
import pytest
from ethereum.tools import tester as t
from ethereum import utils
from tests.setup_transaction_tests import assert_tx_failed
t.s = t.Chain()
t.s.head_state.gas_limit = 10**9

x = t.s.contract(open('examples/wallet/wallet.v.py').read(),
                 args=[[t.a1, t.a2, t.a3, t.a4, t.a5], 3],
                 language='viper')
print(t.s.last_tx.data[-192:])
# Sends wei to the contract for future transactions gas costs
t.s.tx(sender=t.k1, to=x.address, value=10**17)

print([utils.encode_hex(a) for a in [t.a1, t.a2, t.a3, t.a4, t.a5]])


# Signs a transaction with a given key
def sign(seq, to, value, data, key):
    h1 = utils.sha3(
        utils.encode_int32(seq) + b'\x00' * 12 + to +
        utils.encode_int32(value) + data)
    h2 = utils.sha3(b"\x19Ethereum Signed Message:\n32" + h1)
    return list(utils.ecsign(h2, key))


def test_approve(assert_tx_failed):
    to, value, data = b'\x35' * 20, 10**16, b""
    assert x.approve(0,
                     to,
                     value,
示例#38
0
 def __repr__(self):
     return '<TransientBlock(#%d %s)>' % (self.header.number,
                                          encode_hex(self.header.hash)[:8])
示例#39
0
 def add_block(self, block):
     now = self.localtime
     # Are we receiving the block too early?
     if block.header.timestamp > now:
         i = 0
         while i < len(self.time_queue
                       ) and block.timestamp > self.time_queue[i].timestamp:
             i += 1
         self.time_queue.insert(i, block)
         log.info(
             'Block received too early (%d vs %d). Delaying for %d seconds'
             % (now, block.header.timestamp, block.header.timestamp - now))
         return False
     # Is the block being added to the head?
     self.state.deletes = []
     if block.header.prevhash == self.head_hash:
         log.info('Adding to head', head=encode_hex(block.header.prevhash))
         try:
             apply_block(self.state, block)
         except (AssertionError, KeyError, ValueError, InvalidTransaction,
                 VerificationFailed) as e:
             log.info('Block %d (%s) with parent %s invalid, reason: %s' %
                      (block.number, encode_hex(block.header.hash),
                       encode_hex(block.header.prevhash), e))
             return False
         self.db.put(b'block:%d' % block.header.number, block.header.hash)
         block_score = self.get_score(
             block)  # side effect: put 'score:' cache in db
         self.head_hash = block.header.hash
         for i, tx in enumerate(block.transactions):
             self.db.put(b'txindex:' + tx.hash,
                         rlp.encode([block.number, i]))
         assert self.get_blockhash_by_number(
             block.header.number) == block.header.hash
         deletes = self.state.deletes
     # Or is the block being added to a chain that is not currently the head?
     elif block.header.prevhash in self.env.db:
         log.info(
             'Receiving block not on head, adding to secondary post state',
             prevhash=encode_hex(block.header.prevhash))
         temp_state = self.mk_poststate_of_blockhash(block.header.prevhash)
         try:
             apply_block(temp_state, block)
         except (AssertionError, KeyError, ValueError, InvalidTransaction,
                 VerificationFailed) as e:
             log.info('Block %s with parent %s invalid, reason: %s' %
                      (encode_hex(block.header.hash),
                       encode_hex(block.header.prevhash), e))
             return False
         deletes = temp_state.deletes
         block_score = self.get_score(block)
         # If the block should be the new head, replace the head
         if block_score > self.get_score(self.head):
             b = block
             new_chain = {}
             # Find common ancestor
             while b.header.number >= int(self.db.get('GENESIS_NUMBER')):
                 new_chain[b.header.number] = b
                 key = b'block:%d' % b.header.number
                 orig_at_height = self.db.get(
                     key) if key in self.db else None
                 if orig_at_height == b.header.hash:
                     break
                 if b.prevhash not in self.db or self.db.get(
                         b.prevhash) == 'GENESIS':
                     break
                 b = self.get_parent(b)
             # Replace block index and tx indices
             replace_from = b.header.number
             for i in itertools.count(replace_from):
                 log.info('Rewriting height %d' % i)
                 key = b'block:%d' % i
                 orig_at_height = self.db.get(
                     key) if key in self.db else None
                 if orig_at_height:
                     self.db.delete(key)
                     orig_block_at_height = self.get_block(orig_at_height)
                     for tx in orig_block_at_height.transactions:
                         if b'txindex:' + tx.hash in self.db:
                             self.db.delete(b'txindex:' + tx.hash)
                 if i in new_chain:
                     new_block_at_height = new_chain[i]
                     self.db.put(key, new_block_at_height.header.hash)
                     for i, tx in enumerate(
                             new_block_at_height.transactions):
                         self.db.put(
                             b'txindex:' + tx.hash,
                             rlp.encode([new_block_at_height.number, i]))
                 if i not in new_chain and not orig_at_height:
                     break
             self.head_hash = block.header.hash
             self.state = temp_state
     # Block has no parent yet
     else:
         if block.header.prevhash not in self.parent_queue:
             self.parent_queue[block.header.prevhash] = []
         self.parent_queue[block.header.prevhash].append(block)
         log.info(
             'Got block %d (%s) with prevhash %s, parent not found. Delaying for now'
             % (block.number, encode_hex(
                 block.hash), encode_hex(block.prevhash)))
         return False
     self.add_child(block)
     self.db.put('head_hash', self.head_hash)
     self.db.put(block.hash, rlp.encode(block))
     self.db.put(b'deletes:' + block.hash, b''.join(deletes))
     print('Saved %d trie node deletes for block %d (%s)' %
           (len(deletes), block.number, utils.encode_hex(block.hash)))
     # Delete old junk data
     old_block_hash = self.get_blockhash_by_number(block.number -
                                                   self.max_history)
     if old_block_hash:
         try:
             deletes = self.db.get(b'deletes:' + old_block_hash)
             print('Deleting up to %d trie nodes' % (len(deletes) // 32))
             rdb = RefcountDB(self.db)
             for i in range(0, len(deletes), 32):
                 rdb.delete(deletes[i:i + 32])
             self.db.delete(b'deletes:' + old_block_hash)
         except KeyError as e:
             print(e)
             pass
     self.db.commit()
     assert (b'deletes:' + block.hash) in self.db
     log.info('Added block %d (%s) with %d txs and %d gas' % \
         (block.header.number, encode_hex(block.header.hash)[:8],
          len(block.transactions), block.header.gas_used))
     if self.new_head_cb and block.header.number != 0:
         self.new_head_cb(block)
     if block.header.hash in self.parent_queue:
         for _blk in self.parent_queue[block.header.hash]:
             self.add_block(_blk)
         del self.parent_queue[block.header.hash]
     return True
示例#40
0
def test_logs(casper, funded_privkey, new_epoch, get_logs, deposit_validator,
              mk_suggested_vote, get_last_log, casper_chain, logout_validator):
    new_epoch()
    assert casper.current_epoch() == 1
    assert casper.next_validator_index() == 1

    validator_index = casper.next_validator_index()
    deposit_validator(funded_privkey, 1900 * 10**18)
    # Deposit log
    log1 = get_last_log(casper_chain, casper)
    assert set(('_from', '_validation_address', '_validator_index',
                '_start_dyn', '_amount', '_event_type')) == log1.keys()
    assert log1['_event_type'] == b'Deposit'
    assert log1['_from'] == '0x' + utils.encode_hex(
        utils.privtoaddr(funded_privkey))
    assert log1['_validator_index'] == validator_index

    new_epoch()
    # Test epoch logs
    receipt = casper_chain.head_state.receipts[-1]
    logs = get_logs(receipt, casper)
    log_old = logs[-2]
    log_new = logs[-1]

    assert set(('_number', '_checkpoint_hash', '_is_justified',
                '_is_finalized', '_event_type')) == log_old.keys()
    # New epoch log
    assert log_new['_event_type'] == b'Epoch'
    assert log_new['_number'] == 2
    assert log_new['_is_justified'] is False
    assert log_new['_is_finalized'] is False
    # Insta finalized previous
    assert log_old['_event_type'] == b'Epoch'
    assert log_old['_number'] == 1
    assert log_old['_is_justified'] is True
    assert log_old['_is_finalized'] is True

    new_epoch()
    new_epoch()

    casper.vote(mk_suggested_vote(validator_index, funded_privkey))
    # vote log
    log2 = get_last_log(casper_chain, casper)
    assert set(('_from', '_validator_index', '_target_hash', '_target_epoch',
                '_source_epoch', '_event_type')) == log2.keys()
    assert log2['_event_type'] == b'Vote'
    assert log2['_from'] == '0x' + utils.encode_hex(
        utils.privtoaddr(funded_privkey))

    new_epoch()
    casper.vote(mk_suggested_vote(validator_index, funded_privkey))
    log3 = get_last_log(casper_chain, casper)
    assert log3['_event_type'] == b'Vote'

    logout_validator(validator_index, funded_privkey)
    # Logout log
    log4 = get_last_log(casper_chain, casper)
    assert set(('_from', '_validator_index', '_end_dyn',
                '_event_type')) == log4.keys()
    assert log4['_event_type'] == b'Logout'
    assert log4['_from'] == '0x' + utils.encode_hex(
        utils.privtoaddr(funded_privkey))

    # Need to vote 'dynasty_logout_delay'  epochs before logout is active
    for _ in range(casper.dynasty_logout_delay()):
        new_epoch()
        casper.vote(mk_suggested_vote(validator_index, funded_privkey))

    for i in range(casper.withdrawal_delay() + 1):
        new_epoch()

    cur_epoch = casper.current_epoch()
    end_epoch = casper.dynasty_start_epoch(
        casper.validators__end_dynasty(validator_index) + 1)
    assert cur_epoch == end_epoch + casper.withdrawal_delay(
    )  # so we are allowed to withdraw

    casper.withdraw(validator_index)

    # Withdrawal log, finally
    log5 = get_last_log(casper_chain, casper)
    assert set(
        ('_to', '_validator_index', '_amount', '_event_type')) == log5.keys()
    assert log5['_event_type'] == b'Withdraw'
    assert log5['_to'] == '0x' + utils.encode_hex(
        utils.privtoaddr(funded_privkey))
示例#41
0
 def __repr__(self):
     return '<Transaction(%s)>' % encode_hex(self.hash)[:4]
示例#42
0
 def __structlog__(self):
     return encode_hex(self.hash)
示例#43
0
def vm_execute(ext, msg, code):
    # precompute trace flag
    # if we trace vm, we're in slow mode anyway
    trace_vm = log_vm_op.is_active('trace')

    compustate = Compustate(gas=msg.gas)
    stk = compustate.stack
    mem = compustate.memory

    processed_code = preprocess_code(code)

    s = time.time()
    op = None
    steps = 0
    _prevop = None  # for trace only

    while True:
        # print('op: ', op, time.time() - s)
        # s = time.time()
        # stack size limit error
        if compustate.pc not in processed_code:
            return vm_exception('INVALID START POINT')

        _data = processed_code[compustate.pc]
        gas, min_stack, max_stack, compustate.pc = _data[:4]
        ops = _data[4:]

        # out of gas error
        if gas > compustate.gas:
            return vm_exception('OUT OF GAS')

        # insufficient stack error
        if not (min_stack <= len(compustate.stack) <= max_stack):
            return vm_exception('INCOMPATIBLE STACK LENGTH',
                                min_stack=min_stack,
                                have=len(compustate.stack),
                                max_stack=max_stack)

        # Apply operation
        compustate.gas -= gas

        for op in ops:

            if trace_vm:
                """
                This diverges from normal logging, as we use the logging namespace
                only to decide which features get logged in 'eth.vm.op'
                i.e. tracing can not be activated by activating a sub
                like 'eth.vm.op.stack'
                """
                trace_data = {}
                trace_data['stack'] = list(
                    map(to_string, list(compustate.stack)))
                if _prevop in (op_MLOAD, op_MSTORE, op_MSTORE8, op_SHA3,
                               op_CALL, op_CALLCODE, op_CREATE,
                               op_CALLDATACOPY, op_CODECOPY, op_EXTCODECOPY):
                    if len(compustate.memory) < 1024:
                        trace_data['memory'] = \
                            b''.join([encode_hex(ascii_chr(x)) for x
                                      in compustate.memory])
                    else:
                        trace_data['sha3memory'] = \
                            encode_hex(utils.sha3(''.join([ascii_chr(x) for
                                                           x in compustate.memory])))
                if _prevop in (op_SSTORE, op_SLOAD) or steps == 0:
                    trace_data['storage'] = ext.log_storage(msg.to)
                # trace_data['gas'] = to_string(compustate.gas + fee)
                trace_data['inst'] = op
                trace_data['pc'] = to_string(compustate.pc - 1)
                if steps == 0:
                    trace_data['depth'] = msg.depth
                    trace_data['address'] = msg.to
                trace_data['op'] = op
                trace_data['steps'] = steps
                # if op[:4] == 'PUSH':
                #     trace_data['pushvalue'] = pushval
                log_vm_op.trace('vm', **trace_data)
                steps += 1
                _prevop = op

            # Invalid operation
            if op == INVALID:
                return vm_exception('INVALID OP', opcode=op)

            # Valid operations
            if op < 0x10:
                if op == op_STOP:
                    return peaceful_exit('STOP', compustate.gas, [])
                elif op == op_ADD:
                    stk.append((stk.pop() + stk.pop()) & TT256M1)
                elif op == op_SUB:
                    stk.append((stk.pop() - stk.pop()) & TT256M1)
                elif op == op_MUL:
                    stk.append((stk.pop() * stk.pop()) & TT256M1)
                elif op == op_DIV:
                    s0, s1 = stk.pop(), stk.pop()
                    stk.append(0 if s1 == 0 else s0 // s1)
                elif op == op_MOD:
                    s0, s1 = stk.pop(), stk.pop()
                    stk.append(0 if s1 == 0 else s0 % s1)
                elif op == op_SDIV:
                    s0, s1 = utils.to_signed(stk.pop()), utils.to_signed(
                        stk.pop())
                    stk.append(0 if s1 == 0 else (abs(s0) // abs(s1) *
                                                  (-1 if s0 * s1 < 0 else 1))
                               & TT256M1)
                elif op == op_SMOD:
                    s0, s1 = utils.to_signed(stk.pop()), utils.to_signed(
                        stk.pop())
                    stk.append(0 if s1 == 0 else (abs(s0) % abs(s1) *
                                                  (-1 if s0 < 0 else 1))
                               & TT256M1)
                elif op == op_ADDMOD:
                    s0, s1, s2 = stk.pop(), stk.pop(), stk.pop()
                    stk.append((s0 + s1) % s2 if s2 else 0)
                elif op == op_MULMOD:
                    s0, s1, s2 = stk.pop(), stk.pop(), stk.pop()
                    stk.append((s0 * s1) % s2 if s2 else 0)
                elif op == op_EXP:
                    base, exponent = stk.pop(), stk.pop()
                    # fee for exponent is dependent on its bytes
                    # calc n bytes to represent exponent
                    nbytes = len(utils.encode_int(exponent))
                    expfee = nbytes * opcodes.GEXPONENTBYTE
                    if compustate.gas < expfee:
                        compustate.gas = 0
                        return vm_exception('OOG EXPONENT')
                    compustate.gas -= expfee
                    stk.append(pow(base, exponent, TT256))
                elif op == op_SIGNEXTEND:
                    s0, s1 = stk.pop(), stk.pop()
                    if s0 <= 31:
                        testbit = s0 * 8 + 7
                        if s1 & (1 << testbit):
                            stk.append(s1 | (TT256 - (1 << testbit)))
                        else:
                            stk.append(s1 & ((1 << testbit) - 1))
                    else:
                        stk.append(s1)
            elif op < 0x20:
                if op == op_LT:
                    stk.append(1 if stk.pop() < stk.pop() else 0)
                elif op == op_GT:
                    stk.append(1 if stk.pop() > stk.pop() else 0)
                elif op == op_SLT:
                    s0, s1 = utils.to_signed(stk.pop()), utils.to_signed(
                        stk.pop())
                    stk.append(1 if s0 < s1 else 0)
                elif op == op_SGT:
                    s0, s1 = utils.to_signed(stk.pop()), utils.to_signed(
                        stk.pop())
                    stk.append(1 if s0 > s1 else 0)
                elif op == op_EQ:
                    stk.append(1 if stk.pop() == stk.pop() else 0)
                elif op == op_ISZERO:
                    stk.append(0 if stk.pop() else 1)
                elif op == op_AND:
                    stk.append(stk.pop() & stk.pop())
                elif op == op_OR:
                    stk.append(stk.pop() | stk.pop())
                elif op == op_XOR:
                    stk.append(stk.pop() ^ stk.pop())
                elif op == op_NOT:
                    stk.append(TT256M1 - stk.pop())
                elif op == op_BYTE:
                    s0, s1 = stk.pop(), stk.pop()
                    if s0 >= 32:
                        stk.append(0)
                    else:
                        stk.append((s1 // 256**(31 - s0)) % 256)
            elif op < 0x40:
                if op == op_SHA3:
                    s0, s1 = stk.pop(), stk.pop()
                    compustate.gas -= opcodes.GSHA3WORD * \
                        (utils.ceil32(s1) // 32)
                    if compustate.gas < 0:
                        return vm_exception('OOG PAYING FOR SHA3')
                    if not mem_extend(mem, compustate, op, s0, s1):
                        return vm_exception('OOG EXTENDING MEMORY')
                    data = b''.join(map(ascii_chr, mem[s0:s0 + s1]))
                    stk.append(utils.big_endian_to_int(utils.sha3(data)))
                elif op == op_ADDRESS:
                    stk.append(utils.coerce_to_int(msg.to))
                elif op == op_BALANCE:
                    addr = utils.coerce_addr_to_hex(stk.pop() % 2**160)
                    stk.append(ext.get_balance(addr))
                elif op == op_ORIGIN:
                    stk.append(utils.coerce_to_int(ext.tx_origin))
                elif op == op_CALLER:
                    stk.append(utils.coerce_to_int(msg.sender))
                elif op == op_CALLVALUE:
                    stk.append(msg.value)
                elif op == op_CALLDATALOAD:
                    stk.append(msg.data.extract32(stk.pop()))
                elif op == op_CALLDATASIZE:
                    stk.append(msg.data.size)
                elif op == op_CALLDATACOPY:
                    mstart, dstart, size = stk.pop(), stk.pop(), stk.pop()
                    if not mem_extend(mem, compustate, op, mstart, size):
                        return vm_exception('OOG EXTENDING MEMORY')
                    if not data_copy(compustate, size):
                        return vm_exception('OOG COPY DATA')
                    msg.data.extract_copy(mem, mstart, dstart, size)
                elif op == op_CODESIZE:
                    stk.append(len(code))
                elif op == op_CODECOPY:
                    start, s1, size = stk.pop(), stk.pop(), stk.pop()
                    if not mem_extend(mem, compustate, op, start, size):
                        return vm_exception('OOG EXTENDING MEMORY')
                    if not data_copy(compustate, size):
                        return vm_exception('OOG COPY DATA')
                    for i in range(size):
                        if s1 + i < len(code):
                            mem[start + i] = utils.safe_ord(code[s1 + i])
                        else:
                            mem[start + i] = 0
                elif op == op_GASPRICE:
                    stk.append(ext.tx_gasprice)
                elif op == op_EXTCODESIZE:
                    addr = utils.coerce_addr_to_hex(stk.pop() % 2**160)
                    stk.append(len(ext.get_code(addr) or b''))
                elif op == op_EXTCODECOPY:
                    addr = utils.coerce_addr_to_hex(stk.pop() % 2**160)
                    start, s2, size = stk.pop(), stk.pop(), stk.pop()
                    extcode = ext.get_code(addr) or b''
                    assert utils.is_string(extcode)
                    if not mem_extend(mem, compustate, op, start, size):
                        return vm_exception('OOG EXTENDING MEMORY')
                    if not data_copy(compustate, size):
                        return vm_exception('OOG COPY DATA')
                    for i in range(size):
                        if s2 + i < len(extcode):
                            mem[start + i] = utils.safe_ord(extcode[s2 + i])
                        else:
                            mem[start + i] = 0
            elif op < 0x50:
                if op == op_BLOCKHASH:
                    stk.append(
                        utils.big_endian_to_int(ext.block_hash(stk.pop())))
                elif op == op_COINBASE:
                    stk.append(utils.big_endian_to_int(ext.block_coinbase))
                elif op == op_TIMESTAMP:
                    stk.append(ext.block_timestamp)
                elif op == op_NUMBER:
                    stk.append(ext.block_number)
                elif op == op_DIFFICULTY:
                    stk.append(ext.block_difficulty)
                elif op == op_GASLIMIT:
                    stk.append(ext.block_gas_limit)
            elif op < 0x60:
                if op == op_POP:
                    stk.pop()
                elif op == op_MLOAD:
                    s0 = stk.pop()
                    if not mem_extend(mem, compustate, op, s0, 32):
                        return vm_exception('OOG EXTENDING MEMORY')
                    data = 0
                    for c in mem[s0:s0 + 32]:
                        data = (data << 8) + c
                    stk.append(data)
                elif op == op_MSTORE:
                    s0, s1 = stk.pop(), stk.pop()
                    if not mem_extend(mem, compustate, op, s0, 32):
                        return vm_exception('OOG EXTENDING MEMORY')
                    v = s1
                    for i in range(31, -1, -1):
                        mem[s0 + i] = v % 256
                        v //= 256
                elif op == op_MSTORE8:
                    s0, s1 = stk.pop(), stk.pop()
                    if not mem_extend(mem, compustate, op, s0, 1):
                        return vm_exception('OOG EXTENDING MEMORY')
                    mem[s0] = s1 % 256
                elif op == op_SLOAD:
                    stk.append(ext.get_storage_data(msg.to, stk.pop()))
                elif op == op_SSTORE:
                    s0, s1 = stk.pop(), stk.pop()
                    if ext.get_storage_data(msg.to, s0):
                        gascost = opcodes.GSTORAGEMOD if s1 else opcodes.GSTORAGEKILL
                        refund = 0 if s1 else opcodes.GSTORAGEREFUND
                    else:
                        gascost = opcodes.GSTORAGEADD if s1 else opcodes.GSTORAGEMOD
                        refund = 0
                    if compustate.gas < gascost:
                        return vm_exception('OUT OF GAS')
                    compustate.gas -= gascost
                    # adds neg gascost as a refund if below zero
                    ext.add_refund(refund)
                    ext.set_storage_data(msg.to, s0, s1)
                elif op == op_JUMP:
                    compustate.pc = stk.pop()
                    opnew = processed_code[compustate.pc][4] if \
                        compustate.pc in processed_code else op_STOP
                    if opnew != op_JUMPDEST:
                        return vm_exception('BAD JUMPDEST')
                elif op == op_JUMPI:
                    s0, s1 = stk.pop(), stk.pop()
                    if s1:
                        compustate.pc = s0
                        opnew = processed_code[compustate.pc][4] if \
                            compustate.pc in processed_code else op_STOP
                        if opnew != op_JUMPDEST:
                            return vm_exception('BAD JUMPDEST')
                elif op == op_PC:
                    stk.append(compustate.pc - 1)
                elif op == op_MSIZE:
                    stk.append(len(mem))
                elif op == op_GAS:
                    stk.append(compustate.gas)  # AFTER subtracting cost 1
            elif op_PUSH1 <= (op & 255) <= op_PUSH32:
                # Hide push value in high-order bytes of op
                stk.append(op >> 8)
            elif op_DUP1 <= op <= op_DUP16:
                depth = op - op_DUP1 + 1
                stk.append(stk[-depth])
            elif op_SWAP1 <= op <= op_SWAP16:
                depth = op - op_SWAP1 + 1
                temp = stk[-depth - 1]
                stk[-depth - 1] = stk[-1]
                stk[-1] = temp

            elif op_LOG0 <= op <= op_LOG4:
                """
                0xa0 ... 0xa4, 32/64/96/128/160 + len(data) gas
                a. Opcodes LOG0...LOG4 are added, takes 2-6 stack arguments
                        MEMSTART MEMSZ (TOPIC1) (TOPIC2) (TOPIC3) (TOPIC4)
                b. Logs are kept track of during tx execution exactly the same way as suicides
                   (except as an ordered list, not a set).
                   Each log is in the form [address, [topic1, ... ], data] where:
                   * address is what the ADDRESS opcode would output
                   * data is mem[MEMSTART: MEMSTART + MEMSZ]
                   * topics are as provided by the opcode
                c. The ordered list of logs in the transaction are expressed as [log0, log1, ..., logN].
                """
                depth = op - op_LOG0
                mstart, msz = stk.pop(), stk.pop()
                topics = [stk.pop() for x in range(depth)]
                compustate.gas -= msz * opcodes.GLOGBYTE
                if not mem_extend(mem, compustate, op, mstart, msz):
                    return vm_exception('OOG EXTENDING MEMORY')
                data = b''.join(map(ascii_chr, mem[mstart:mstart + msz]))
                ext.log(msg.to, topics, data)
                log_log.trace('LOG',
                              to=msg.to,
                              topics=topics,
                              data=list(map(utils.safe_ord, data)))
                # print('LOG', msg.to, topics, list(map(ord, data)))

            elif op == op_CREATE:
                value, mstart, msz = stk.pop(), stk.pop(), stk.pop()
                if not mem_extend(mem, compustate, op, mstart, msz):
                    return vm_exception('OOG EXTENDING MEMORY')
                if ext.get_balance(msg.to) >= value and msg.depth < 1024:
                    cd = CallData(mem, mstart, msz)
                    create_msg = Message(msg.to, b'', value, compustate.gas,
                                         cd, msg.depth + 1)
                    o, gas, addr = ext.create(create_msg)
                    if o:
                        stk.append(utils.coerce_to_int(addr))
                        compustate.gas = gas
                    else:
                        stk.append(0)
                        compustate.gas = 0
                else:
                    stk.append(0)
            elif op == op_CALL:
                gas, to, value, meminstart, meminsz, memoutstart, memoutsz = \
                    stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop()
                if not mem_extend(mem, compustate, op, meminstart, meminsz) or \
                        not mem_extend(mem, compustate, op, memoutstart, memoutsz):
                    return vm_exception('OOG EXTENDING MEMORY')
                to = utils.encode_int(to)
                to = ((b'\x00' * (32 - len(to))) + to)[12:]
                extra_gas = (not ext.account_exists(to)) * opcodes.GCALLNEWACCOUNT + \
                    (value > 0) * opcodes.GCALLVALUETRANSFER
                submsg_gas = gas + opcodes.GSTIPEND * (value > 0)
                if compustate.gas < gas + extra_gas:
                    return vm_exception('OUT OF GAS', needed=gas + extra_gas)
                if ext.get_balance(msg.to) >= value and msg.depth < 1024:
                    compustate.gas -= (gas + extra_gas)
                    cd = CallData(mem, meminstart, meminsz)
                    call_msg = Message(msg.to,
                                       to,
                                       value,
                                       submsg_gas,
                                       cd,
                                       msg.depth + 1,
                                       code_address=to)
                    result, gas, data = ext.msg(call_msg)
                    if result == 0:
                        stk.append(0)
                    else:
                        stk.append(1)
                        compustate.gas += gas
                        for i in range(min(len(data), memoutsz)):
                            mem[memoutstart + i] = data[i]
                else:
                    compustate.gas -= (gas + extra_gas - submsg_gas)
                    stk.append(0)
            elif op == op_CALLCODE:
                gas, to, value, meminstart, meminsz, memoutstart, memoutsz = \
                    stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop()
                if not mem_extend(mem, compustate, op, meminstart, meminsz) or \
                        not mem_extend(mem, compustate, op, memoutstart, memoutsz):
                    return vm_exception('OOG EXTENDING MEMORY')
                extra_gas = (value > 0) * opcodes.GCALLVALUETRANSFER
                submsg_gas = gas + opcodes.GSTIPEND * (value > 0)
                if compustate.gas < gas + extra_gas:
                    return vm_exception('OUT OF GAS', needed=gas + extra_gas)
                if ext.get_balance(msg.to) >= value and msg.depth < 1024:
                    compustate.gas -= (gas + extra_gas)
                    to = utils.encode_int(to)
                    to = ((b'\x00' * (32 - len(to))) + to)[12:]
                    cd = CallData(mem, meminstart, meminsz)
                    call_msg = Message(msg.to,
                                       msg.to,
                                       value,
                                       submsg_gas,
                                       cd,
                                       msg.depth + 1,
                                       code_address=to)
                    result, gas, data = ext.msg(call_msg)
                    if result == 0:
                        stk.append(0)
                    else:
                        stk.append(1)
                        compustate.gas += gas
                        for i in range(min(len(data), memoutsz)):
                            mem[memoutstart + i] = data[i]
                else:
                    compustate.gas -= (gas + extra_gas - submsg_gas)
                    stk.append(0)
            elif op == op_RETURN:
                s0, s1 = stk.pop(), stk.pop()
                if not mem_extend(mem, compustate, op, s0, s1):
                    return vm_exception('OOG EXTENDING MEMORY')
                return peaceful_exit('RETURN', compustate.gas, mem[s0:s0 + s1])
            elif op == op_SUICIDE:
                to = utils.encode_int(stk.pop())
                to = ((b'\x00' * (32 - len(to))) + to)[12:]
                xfer = ext.get_balance(msg.to)
                ext.set_balance(to, ext.get_balance(to) + xfer)
                ext.set_balance(msg.to, 0)
                ext.add_suicide(msg.to)
                # print('suiciding %s %s %d' % (msg.to, to, xfer))
                return 1, compustate.gas, []
示例#44
0
ecrecover_test = """
def test_ecrecover(h: bytes32, v:num256, r:num256, s:num256) -> address:
    return ecrecover(h, v, r, s)

def test_ecrecover2() -> address:
    return ecrecover(0x3535353535353535353535353535353535353535353535353535353535353535,
                     as_num256(28),
                     as_num256(63198938615202175987747926399054383453528475999185923188997970550032613358815),
                     as_num256(6577251522710269046055727877571505144084475024240851440410274049870970796685))
"""

c = s.abi_contract(ecrecover_test, language='viper')
h = b'\x35' * 32
k = b'\x46' * 32
v, r, S = u.ecsign(h, k)
assert c.test_ecrecover(h, v, r, S) == '0x' + u.encode_hex(u.privtoaddr(k))
assert c.test_ecrecover2() == '0x' + u.encode_hex(u.privtoaddr(k))

print("Passed ecrecover test")

extract32_code = """
y: bytes <= 100
def extrakt32(inp: bytes <= 100, index: num) -> bytes32:
    return extract32(inp, index)

def extrakt32_mem(inp: bytes <= 100, index: num) -> bytes32:
    x = inp
    return extract32(x, index)

def extrakt32_storage(index: num, inp: bytes <= 100) -> bytes32:
    self.y = inp
示例#45
0
def main():
    '''
    Main method. Runs the program if it is used standalone (rather than as an exported library).
    '''

    parser = _get_args()

    if len(parser.target_address) != 42:
        log.error(
            "Target Address length does not appear to match the correct length of an Ethereum address"
        )
        sys.exit(1)
    if len(parser.from_address) != 42:
        log.error(
            "From Address length does not appear to match the correct length of an Ethereum address"
        )
        sys.exit(1)
    if parser.target_address[0:2] != "0x":
        log.error(
            "Target address not in expected format, expected address to start with 0x"
        )
        sys.exit(1)
    if parser.from_address[0:2] != "0x":
        log.error(
            "From address not in expected format, expected address to start with 0x"
        )
        sys.exit(1)

    if not check_checksum(parser.target_address):
        log.error(
            "Target address is not correctly encoded using EIP-55 {}".format(
                parser.target_address))
        sys.exit(1)
    if not check_checksum(parser.from_address):
        log.error(
            "From address is not correctly encoded using EIP-55 {}".format(
                parser.from_address))
        sys.exit(1)

    toAddress = normalize_address(parser.target_address)
    fromAddress = normalize_address(parser.from_address)
    gasPrice = parser.gas_price
    gasLimit = parser.gas_limit
    sendAmount = parser.amount
    if (parser.dapp_data):
        dappData = rec_bin(parser.dapp_data)
    else:
        dappData = b""

    tx, addressB, commit, randw = _generateAddressBInternal(
        fromAddress, toAddress, sendAmount, dappData, gasPrice, gasLimit)

    # print("-"* 35)
    # printRemix(fromAddress, tx, encode_hex(randw))
    print("-" * 35)

    print("AddressB: {}".format(addressB)
          )  # addressB also can retrieved using tx.to_dict().get("sender")
    print("commit: {}".format(encode_hex(commit)))
    print("witness (w): {}".format(encode_hex(randw)))
    # print("Reveal Transation (json): {}".format(tx.to_dict()))
    print("Reveal Transaction (hex): {}".format(encode_hex(rlp.encode(tx))))
    print(
        "You can use the reveal transaction hex to broadcast with any service you like, e.g.: https://ropsten.etherscan.io/pushTx"
    )
示例#46
0
                                           0], [1, 0, 0, 1, 0, 0, 1,
                                                0], [1, 0] * 8):
    assert decode_bin_path(encode_bin_path(bytes(path))) == bytes(path)

r1 = None

for _ in range(3):
    t = Trie(EphemDB(), b'')
    for i, (k, v) in enumerate(shuffle_in_place(kvpairs)):
        #print(t.to_dict())
        t.update(k, v)
        assert t.get(k) == v
        if not i % 50:
            if not i % 250:
                t.to_dict()
            print("Length of branch at %d nodes: %d" %
                  (i, len(rlp.encode(t.get_branch(k)))))
    assert r1 is None or t.root == r1
    r1 = t.root
    t.update(kvpairs[0][0], kvpairs[0][1])
    assert t.root == r1
    print(t.get_branch(kvpairs[0][0]))
    print(t.get_branch(kvpairs[0][0][::-1]))
    print(encode_hex(t.root))
    for k, v in shuffle_in_place(kvpairs):
        t.update(k, b'')
        if not random.randrange(100):
            t.to_dict()
    #t.print_nodes()
    assert t.root == b''
示例#47
0
def rec_hex(x):
    if isinstance(x, list):
        return [rec_hex(elem) for elem in x]
    else:
        return utils.encode_hex(x)
示例#48
0
from ethereum.utils import mk_contract_address, encode_hex
source = '0x4a574510c7014e4ae985403536074abe582adfc8'

L = []
# DAO
L.append('0xbb9bc244d798123fde783fcc1c72d3bb8c189413')
# DAO extrabalance
L.append('0x807640a13483f8ac783c557fcdf27be11ea4ac7a')
# child DAOs (created by DAO creator)
L.extend(
    [b'0x' + encode_hex(mk_contract_address(source, i)) for i in range(1, 58)])
# child extrabalances
L.extend([
    b'0x' + encode_hex(mk_contract_address(mk_contract_address(source, i), 0))
    for i in range(1, 58)
])
示例#49
0
def decodeBlock(block):
    """
    Decode various pieces of information (from hex) for a block and return the parsed data.

    Note that the block is of the form:
 	{
       "id": 0,
    	"jsonrpc": "2.0",
    	"result": {
    	  "number": "0xf4241",
    	  "hash": "0xcb5cab7266694daa0d28cbf40496c08dd30bf732c41e0455e7ad389c10d79f4f",
    	  "parentHash": "0x8e38b4dbf6b11fcc3b9dee84fb7986e29ca0a02cecd8977c161ff7333329681e",
    	  "nonce": "0x9112b8c2b377fbe8",
    	  "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
    	  "logsBloom": "0x0",
    	  "transactionsRoot": "0xc61c50a0a2800ddc5e9984af4e6668de96aee1584179b3141f458ffa7d4ecec6",
    	  "stateRoot": "0x7dd4aabb93795feba9866821c0c7d6a992eda7fbdd412ea0f715059f9654ef23",
    	  "receiptRoot": "0xb873ddefdb56d448343d13b188241a4919b2de10cccea2ea573acf8dbc839bef",
    	  "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226",
    	  "difficulty": "0xb6b4bbd735f",
    	  "totalDifficulty": "0x63056041aaea71c9",
    	  "size": "0x292",
    	  "extraData": "0xd783010303844765746887676f312e352e31856c696e7578",
    	  "gasLimit": "0x2fefd8",
    	  "gasUsed": "0x5208",
    	  "timestamp": "0x56bfb41a",
    	  "transactions": [
    	    {
    	      "hash": "0xefb6c796269c0d1f15fdedb5496fa196eb7fb55b601c0fa527609405519fd581",
    	      "nonce": "0x2a121",
    	      "blockHash": "0xcb5cab7266694daa0d28cbf40496c08dd30bf732c41e0455e7ad389c10d79f4f",
    	      "blockNumber": "0xf4241",
    	      "transactionIndex": "0x0",
    	      "from": "0x2a65aca4d5fc5b5c859090a6c34d164135398226",
    	      "to": "0x819f4b08e6d3baa33ba63f660baed65d2a6eb64c",
    	      "value": "0xe8e43bc79c88000",
    	      "gas": "0x15f90",
    	      "gasPrice": "0xba43b7400",
    	      "input": "0x"
    	    }
    	  ],
    	  "uncles": []
    	}
  	}
    """
    try:
        txs = []
        b = block
        if "result" in block:
            b = block["result"]
        # Filter the block
        new_block = {
            "number": int(b["number"], 16),
            "timestamp": int(b["timestamp"], 16),  # Timestamp is in unix time
            "transactions": [],
        }
        # Filter and decode each transaction and add it back
        # 	Value, gas, and gasPrice are all converted to ether
        reward = float(5.0)
        i = 1
        to = "to"
        isContractCreation = False
        fromContract = False
        toContract = False
        for t in b["transactions"]:
            if t["to"] == None:
                to = "0x" + encode_hex(
                    mk_contract_address(t["from"], int(t["nonce"], 16))
                )
                isContractCreation = True
                contractAddresses.append(to)
            elif t["to"] in contractAddresses:
                toContract = True
            else:
                to = t["to"]
            if t["from"] in contractAddresses:
                fromContract = True
            tx = makeTx(
                b["number"],
                i,
                b["timestamp"],
                t["from"],
                to,
                float(int(t["value"], 16)) / 1000000000000000000.0,
                isContractCreation,
                t["input"],
                t["gas"],
                t["gasPrice"],
                fromContract,
                toContract,
            )
            reward += (
                float(int(t["gas"], 16) * int(t["gasPrice"], 16))
                / 1000000000000000000.0
            )
            txs.append(tx)
            i += 1
        rewardTx = makeTx(
            b["number"],
            0,
            b["timestamp"],
            "REWARD",
            b["miner"],
            reward,
            isContractCreation,
            "",
            "0x0",
            "0x0",
            False,
            False,
        )
        txs.append(rewardTx)
        return txs

    except:
        return None
示例#50
0
def test_channelnewbalance_event(private_keys, settle_timeout, tester_state,
                                 tester_events, tester_token, tester_registry):
    """ Check the correct events are generated for deposit calls. """

    privatekey0 = private_keys[0]
    privatekey1 = private_keys[1]
    address0 = privatekey_to_address(privatekey0)
    address1 = privatekey_to_address(privatekey1)

    channel_manager = new_channelmanager(
        privatekey0,
        tester_state,
        tester_events.append,
        tester_registry,
        tester_token,
    )

    nettingchannel = new_nettingcontract(
        privatekey0,
        privatekey1,
        tester_state,
        tester_events.append,
        channel_manager,
        settle_timeout,
    )

    initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0)
    deposit_amount = initial_balance0 // 10

    assert tester_token.approve(
        nettingchannel.address, deposit_amount, sender=privatekey0) is True
    assert tester_token.approve(
        nettingchannel.address, deposit_amount, sender=privatekey1) is True

    previous_events = list(tester_events)
    assert nettingchannel.deposit(deposit_amount, sender=privatekey0) is True
    assert len(previous_events) + 2 == len(tester_events)

    block_number = tester_state.block.number

    transfer_event = tester_events[-2]
    assert transfer_event == {
        '_event_type': 'Transfer',
        '_from': encode_hex(address0),
        '_to': nettingchannel.address,
        '_value': deposit_amount,
    }

    newbalance_event = tester_events[-1]
    assert newbalance_event == {
        '_event_type': 'ChannelNewBalance',
        'token_address': encode_hex(tester_token.address),
        'participant': encode_hex(address0),
        'balance': deposit_amount,
        'block_number': block_number,
    }

    previous_events = list(tester_events)
    assert nettingchannel.deposit(deposit_amount, sender=privatekey1) is True
    assert len(previous_events) + 2 == len(tester_events)

    block_number = tester_state.block.number

    transfer_event = tester_events[-2]
    assert transfer_event == {
        '_event_type': 'Transfer',
        '_from': encode_hex(address1),
        '_to': nettingchannel.address,
        '_value': deposit_amount,
    }

    newbalance_event = tester_events[-1]
    assert newbalance_event == {
        '_event_type': 'ChannelNewBalance',
        'token_address': encode_hex(tester_token.address),
        'participant': encode_hex(address1),
        'balance': deposit_amount,
        'block_number': block_number,
    }
示例#51
0
def geth_create_blockchain(private_keys, geth_private_keys, p2p_base_port,
                           base_datadir, verbosity):
    # pylint: disable=too-many-locals,too-many-statements

    # TODO: handle better the errors cases:
    # - cant bind, port in use
    start_rpcport = 4000

    account_addresses = [
        privatekey_to_address(key) for key in set(private_keys)
    ]

    alloc = {
        address_encoder(address): {
            'balance': DEFAULT_BALANCE_BIN,
        }
        for address in account_addresses
    }

    genesis = {
        'config': {
            'homesteadBlock': 0,
        },
        'nonce': '0x0000000000000042',
        'mixhash':
        '0x0000000000000000000000000000000000000000000000000000000000000000',
        'difficulty': '0x40',
        'coinbase': '0x0000000000000000000000000000000000000000',
        'timestamp': '0x00',
        'parentHash':
        '0x0000000000000000000000000000000000000000000000000000000000000000',
        'extraData': 'raiden',
        'gasLimit': GAS_LIMIT_HEX,
        'alloc': alloc,
    }

    nodes_configuration = []
    for pos, key in enumerate(geth_private_keys):
        config = dict()

        # make the first node miner
        if pos == 0:
            config['minerthreads'] = 1  # conservative
            config['unlock'] = 0

        config['nodekey'] = key
        config['nodekeyhex'] = encode_hex(key)
        config['pub'] = encode_hex(privtopub(key))
        config['address'] = privatekey_to_address(key)
        config['port'] = p2p_base_port + pos
        config['rpcport'] = start_rpcport + pos
        config['enode'] = 'enode://{pub}@127.0.0.1:{port}'.format(
            pub=config['pub'],
            port=config['port'],
        )
        config['bootnodes'] = ','.join(node['enode']
                                       for node in nodes_configuration)

        nodes_configuration.append(config)

    cmds = []
    for i, config in enumerate(nodes_configuration):
        nodedir = os.path.join(base_datadir, config['nodekeyhex'])

        os.makedirs(nodedir)
        geth_init_datadir(genesis, nodedir)

        if 'minerthreads' in config:
            geth_create_account(nodedir, private_keys[i])

        commandline = geth_to_cmd(config, nodedir, verbosity)
        cmds.append(commandline)

    # save current term settings before running geth
    if isinstance(sys.stdin,
                  file):  # check that the test is running on non-capture mode
        term_settings = termios.tcgetattr(sys.stdin)

    processes_list = []
    for cmd in cmds:
        if '--unlock' in cmd:
            process = subprocess.Popen(cmd,
                                       universal_newlines=True,
                                       stdin=subprocess.PIPE)

            # --password wont work, write password to unlock
            process.stdin.write(DEFAULT_PASSPHRASE + os.linesep)  # Passphrase:
            process.stdin.write(DEFAULT_PASSPHRASE +
                                os.linesep)  # Repeat passphrase:
        else:
            process = subprocess.Popen(cmd)

        processes_list.append(process)
        assert process.returncode is None

    geth_wait_and_check(private_keys)

    # reenter echo mode (disabled by geth pasphrase prompt)
    if isinstance(sys.stdin, file):
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, term_settings)

    return processes_list
示例#52
0
文件: tester.py 项目: wub11/pyetherum
def int_to_0x_hex(v):
    o = encode_hex(int_to_big_endian(v))
    if o and o[0] == '0':
        return '0x' + o[1:]
    else:
        return '0x' + o
示例#53
0
def vm_execute(ext, msg, code):
    # precompute trace flag
    # if we trace vm, we're in slow mode anyway
    trace_vm = log_vm_op.is_active('trace')

    compustate = Compustate(gas=msg.gas)
    stk = compustate.stack
    mem = compustate.memory

    if code in code_cache:
        processed_code = code_cache[code]
    else:
        processed_code = preprocess_code(code)
        code_cache[code] = processed_code
        # print(processed_code.keys(), code)

    codelen = len(code)

    s = time.time()
    steps = 0
    _prevop = None  # for trace only

    while compustate.pc in processed_code:
        ops, minstack, maxstack, totgas, nextpos = processed_code[
            compustate.pc]

        if len(compustate.stack) < minstack:
            return vm_exception('INSUFFICIENT STACK')
        if len(compustate.stack) > maxstack:
            return vm_exception('STACK SIZE LIMIT EXCEEDED')
        if totgas > compustate.gas:
            return vm_exception('OUT OF GAS %d %d' % (totgas, compustate.gas))
        jumped = False

        compustate.gas -= totgas
        compustate.pc = nextpos

        # Invalid operation; can only come at the end of a chunk
        if ops[-1][0] == 'INVALID':
            return vm_exception('INVALID OP', opcode=ops[-1][1])

        for op, opcode, pushval in ops:

            if trace_vm:
                """
                This diverges from normal logging, as we use the logging namespace
                only to decide which features get logged in 'eth.vm.op'
                i.e. tracing can not be activated by activating a sub
                like 'eth.vm.op.stack'
                """
                trace_data = {}
                trace_data['stack'] = list(
                    map(to_string, list(compustate.stack)))
                if _prevop in ('MLOAD', 'MSTORE', 'MSTORE8', 'SHA3', 'CALL',
                               'CALLCODE', 'CREATE', 'CALLDATACOPY',
                               'CODECOPY', 'EXTCODECOPY'):
                    if len(compustate.memory) < 1024:
                        trace_data['memory'] = \
                            ''.join([encode_hex(ascii_chr(x)) for x
                                     in compustate.memory])
                    else:
                        trace_data['sha3memory'] = \
                            encode_hex(utils.sha3(b''.join([ascii_chr(x) for
                                                            x in compustate.memory])))
                if _prevop in ('SSTORE', ) or steps == 0:
                    trace_data['storage'] = ext.log_storage(msg.to)
                trace_data['gas'] = to_string(compustate.gas + totgas)
                trace_data['inst'] = opcode
                trace_data['pc'] = to_string(compustate.pc - 1)
                if steps == 0:
                    trace_data['depth'] = msg.depth
                    trace_data['address'] = msg.to
                trace_data['steps'] = steps
                trace_data['depth'] = msg.depth
                if op[:4] == 'PUSH':
                    trace_data['pushvalue'] = pushval
                log_vm_op.trace('vm', op=op, **trace_data)
                steps += 1
                _prevop = op

            # Valid operations
            # Pushes first because they are very frequent
            if 0x60 <= opcode <= 0x7f:
                # compustate.pc += opcode - 0x5f # Move 1 byte forward for
                # 0x60, up to 32 bytes for 0x7f
                stk.append(pushval)
            elif opcode < 0x10:
                if op == 'STOP':
                    return peaceful_exit('STOP', compustate.gas, [])
                elif op == 'ADD':
                    stk.append((stk.pop() + stk.pop()) & TT256M1)
                elif op == 'SUB':
                    stk.append((stk.pop() - stk.pop()) & TT256M1)
                elif op == 'MUL':
                    stk.append((stk.pop() * stk.pop()) & TT256M1)
                elif op == 'DIV':
                    s0, s1 = stk.pop(), stk.pop()
                    stk.append(0 if s1 == 0 else s0 // s1)
                elif op == 'MOD':
                    s0, s1 = stk.pop(), stk.pop()
                    stk.append(0 if s1 == 0 else s0 % s1)
                elif op == 'SDIV':
                    s0, s1 = utils.to_signed(stk.pop()), utils.to_signed(
                        stk.pop())
                    stk.append(0 if s1 == 0 else (abs(s0) // abs(s1) *
                                                  (-1 if s0 * s1 < 0 else 1))
                               & TT256M1)
                elif op == 'SMOD':
                    s0, s1 = utils.to_signed(stk.pop()), utils.to_signed(
                        stk.pop())
                    stk.append(0 if s1 == 0 else (abs(s0) % abs(s1) *
                                                  (-1 if s0 < 0 else 1))
                               & TT256M1)
                elif op == 'ADDMOD':
                    s0, s1, s2 = stk.pop(), stk.pop(), stk.pop()
                    stk.append((s0 + s1) % s2 if s2 else 0)
                elif op == 'MULMOD':
                    s0, s1, s2 = stk.pop(), stk.pop(), stk.pop()
                    stk.append((s0 * s1) % s2 if s2 else 0)
                elif op == 'EXP':
                    base, exponent = stk.pop(), stk.pop()
                    # fee for exponent is dependent on its bytes
                    # calc n bytes to represent exponent
                    nbytes = len(utils.encode_int(exponent))
                    expfee = nbytes * opcodes.GEXPONENTBYTE
                    if ext.post_clearing_hardfork():
                        expfee += opcodes.EXP_SUPPLEMENTAL_GAS * nbytes
                    if compustate.gas < expfee:
                        compustate.gas = 0
                        return vm_exception('OOG EXPONENT')
                    compustate.gas -= expfee
                    stk.append(pow(base, exponent, TT256))
                elif op == 'SIGNEXTEND':
                    s0, s1 = stk.pop(), stk.pop()
                    if s0 <= 31:
                        testbit = s0 * 8 + 7
                        if s1 & (1 << testbit):
                            stk.append(s1 | (TT256 - (1 << testbit)))
                        else:
                            stk.append(s1 & ((1 << testbit) - 1))
                    else:
                        stk.append(s1)
            elif opcode < 0x20:
                if op == 'LT':
                    stk.append(1 if stk.pop() < stk.pop() else 0)
                elif op == 'GT':
                    stk.append(1 if stk.pop() > stk.pop() else 0)
                elif op == 'SLT':
                    s0, s1 = utils.to_signed(stk.pop()), utils.to_signed(
                        stk.pop())
                    stk.append(1 if s0 < s1 else 0)
                elif op == 'SGT':
                    s0, s1 = utils.to_signed(stk.pop()), utils.to_signed(
                        stk.pop())
                    stk.append(1 if s0 > s1 else 0)
                elif op == 'EQ':
                    stk.append(1 if stk.pop() == stk.pop() else 0)
                elif op == 'ISZERO':
                    stk.append(0 if stk.pop() else 1)
                elif op == 'AND':
                    stk.append(stk.pop() & stk.pop())
                elif op == 'OR':
                    stk.append(stk.pop() | stk.pop())
                elif op == 'XOR':
                    stk.append(stk.pop() ^ stk.pop())
                elif op == 'NOT':
                    stk.append(TT256M1 - stk.pop())
                elif op == 'BYTE':
                    s0, s1 = stk.pop(), stk.pop()
                    if s0 >= 32:
                        stk.append(0)
                    else:
                        stk.append((s1 // 256**(31 - s0)) % 256)
            elif opcode < 0x40:
                if op == 'SHA3':
                    s0, s1 = stk.pop(), stk.pop()
                    compustate.gas -= opcodes.GSHA3WORD * \
                        (utils.ceil32(s1) // 32)
                    if compustate.gas < 0:
                        return vm_exception('OOG PAYING FOR SHA3')
                    if not mem_extend(mem, compustate, op, s0, s1):
                        return vm_exception('OOG EXTENDING MEMORY')
                    data = bytearray_to_bytestr(mem[s0:s0 + s1])
                    stk.append(utils.big_endian_to_int(utils.sha3(data)))
                elif op == 'ADDRESS':
                    stk.append(utils.coerce_to_int(msg.to))
                elif op == 'BALANCE':
                    if ext.post_anti_dos_hardfork():
                        if not eat_gas(compustate,
                                       opcodes.BALANCE_SUPPLEMENTAL_GAS):
                            return vm_exception("OUT OF GAS")
                    addr = utils.coerce_addr_to_hex(stk.pop() % 2**160)
                    stk.append(ext.get_balance(addr))
                elif op == 'ORIGIN':
                    stk.append(utils.coerce_to_int(ext.tx_origin))
                elif op == 'CALLER':
                    stk.append(utils.coerce_to_int(msg.sender))
                elif op == 'CALLVALUE':
                    stk.append(msg.value)
                elif op == 'CALLDATALOAD':
                    stk.append(msg.data.extract32(stk.pop()))
                elif op == 'CALLDATASIZE':
                    stk.append(msg.data.size)
                elif op == 'CALLDATACOPY':
                    mstart, dstart, size = stk.pop(), stk.pop(), stk.pop()
                    if not mem_extend(mem, compustate, op, mstart, size):
                        return vm_exception('OOG EXTENDING MEMORY')
                    if not data_copy(compustate, size):
                        return vm_exception('OOG COPY DATA')
                    msg.data.extract_copy(mem, mstart, dstart, size)
                elif op == 'CODESIZE':
                    stk.append(len(code))
                elif op == 'CODECOPY':
                    mstart, dstart, size = stk.pop(), stk.pop(), stk.pop()
                    if not mem_extend(mem, compustate, op, mstart, size):
                        return vm_exception('OOG EXTENDING MEMORY')
                    if not data_copy(compustate, size):
                        return vm_exception('OOG COPY DATA')
                    for i in range(size):
                        if dstart + i < len(code):
                            mem[mstart + i] = utils.safe_ord(code[dstart + i])
                        else:
                            mem[mstart + i] = 0
                elif op == 'RETURNDATACOPY':
                    mstart, dstart, size = stk.pop(), stk.pop(), stk.pop()
                    if not mem_extend(mem, compustate, op, mstart, size):
                        return vm_exception('OOG EXTENDING MEMORY')
                    if not data_copy(compustate, size):
                        return vm_exception('OOG COPY DATA')
                    if dstart + size > len(compustate.last_returned):
                        return vm_exception('RETURNDATACOPY out of range')
                    mem[mstart:mstart + size] = compustate.last_returned
                elif op == 'RETURNDATASIZE':
                    stk.append(len(compustate.last_returned))
                elif op == 'GASPRICE':
                    stk.append(ext.tx_gasprice)
                elif op == 'EXTCODESIZE':
                    if ext.post_anti_dos_hardfork():
                        if not eat_gas(compustate,
                                       opcodes.EXTCODELOAD_SUPPLEMENTAL_GAS):
                            return vm_exception("OUT OF GAS")
                    addr = utils.coerce_addr_to_hex(stk.pop() % 2**160)
                    stk.append(len(ext.get_code(addr) or b''))
                elif op == 'EXTCODECOPY':
                    if ext.post_anti_dos_hardfork():
                        if not eat_gas(compustate,
                                       opcodes.EXTCODELOAD_SUPPLEMENTAL_GAS):
                            return vm_exception("OUT OF GAS")
                    addr = utils.coerce_addr_to_hex(stk.pop() % 2**160)
                    start, s2, size = stk.pop(), stk.pop(), stk.pop()
                    extcode = ext.get_code(addr) or b''
                    assert utils.is_string(extcode)
                    if not mem_extend(mem, compustate, op, start, size):
                        return vm_exception('OOG EXTENDING MEMORY')
                    if not data_copy(compustate, size):
                        return vm_exception('OOG COPY DATA')
                    for i in range(size):
                        if s2 + i < len(extcode):
                            mem[start + i] = utils.safe_ord(extcode[s2 + i])
                        else:
                            mem[start + i] = 0
            elif opcode < 0x50:
                if op == 'BLOCKHASH':
                    if ext.post_metropolis_hardfork() and False:
                        bh_addr = ext.blockhash_store
                        stk.append(ext.get_storage_data(bh_addr, stk.pop()))
                    else:
                        stk.append(
                            utils.big_endian_to_int(ext.block_hash(stk.pop())))
                elif op == 'COINBASE':
                    stk.append(utils.big_endian_to_int(ext.block_coinbase))
                elif op == 'TIMESTAMP':
                    stk.append(ext.block_timestamp)
                elif op == 'NUMBER':
                    stk.append(ext.block_number)
                elif op == 'DIFFICULTY':
                    stk.append(ext.block_difficulty)
                elif op == 'GASLIMIT':
                    stk.append(ext.block_gas_limit)
            elif opcode < 0x60:
                if op == 'POP':
                    stk.pop()
                elif op == 'MLOAD':
                    s0 = stk.pop()
                    if not mem_extend(mem, compustate, op, s0, 32):
                        return vm_exception('OOG EXTENDING MEMORY')
                    stk.append(utils.bytes_to_int(mem[s0:s0 + 32]))
                elif op == 'MSTORE':
                    s0, s1 = stk.pop(), stk.pop()
                    if not mem_extend(mem, compustate, op, s0, 32):
                        return vm_exception('OOG EXTENDING MEMORY')
                    mem[s0:s0 + 32] = utils.encode_int32(s1)
                elif op == 'MSTORE8':
                    s0, s1 = stk.pop(), stk.pop()
                    if not mem_extend(mem, compustate, op, s0, 1):
                        return vm_exception('OOG EXTENDING MEMORY')
                    mem[s0] = s1 % 256
                elif op == 'SLOAD':
                    if ext.post_anti_dos_hardfork():
                        if not eat_gas(compustate,
                                       opcodes.SLOAD_SUPPLEMENTAL_GAS):
                            return vm_exception("OUT OF GAS")
                    stk.append(ext.get_storage_data(msg.to, stk.pop()))
                elif op == 'SSTORE':
                    s0, s1 = stk.pop(), stk.pop()
                    if msg.static:
                        return vm_exception(
                            'Cannot SSTORE inside a static context')
                    if ext.get_storage_data(msg.to, s0):
                        gascost = opcodes.GSTORAGEMOD if s1 else opcodes.GSTORAGEKILL
                        refund = 0 if s1 else opcodes.GSTORAGEREFUND
                    else:
                        gascost = opcodes.GSTORAGEADD if s1 else opcodes.GSTORAGEMOD
                        refund = 0
                    if compustate.gas < gascost:
                        return vm_exception('OUT OF GAS')
                    compustate.gas -= gascost
                    # adds neg gascost as a refund if below zero
                    ext.add_refund(refund)
                    ext.set_storage_data(msg.to, s0, s1)
                elif op == 'JUMP':
                    compustate.pc = stk.pop()
                    opnew = code[
                        compustate.pc] if compustate.pc < codelen else 0
                    jumped = True
                    if opnew != JUMPDEST:
                        return vm_exception('BAD JUMPDEST')
                elif op == 'JUMPI':
                    s0, s1 = stk.pop(), stk.pop()
                    if s1:
                        compustate.pc = s0
                        opnew = code[
                            compustate.pc] if compustate.pc < codelen else 0
                        jumped = True
                        if opnew != JUMPDEST:
                            return vm_exception('BAD JUMPDEST')
                elif op == 'PC':
                    stk.append(compustate.pc - 1)
                elif op == 'MSIZE':
                    stk.append(len(mem))
                elif op == 'GAS':
                    stk.append(compustate.gas)  # AFTER subtracting cost 1
            elif op[:3] == 'DUP':
                # 0x7f - opcode is a negative number, -1 for 0x80 ... -16 for
                # 0x8f
                stk.append(stk[0x7f - opcode])
            elif op[:4] == 'SWAP':
                # 0x8e - opcode is a negative number, -2 for 0x90 ... -17 for
                # 0x9f
                temp = stk[0x8e - opcode]
                stk[0x8e - opcode] = stk[-1]
                stk[-1] = temp

            elif op[:3] == 'LOG':
                """
                0xa0 ... 0xa4, 32/64/96/128/160 + len(data) gas
                a. Opcodes LOG0...LOG4 are added, takes 2-6 stack arguments
                        MEMSTART MEMSZ (TOPIC1) (TOPIC2) (TOPIC3) (TOPIC4)
                b. Logs are kept track of during tx execution exactly the same way as suicides
                   (except as an ordered list, not a set).
                   Each log is in the form [address, [topic1, ... ], data] where:
                   * address is what the ADDRESS opcode would output
                   * data is mem[MEMSTART: MEMSTART + MEMSZ]
                   * topics are as provided by the opcode
                c. The ordered list of logs in the transaction are expressed as [log0, log1, ..., logN].
                """
                depth = int(op[3:])
                mstart, msz = stk.pop(), stk.pop()
                topics = [stk.pop() for x in range(depth)]
                compustate.gas -= msz * opcodes.GLOGBYTE
                if msg.static:
                    return vm_exception('Cannot LOG inside a static context')
                if not mem_extend(mem, compustate, op, mstart, msz):
                    return vm_exception('OOG EXTENDING MEMORY')
                data = bytearray_to_bytestr(mem[mstart:mstart + msz])
                ext.log(msg.to, topics, data)
                log_log.trace('LOG',
                              to=msg.to,
                              topics=topics,
                              data=list(map(utils.safe_ord, data)))
                # print('LOG', msg.to, topics, list(map(ord, data)))

            elif op == 'CREATE':
                value, mstart, msz = stk.pop(), stk.pop(), stk.pop()
                if not mem_extend(mem, compustate, op, mstart, msz):
                    return vm_exception('OOG EXTENDING MEMORY')
                if msg.static:
                    return vm_exception(
                        'Cannot CREATE inside a static context')
                if ext.get_balance(msg.to) >= value and msg.depth < MAX_DEPTH:
                    cd = CallData(mem, mstart, msz)
                    ingas = compustate.gas
                    if ext.post_anti_dos_hardfork():
                        ingas = all_but_1n(ingas,
                                           opcodes.CALL_CHILD_LIMIT_DENOM)
                    create_msg = Message(msg.to, b'', value, ingas, cd,
                                         msg.depth + 1)
                    o, gas, addr = ext.create(create_msg)
                    if o:
                        stk.append(utils.coerce_to_int(addr))
                    else:
                        stk.append(0)
                    compustate.gas = compustate.gas - ingas + gas
                else:
                    stk.append(0)
            elif op in ('CALL', 'CALLCODE', 'DELEGATECALL', 'STATICCALL'):
                # Pull arguments from the stack
                if op in ('CALL', 'CALLCODE'):
                    gas, to, value, meminstart, meminsz, memoutstart, memoutsz = \
                        stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop()
                else:
                    gas, to, meminstart, meminsz, memoutstart, memoutsz = \
                        stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop()
                    value = 0
                # Static context prohibition
                if msg.static and value > 0:
                    return vm_exception(
                        'Cannot make a non-zero-value call inside a static context'
                    )
                # Expand memory
                if not mem_extend(mem, compustate, op, meminstart, meminsz) or \
                        not mem_extend(mem, compustate, op, memoutstart, memoutsz):
                    return vm_exception('OOG EXTENDING MEMORY')
                to = utils.int_to_addr(to)
                # Extra gas costs based on hard fork-dependent factors
                extra_gas = (not ext.account_exists(to)) * (op == 'CALL') * (value > 0 or not ext.post_clearing_hardfork()) * opcodes.GCALLNEWACCOUNT + \
                    (value > 0) * opcodes.GCALLVALUETRANSFER + \
                    ext.post_anti_dos_hardfork() * opcodes.CALL_SUPPLEMENTAL_GAS
                # Compute child gas limit
                if ext.post_anti_dos_hardfork():
                    if compustate.gas < extra_gas:
                        return vm_exception('OUT OF GAS', needed=extra_gas)
                    gas = min(
                        gas,
                        all_but_1n(compustate.gas - extra_gas,
                                   opcodes.CALL_CHILD_LIMIT_DENOM))
                else:
                    if compustate.gas < gas + extra_gas:
                        return vm_exception('OUT OF GAS',
                                            needed=gas + extra_gas)
                submsg_gas = gas + opcodes.GSTIPEND * (value > 0)
                # Verify that there is sufficient balance and depth
                if ext.get_balance(msg.to) < value or msg.depth >= MAX_DEPTH:
                    compustate.gas -= (gas + extra_gas - submsg_gas)
                    stk.append(0)
                else:
                    # Subtract gas from parent
                    compustate.gas -= (gas + extra_gas)
                    assert compustate.gas >= 0
                    cd = CallData(mem, meminstart, meminsz)
                    # Generate the message
                    if op == 'CALL':
                        call_msg = Message(msg.to,
                                           to,
                                           value,
                                           submsg_gas,
                                           cd,
                                           msg.depth + 1,
                                           code_address=to,
                                           static=msg.static)
                    elif ext.post_homestead_hardfork(
                    ) and op == 'DELEGATECALL':
                        call_msg = Message(msg.sender,
                                           msg.to,
                                           msg.value,
                                           submsg_gas,
                                           cd,
                                           msg.depth + 1,
                                           code_address=to,
                                           transfers_value=False,
                                           static=msg.static)
                    elif op == 'DELEGATECALL':
                        return vm_exception('OPCODE INACTIVE')
                    elif op == 'CALLCODE':
                        call_msg = Message(msg.to,
                                           msg.to,
                                           value,
                                           submsg_gas,
                                           cd,
                                           msg.depth + 1,
                                           code_address=to,
                                           static=msg.static)
                    elif op == 'STATICCALL':
                        call_msg = Message(msg.to,
                                           to,
                                           value,
                                           submsg_gas,
                                           cd,
                                           msg.depth + 1,
                                           code_address=to,
                                           static=True)
                    else:
                        raise Exception("Lolwut")
                    # Get result
                    result, gas, data = ext.msg(call_msg)
                    if result == 0:
                        stk.append(0)
                    else:
                        stk.append(1)
                    # Set output memory
                    for i in range(min(len(data), memoutsz)):
                        mem[memoutstart + i] = data[i]
                    compustate.gas += gas
                    compustate.last_returned = bytearray(data)
            elif op == 'RETURN':
                s0, s1 = stk.pop(), stk.pop()
                if not mem_extend(mem, compustate, op, s0, s1):
                    return vm_exception('OOG EXTENDING MEMORY')
                return peaceful_exit('RETURN', compustate.gas, mem[s0:s0 + s1])
            elif op == 'REVERT':
                if not ext.post_metropolis_hardfork():
                    return vm_exception('Opcode not yet enabled')
                s0, s1 = stk.pop(), stk.pop()
                if not mem_extend(mem, compustate, op, s0, s1):
                    return vm_exception('OOG EXTENDING MEMORY')
                return revert(compustate.gas, mem[s0:s0 + s1])
            elif op == 'SUICIDE':
                if msg.static:
                    return vm_exception(
                        'Cannot SUICIDE inside a static context')
                to = utils.encode_int(stk.pop())
                to = ((b'\x00' * (32 - len(to))) + to)[12:]
                xfer = ext.get_balance(msg.to)
                if ext.post_anti_dos_hardfork():
                    extra_gas = opcodes.SUICIDE_SUPPLEMENTAL_GAS + \
                        (not ext.account_exists(
                            to)) * (xfer > 0 or not ext.post_clearing_hardfork()) * opcodes.GCALLNEWACCOUNT
                    if not eat_gas(compustate, extra_gas):
                        return vm_exception("OUT OF GAS")
                ext.set_balance(to, ext.get_balance(to) + xfer)
                ext.set_balance(msg.to, 0)
                ext.add_suicide(msg.to)
                log_msg.debug('SUICIDING',
                              addr=utils.checksum_encode(msg.to),
                              to=utils.checksum_encode(to),
                              xferring=xfer)
                return 1, compustate.gas, []

            # assert utils.is_numeric(compustate.gas)
            # this is slow!
            # for a in stk:
            #     assert is_numeric(a), (op, stk)
            #     assert a >= 0 and a < 2**256, (a, op, stk)
        # if not jumped:
        #    assert compustate.pc == nextpos
        #    compustate.pc = nextpos
    if compustate.pc >= codelen:
        return peaceful_exit('CODE OUT OF RANGE', compustate.gas, [])
    return vm_exception('INVALID JUMP')
示例#54
0
def test_netting(deposit, settle_timeout, tester_channels, tester_state,
                 tester_events, tester_token):
    """
    This test ensures that Alice can send payments to Bob exceeding her initial deposit.
    A.sent > A.deposit
    the condition for this to work is that Bob has also sent payments to Alice in the meantime, so that
    B.sent >= (A.sent - A.deposit)
    A sample use case:
    A.deposit = 10
    B.deposit = 10
    A.send(10)  # at this point Alice's deposit is exhausted
    A.send(5) --> fail
    B.send(5)  # this replenishes the available tokens for Alice
    A.send(5)  # is now possible
    """
    privatekey0_raw, privatekey1_raw, nettingchannel, channel0, channel1 = tester_channels[
        0]
    privatekey0 = PrivateKey(privatekey0_raw, ctx=GLOBAL_CTX, raw=True)
    privatekey1 = PrivateKey(privatekey1_raw, ctx=GLOBAL_CTX, raw=True)
    address0 = privatekey_to_address(privatekey0_raw)
    address1 = privatekey_to_address(privatekey1_raw)
    unknown_key = tester.k3

    initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0_raw)
    initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1_raw)

    transfer_amount0 = deposit
    first_direct_transfer0 = channel0.create_directtransfer(
        transfer_amount0,
        1  # TODO: fill in identifier
    )  # at this point address0 deposit is exhausted
    first_direct_transfer0.sign(privatekey0, address0)
    first_direct_transfer0_data = str(first_direct_transfer0.packed().data)

    channel0.register_transfer(first_direct_transfer0)
    channel1.register_transfer(first_direct_transfer0)

    transfer_amount_failed = 5
    with pytest.raises(ValueError):
        second_direct_transfer0 = channel0.create_directtransfer(
            transfer_amount_failed,
            1  # TODO: fill in identifier
        )  # This will raise Insufficient funds Value error

    transfer_amount1 = 30
    direct_transfer1 = channel1.create_directtransfer(
        transfer_amount1,
        1  # TODO: fill in identifier
    )  # Replenishes tokens in the address0

    direct_transfer1.sign(privatekey1, address1)
    direct_transfer1_data = str(direct_transfer1.packed().data)

    channel0.register_transfer(direct_transfer1)
    channel1.register_transfer(direct_transfer1)

    second_transfer_amount0 = 5
    second_direct_transfer0 = channel0.create_directtransfer(
        second_transfer_amount0,
        1  # TODO: fill in identifier
    )
    second_direct_transfer0.sign(privatekey0, address0)
    second_direct_transfer0_data = str(second_direct_transfer0.packed().data)

    channel0.register_transfer(second_direct_transfer0)
    channel1.register_transfer(second_direct_transfer0)

    previous_events = list(tester_events)
    nettingchannel.close(
        second_direct_transfer0_data,
        sender=privatekey1_raw,
    )
    assert len(previous_events) + 1 == len(tester_events)

    block_number = tester_state.block.number

    close_event = tester_events[-1]
    assert close_event == {
        '_event_type': 'ChannelClosed',
        'closing_address': encode_hex(address1),
        'block_number': block_number,
    }

    nettingchannel.updateTransfer(
        direct_transfer1_data,
        sender=privatekey0_raw,
    )

    assert nettingchannel.closed(sender=privatekey0_raw) == block_number
    assert nettingchannel.closingAddress(
        sender=privatekey0_raw) == encode_hex(address1)

    tester_state.mine(number_of_blocks=settle_timeout + 1)

    previous_events = list(tester_events)
    nettingchannel.settle(sender=privatekey0_raw)
    assert len(previous_events) + 3 == len(tester_events)

    block_number = tester_state.block.number
    transfer0_event = tester_events[-3]
    assert transfer0_event == {
        '_event_type':
        'Transfer',
        '_from':
        nettingchannel.address,
        '_to':
        encode_hex(address0),
        '_value':
        deposit - transfer_amount0 - second_transfer_amount0 +
        transfer_amount1,
    }

    transfer1_event = tester_events[-2]
    assert transfer1_event == {
        '_event_type':
        'Transfer',
        '_from':
        nettingchannel.address,
        '_to':
        encode_hex(address1),
        '_value':
        deposit + transfer_amount0 + second_transfer_amount0 -
        transfer_amount1,
    }

    settle_event = tester_events[-1]
    assert settle_event == {
        '_event_type': 'ChannelSettled',
        'block_number': block_number,
    }

    assert tester_token.balanceOf(
        address0, sender=privatekey0_raw) == (initial_balance0 + deposit -
                                              transfer_amount0 -
                                              second_transfer_amount0 +
                                              +transfer_amount1)
    assert tester_token.balanceOf(
        address1,
        sender=privatekey1_raw) == (initial_balance1 + deposit +
                                    transfer_amount0 +
                                    second_transfer_amount0 - transfer_amount1)
    assert tester_token.balanceOf(nettingchannel.address,
                                  sender=privatekey1_raw) == 0
示例#55
0
 def encode_node(nd):
     if is_string(nd):
         return encode_hex(nd)
     else:
         return encode_hex(rlp_encode(nd))
示例#56
0
def test_two_messages_mediated_transfer(deposit, settle_timeout, tester_state,
                                        tester_channels, tester_token,
                                        tester_events):

    privatekey0_raw, privatekey1_raw, nettingchannel, channel0, channel1 = tester_channels[
        0]
    privatekey0 = PrivateKey(privatekey0_raw, ctx=GLOBAL_CTX, raw=True)
    privatekey1 = PrivateKey(privatekey1_raw, ctx=GLOBAL_CTX, raw=True)
    address0 = privatekey_to_address(privatekey0_raw)
    address1 = privatekey_to_address(privatekey1_raw)
    unknow_key = tester.k3

    initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0_raw)
    initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1_raw)

    lock_amount0 = 29
    lock_expiration0 = tester_state.block.number + DEFAULT_REVEAL_TIMEOUT + 3
    hashlock0 = sha3(tester.k0)

    mediated_transfer0 = channel0.create_mediatedtransfer(
        transfer_initiator=address0,
        transfer_target=address1,
        fee=0,
        amount=lock_amount0,
        identifier=1,  # TODO: fill in identifier
        expiration=lock_expiration0,
        hashlock=hashlock0,
    )
    mediated_transfer0.sign(privatekey0, address0)

    lock_amount1 = 29
    lock_expiration1 = tester_state.block.number + DEFAULT_REVEAL_TIMEOUT + 5
    hashlock1 = sha3(tester.k1)

    mediated_transfer1 = channel1.create_mediatedtransfer(
        transfer_initiator=address1,
        transfer_target=address0,
        fee=0,
        amount=lock_amount1,
        identifier=1,  # TODO: fill in identifier
        expiration=lock_expiration1,
        hashlock=hashlock1,
    )
    mediated_transfer1.sign(privatekey1, address1)

    with pytest.raises(TransactionFailed):
        nettingchannel.close(
            str(mediated_transfer0.packed().data),
            str(mediated_transfer1.packed().data),
            sender=unknow_key,
        )

    previous_events = list(tester_events)
    nettingchannel.close(
        str(mediated_transfer0.packed().data),
        str(mediated_transfer1.packed().data),
        sender=privatekey0_raw,
    )
    assert len(previous_events) + 1 == len(tester_events)

    block_number = tester_state.block.number

    close_event = tester_events[-1]
    assert close_event == {
        '_event_type': 'ChannelClosed',
        'closingAddress': encode_hex(address0),
        'blockNumber': block_number,
    }
    assert nettingchannel.closed(sender=privatekey0_raw) == block_number
    assert nettingchannel.closingAddress(
        sender=privatekey0_raw) == encode_hex(address0)

    tester_state.mine(number_of_blocks=settle_timeout + 1)

    previous_events = list(tester_events)
    nettingchannel.settle(sender=privatekey0_raw)
    block_number = tester_state.block.number

    assert len(previous_events) + 3 == len(tester_events)

    transfer0_event = tester_events[-3]
    assert transfer0_event == {
        '_event_type': 'Transfer',
        '_from': nettingchannel.address,
        '_to': encode_hex(address0),
        '_value': deposit,
    }

    transfer1_event = tester_events[-2]
    assert transfer1_event == {
        '_event_type': 'Transfer',
        '_from': nettingchannel.address,
        '_to': encode_hex(address1),
        '_value': deposit,
    }

    settle_event = tester_events[-1]
    assert settle_event == {
        '_event_type': 'ChannelSettled',
        'blockNumber': block_number,
    }

    assert tester_token.balanceOf(
        address0, sender=privatekey0_raw) == initial_balance0 + deposit  # noqa
    assert tester_token.balanceOf(
        address1, sender=privatekey1_raw) == initial_balance1 + deposit  # noqa
    assert tester_token.balanceOf(nettingchannel.address,
                                  sender=privatekey1_raw) == 0
示例#57
0
def test_channeldeposit(private_keys, settle_timeout, tester_state,
                        tester_token, tester_events, tester_registry):
    """ Guarantee the correct tracking of each participant deposits, checks the
    initial state (pre-deposit) and state changes for each deposits.
    """

    # not using the tester_nettingcontracts fixture to control the
    # transfer/deposits

    privatekey0 = private_keys[0]
    privatekey1 = private_keys[1]
    address0 = privatekey_to_address(privatekey0)
    address1 = privatekey_to_address(privatekey1)
    unknow_key = tester.k3

    channel_manager = new_channelmanager(
        privatekey0,
        tester_state,
        tester_events.append,
        tester_registry,
        tester_token,
    )

    channel = new_nettingcontract(
        privatekey0,
        privatekey1,
        tester_state,
        tester_events.append,
        channel_manager,
        settle_timeout,
    )

    # check initial state, needs to be zeroed out
    assert channel.settleTimeout(sender=privatekey0) == settle_timeout
    assert channel.tokenAddress(sender=privatekey0) == encode_hex(
        tester_token.address)
    assert channel.opened(sender=privatekey0) == 0
    assert channel.closed(sender=privatekey0) == 0
    assert channel.settled(sender=privatekey0) == 0

    assert channel.addressAndBalance(
        sender=privatekey0)[0] == encode_hex(address0)
    assert channel.addressAndBalance(sender=privatekey0)[1] == 0
    assert channel.addressAndBalance(
        sender=privatekey0)[2] == encode_hex(address1)
    assert channel.addressAndBalance(sender=privatekey0)[3] == 0

    initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0)
    deposit_amount = initial_balance0 // 10

    # try to make invalid deposits
    with pytest.raises(TransactionFailed):
        channel.deposit(1, sender=unknow_key)  # not participant

    assert tester_token.approve(
        channel.address, deposit_amount * 2, sender=privatekey0) is True

    assert channel.deposit(deposit_amount * 2 + 1, sender=privatekey0) is False

    with pytest.raises(abi.ValueOutOfBounds):
        channel.deposit(-1, sender=privatekey0)

    # create a first deposit with half of the allowance
    assert channel.deposit(deposit_amount, sender=privatekey0) is True

    assert tester_token.balanceOf(channel.address,
                                  sender=privatekey0) == deposit_amount
    assert tester_token.balanceOf(
        address0,
        sender=privatekey0) == initial_balance0 - deposit_amount  # noqa
    assert channel.opened(sender=privatekey0) == tester_state.block.number

    assert channel.addressAndBalance(
        sender=privatekey0)[0] == encode_hex(address0)
    assert channel.addressAndBalance(sender=privatekey0)[1] == deposit_amount
    assert channel.addressAndBalance(
        sender=privatekey0)[2] == encode_hex(address1)
    assert channel.addressAndBalance(sender=privatekey0)[3] == 0

    # check a second depoist with the rest of the allowance
    assert channel.deposit(deposit_amount, sender=privatekey0) is True

    assert tester_token.balanceOf(channel.address,
                                  sender=privatekey0) == deposit_amount * 2
    assert tester_token.balanceOf(
        address0,
        sender=privatekey0) == initial_balance0 - deposit_amount * 2  # noqa
    assert channel.opened(sender=privatekey0) == tester_state.block.number

    assert channel.addressAndBalance(
        sender=privatekey0)[0] == encode_hex(address0)
    assert channel.addressAndBalance(
        sender=privatekey0)[1] == deposit_amount * 2
    assert channel.addressAndBalance(
        sender=privatekey0)[2] == encode_hex(address1)
    assert channel.addressAndBalance(sender=privatekey0)[3] == 0

    # allowance zeroed, we cant make a new deposit
    assert channel.deposit(deposit_amount, sender=privatekey0) is False

    # needs to be able to add aditional token
    assert tester_token.approve(
        channel.address, deposit_amount, sender=privatekey0) is True
    assert channel.deposit(deposit_amount, sender=privatekey0) is True

    assert tester_token.balanceOf(channel.address,
                                  sender=privatekey0) == deposit_amount * 3
    assert tester_token.balanceOf(
        address0,
        sender=privatekey0) == initial_balance0 - deposit_amount * 3  # noqa
    assert channel.opened(sender=privatekey0) == tester_state.block.number

    assert channel.addressAndBalance(
        sender=privatekey0)[0] == encode_hex(address0)
    assert channel.addressAndBalance(
        sender=privatekey0)[1] == deposit_amount * 3
    assert channel.addressAndBalance(
        sender=privatekey0)[2] == encode_hex(address1)
    assert channel.addressAndBalance(sender=privatekey0)[3] == 0
示例#58
0
 def print_address(name, address):
     print('Deployed {:25}: 0x{}'.format(name,
                                         utils.encode_hex(address)))
示例#59
0
def test_closewithouttransfer_settle(deposit, settle_timeout, tester_state,
                                     tester_events, tester_nettingcontracts,
                                     tester_token):

    privatekey0, privatekey1, nettingchannel = tester_nettingcontracts[0]
    address0 = privatekey_to_address(privatekey0)
    address1 = privatekey_to_address(privatekey1)
    unknown_key = tester.k3

    initial_balance0 = tester_token.balanceOf(address0, sender=privatekey0)
    initial_balance1 = tester_token.balanceOf(address1, sender=privatekey1)

    with pytest.raises(TransactionFailed):
        nettingchannel.close(sender=unknown_key)

    previous_events = list(tester_events)
    nettingchannel.close('', sender=privatekey0)
    assert len(previous_events) + 1 == len(tester_events)

    block_number = tester_state.block.number

    close_event = tester_events[-1]
    assert close_event == {
        '_event_type': 'ChannelClosed',
        'closing_address': encode_hex(address0),
        'block_number': block_number,
    }

    assert nettingchannel.closed(sender=privatekey0) == block_number
    assert nettingchannel.closingAddress(
        sender=privatekey0) == encode_hex(address0)

    tester_state.mine(number_of_blocks=settle_timeout + 1)

    previous_events = list(tester_events)
    # Anyone can call settle(), not just channel participants
    nettingchannel.settle(sender=unknown_key)
    block_number = tester_state.block.number

    assert len(previous_events) + 3 == len(tester_events)

    transfer0_event = tester_events[-3]
    assert transfer0_event == {
        '_event_type': 'Transfer',
        '_from': nettingchannel.address,
        '_to': encode_hex(address1),
        '_value': deposit,
    }

    transfer1_event = tester_events[-2]
    assert transfer1_event == {
        '_event_type': 'Transfer',
        '_from': nettingchannel.address,
        '_to': encode_hex(address0),
        '_value': deposit,
    }

    settle_event = tester_events[-1]
    assert settle_event == {
        '_event_type': 'ChannelSettled',
        'block_number': block_number,
    }

    assert tester_token.balanceOf(
        address0, sender=privatekey0) == initial_balance0 + deposit
    assert tester_token.balanceOf(
        address1, sender=privatekey1) == initial_balance1 + deposit
    assert tester_token.balanceOf(nettingchannel.address,
                                  sender=privatekey1) == 0
示例#60
0
def patch_send_transaction(client, nonce_offset=0):
    """Check if the remote supports pyethapp's extended jsonrpc spec for local tx signing.
    If not, replace the `send_transaction` method with a more generic one.
    """
    patch_necessary = False

    try:
        client.call('eth_nonce', encode_hex(client.sender), 'pending')
    except:
        patch_necessary = True
        client.last_nonce_update = 0
        client.current_nonce = None
        client.nonce_lock = Semaphore()

    def send_transaction(sender, to, value=0, data='', startgas=GAS_LIMIT,
                         gasprice=GAS_PRICE, nonce=None):
        """Custom implementation for `pyethapp.rpc_client.JSONRPCClient.send_transaction`.
        This is necessary to support other remotes that don't support pyethapp's extended specs.
        @see https://github.com/ethereum/pyethapp/blob/develop/pyethapp/rpc_client.py#L359
        """
        def get_nonce():
            """Eventually syncing nonce counter.
            This will keep a local nonce counter that is only syncing against
            the remote every `UPDATE_INTERVAL`.

            If the remote counter is lower than the current local counter,
            it will wait for the remote to catch up.
            """
            with client.nonce_lock:
                UPDATE_INTERVAL = 5.
                query_time = now()
                needs_update = abs(query_time - client.last_nonce_update) > UPDATE_INTERVAL
                not_initialized = client.current_nonce is None
                if needs_update or not_initialized:
                    nonce = _query_nonce()
                    # we may have hammered the server and not all tx are
                    # registered as `pending` yet
                    while nonce < client.current_nonce:
                        log.debug(
                            "nonce on server too low; retrying",
                            server=nonce,
                            local=client.current_nonce
                        )
                        nonce = _query_nonce()
                        query_time = now()
                    client.current_nonce = nonce
                    client.last_nonce_update = query_time
                else:
                    client.current_nonce += 1
                return client.current_nonce

        def _query_nonce():
            pending_transactions_hex = client.call(
                'eth_getTransactionCount',
                address_encoder(sender),
                'pending',
            )
            pending_transactions = int(pending_transactions_hex, 16)
            nonce = pending_transactions + nonce_offset
            return nonce

        nonce = get_nonce()

        tx = Transaction(nonce, gasprice, startgas, to, value, data)
        assert hasattr(client, 'privkey') and client.privkey
        tx.sign(client.privkey)
        result = client.call(
            'eth_sendRawTransaction',
            data_encoder(rlp.encode(tx)),
        )
        return result[2 if result.startswith('0x') else 0:]

    if patch_necessary:
        client.send_transaction = send_transaction