Beispiel #1
0
    def test_if_enough_time_passed_since_last_play_then_grant_earnings_to_last_player(
            self):

        # Player 1 presses the button
        result = self.contract.process(MIN_AMOUNT_REQUIRED,
                                       value=140,
                                       sender=t.k0)
        self.assertEquals(result, 1)

        self.state.mine(1)

        winningBalanceBefore = State().get_balance(u.int_to_addr(t.k1))
        losingBalanceBefore = State().get_balance(u.int_to_addr(t.k0))

        # Player 2 presses the button
        result = self.contract.process(MIN_AMOUNT_REQUIRED,
                                       value=140,
                                       sender=t.k1)
        self.assertEquals(result, 1)

        self.state.mine(3)

        # Player 2 presses the button again
        result = self.contract.process(MIN_AMOUNT_REQUIRED,
                                       value=140,
                                       sender=t.k1)
        self.assertEquals(result, 2)

        winningBalanceAfter = State().get_balance(u.int_to_addr(t.k1))
        losingBalanceAfter = State().get_balance(u.int_to_addr(t.k0))

        self.assertEquals(losingBalanceAfter, losingBalanceBefore)
        self.assertTrue(winningBalanceAfter > losingBalanceBefore)
Beispiel #2
0
def test_reverter():
    c = tester.Chain()
    x = c.contract(reverter_code, value=10**15, language='serpent')
    x.entry()
    assert c.head_state.get_storage_data(x.address, 8080) == 4040
    assert c.head_state.get_balance(utils.int_to_addr(5050)) == 9
    assert c.head_state.get_storage_data(x.address, 8081) == 0
    assert c.head_state.get_balance(utils.int_to_addr(5051)) == 0
Beispiel #3
0
def validator_inject(state, vcode, deposit_size,
                     randao_commitment, address, nonce=0, ct=None):
    if not ct:
        ct = get_casper_ct()
    state.set_balance(utils.int_to_addr(1), deposit_size)
    t = Transaction(nonce, 0, 10**8, casper_config['CASPER_ADDR'], deposit_size,
                    ct.encode('deposit', [vcode, randao_commitment, address]))
    t._sender = utils.int_to_addr(1)
    success, output = apply_transaction(state, t)
    assert success
Beispiel #4
0
    def test_simple_send(self):
        self.c.issue(tester.a0, 100000000000)
        assert self.c.balance(tester.a0) == 100000000000

        assert self.c.send(tester.a1, 1000) == 1
        assert self.c.balance(tester.a0) == 100000000000 - 1000
        assert self.c.balance(tester.a1) == 1000
        last_tx = self.c.last_tx()
        assert utils.int_to_addr(last_tx[0]) == tester.a0
        assert utils.int_to_addr(last_tx[1]) == tester.a1
        assert last_tx[2:] == [1000, 1]
Beispiel #5
0
def test_chain(alloc={},
               genesis_gas_limit=9999999,
               min_gas_limit=5000,
               startgas=3141592):
    # alloc
    alloc[tester.a0] = {'balance': 100000 * utils.denoms.ether}

    for i in range(9):
        alloc[utils.int_to_addr(i)] = {'balance': 1}
    # genesis
    header = {
        "number": 0,
        "gas_limit": genesis_gas_limit,
        "gas_used": 0,
        "timestamp": 1467446877,
        "difficulty": 1,
        "uncles_hash": '0x' + utils.encode_hex(utils.sha3(rlp.encode([])))
    }
    genesis = mk_basic_state(alloc, header, tester.get_env(None))
    # tester
    tester.languages['viper'] = compiler.Compiler()
    tester.STARTGAS = startgas
    chain = tester.Chain(alloc=alloc, genesis=genesis)
    chain.chain.env.config['MIN_GAS_LIMIT'] = min_gas_limit
    chain.mine(1)
    return chain
Beispiel #6
0
def test_crowdfund():
    c = tester.Chain()
    x = c.contract(crowdfund_code, language='serpent')
    # Create a campaign with id 100
    x.create_campaign(100, 45, 100000, 2)
    # Create a campaign with id 200
    x.create_campaign(200, 48, 100000, 2)
    # Make some contributions
    x.contribute(100, value=1, sender=tester.k1)
    assert 1 == x.progress_report(100)
    x.contribute(200, value=30000, sender=tester.k2)
    x.contribute(100, value=59049, sender=tester.k3)
    assert 59050 == x.progress_report(100)
    x.contribute(200, value=70001, sender=tester.k4)
    # Expect the 100001 units to be delivered to the destination
    # account for campaign 2
    assert 100001 == c.head_state.get_balance(utils.int_to_addr(48))
    mida1 = c.head_state.get_balance(tester.a1)
    mida3 = c.head_state.get_balance(tester.a3)
    # Mine 5 blocks to expire the campaign
    c.mine(5)
    # Ping the campaign after expiry
    x.contribute(100, value=1)
    # Expect refunds
    assert mida1 + 1 == c.head_state.get_balance(tester.a1)
    assert mida3 + 59049 == c.head_state.get_balance(tester.a3)
def test_typed_storage():
    def randomword(length):
        return ''.join(random.choice(string.lowercase) for i in range(length))

    types = nc.TypedStorage._valid_types
    random.seed(1)  # a hardcoded seed to make the test deterministic

    for t in types:
        ts = nc.TypedStorage(t)
        td = dict()
        randomprefix = randomword(random.randint(1, 10))
        randomkey = randomword(random.randint(1, 50))
        ts.setup(randomprefix, td.get, td.__setitem__)
        if t == 'address':
            address = utils.int_to_addr(random.randint(0, 0xFFFFFFFF))
            ts.set(randomkey, address, t)
            assert ts.get(randomkey, t) == address
        elif t == 'string' or t == 'bytes' or t == 'binary':
            word = randomword(10)
            ts.set(randomkey, word, t)
            assert ts.get(randomkey, t) == word
        elif 'uint' in t:
            size = int(t[4:])
            v = random.randint(0, 2**size - 1)
            ts.set(randomkey, v, t)
            assert ts.get(randomkey, t) == v
        elif 'int' in t:
            size = int(t[3:])
            v = random.randint(0, 2**(size - 2) - 1)
            ts.set(randomkey, v, t)
            assert ts.get(randomkey, t) == v
        else:
            pass
Beispiel #8
0
def test_crowdfund():
    s = tester.state()
    c = s.abi_contract(crowdfund_code)
    # Create a campaign with id 100
    c.create_campaign(100, 45, 100000, 2)
    # Create a campaign with id 200
    c.create_campaign(200, 48, 100000, 2)
    # Make some contributions
    c.contribute(100, value=1, sender=tester.k1)
    assert 1 == c.progress_report(100)
    c.contribute(200, value=30000, sender=tester.k2)
    c.contribute(100, value=59049, sender=tester.k3)
    assert 59050 == c.progress_report(100)
    c.contribute(200, value=70001, sender=tester.k4)
    # Expect the 100001 units to be delivered to the destination
    # account for campaign 2
    assert 100001 == s.block.get_balance(utils.int_to_addr(48))
    mida1 = s.block.get_balance(tester.a1)
    mida3 = s.block.get_balance(tester.a3)
    # Mine 5 blocks to expire the campaign
    s.mine(5)
    # Ping the campaign after expiry
    c.contribute(100, value=1)
    # Expect refunds
    assert mida1 + 1 == s.block.get_balance(tester.a1)
    assert mida3 + 59049 == s.block.get_balance(tester.a3)
Beispiel #9
0
def listener(log):
    print "LISTENER", log
    if log['_event_type'] == 'Created':
        addr = utils.int_to_addr(log['addr'])
        spread_contracts.append(addr.encode('hex'))
    if log['_event_type'] == 'NextCalled':
        depths.append(log['depth'])
Beispiel #10
0
class NativeContractBase(object):

    address = utils.int_to_addr(1024)

    def __init__(self, ext, msg):
        self._ext = ext
        self._msg = msg
        self.gas = msg.gas

    @classmethod
    def _on_msg(cls, ext, msg):
        nac = cls(ext, msg)
        try:
            return nac._safe_call()
        except Exception:
            log.error('contract errored', contract=cls.__name__)
            print(traceback.format_exc())
            return 0, msg.gas, []

    def _get_storage_data(self, key):
        return self._ext.get_storage_data(self._msg.to, key)

    def _set_storage_data(self, key, value):
        return self._ext.set_storage_data(self._msg.to, key, value)

    def _safe_call(self):
        return 1, self.gas, []
def custom_chain(tester,
                 alloc={},
                 genesis_gas_limit=4712388,
                 min_gas_limit=5000,
                 startgas=3141592):
    # alloc
    for i in range(9):
        alloc[utils.int_to_addr(i)] = {'balance': 1}
    # genesis
    from ethereum.genesis_helpers import mk_basic_state
    header = {
        "number": 0,
        "gas_limit": genesis_gas_limit,
        "gas_used": 0,
        "timestamp": 1467446877,
        "difficulty": 1,
        "uncles_hash": '0x' + utils.encode_hex(utils.sha3(rlp.encode([])))
    }
    genesis = mk_basic_state(alloc, header, tester.get_env(None))
    # tester
    tester.languages['viper'] = compiler.Compiler()
    tester.STARTGAS = startgas
    c = tester.Chain(alloc=alloc, genesis=genesis)
    c.chain.env.config['MIN_GAS_LIMIT'] = min_gas_limit
    c.mine(1)
    return c
def test_crowdfund():
    s = tester.state()
    c = s.abi_contract(crowdfund_code)
    # Create a campaign with id 100
    c.create_campaign(100, 45, 100000, 2)
    # Create a campaign with id 200
    c.create_campaign(200, 48, 100000, 2)
    # Make some contributions
    c.contribute(100, value=1, sender=tester.k1)
    assert 1 == c.progress_report(100)
    c.contribute(200, value=30000, sender=tester.k2)
    c.contribute(100, value=59049, sender=tester.k3)
    assert 59050 == c.progress_report(100)
    c.contribute(200, value=70001, sender=tester.k4)
    # Expect the 100001 units to be delivered to the destination
    # account for campaign 2
    assert 100001 == s.block.get_balance(utils.int_to_addr(48))
    mida1 = s.block.get_balance(tester.a1)
    mida3 = s.block.get_balance(tester.a3)
    # Mine 5 blocks to expire the campaign
    s.mine(5)
    # Ping the campaign after expiry
    c.contribute(100, value=1)
    # Expect refunds
    assert mida1 + 1 == s.block.get_balance(tester.a1)
    assert mida3 + 59049 == s.block.get_balance(tester.a3)
Beispiel #13
0
def listener(log):
    print "LISTENER", log
    if log['_event_type'] == 'Created':
        addr = utils.int_to_addr(log['addr'])
        spread_contracts.append(addr.encode('hex'))
    if log['_event_type'] == 'NextCalled':
        depths.append(log['depth'])
    class TestTSC(nc.NativeContract):

        address = utils.int_to_addr(2051)
        size = nc.Scalar('uint32')
        numbers = nc.List('uint32')
        words = nc.Dict('bytes')

        def setup_numbers(ctx, size='uint32', returns=None):
            ctx.size = size
            assert isinstance(ctx.numbers, nc.List)
            for i in range(size):
                ctx.numbers.append(i)

        def sum_numbers(ctx, returns='uint32'):
            assert ctx.size == len(ctx.numbers)
            return sum(ctx.numbers[i] for i in range(len(ctx.numbers)))

        def setup_words(ctx, num='uint32', returns=None):
            for i in range(num):
                key = 'key%d' % i
                word = 'word%d' % i
                ctx.words[key] = word
                assert ctx.words[key] == word

        def get_word(ctx, key='bytes', returns='bytes'):
            r = ctx.words[key]
            return r

        def muladdsize(ctx, val='uint32', returns='uint32'):
            ctx.size += val
            ctx.size *= val
            return ctx.size
Beispiel #15
0
class CreateNativeContractInstance(NativeContractBase):
    """
    special contract to create an instance of native contract
    instance refers to instance in the BC.

    msg.data[:4] defines the native contract
    msg.data[4:] is sent as data to the new contract

    call with last 4 bytes of the address of the contract for which an instance should be created.
    i.e.  msg.data = ContractClass.address[-4:]

    called by _apply_message
        value was added to this contract (needs to be moved)
    """

    address = utils.int_to_addr(1024)

    def _safe_call(self):
        log.debug('create native contract instance called')
        assert len(self._msg.sender) == 20
        assert len(self._msg.data.extract_all()) >= 4

        # get native contract
        nc_address = registry.native_contract_address_prefix + self._msg.data.extract_all(
        )[:4]
        if nc_address not in registry:
            return 0, self._msg.gas, b''
        native_contract = registry[nc_address].im_self

        # get new contract address
        if self._ext.tx_origin != self._msg.sender:
            self._ext._block.increment_nonce(self._msg.sender)
        nonce = utils.encode_int(
            self._ext._block.get_nonce(self._msg.sender) - 1)
        self._msg.to = registry.mk_instance_address(native_contract,
                                                    self._msg.sender, nonce)
        assert not self._ext.get_balance(self._msg.to)  # must be none existant

        # value was initially added to this contract's address, we need to transfer
        success = self._ext._block.transfer_value(self.address, self._msg.to,
                                                  self._msg.value)
        assert success
        assert not self._ext.get_balance(self.address)

        # call new instance with additional data
        self._msg.is_create = True
        self._msg.data = vm.CallData(self._msg.data.data[4:], 0, 0)
        res, gas, dat = registry[self._msg.to](self._ext, self._msg)
        assert gas >= 0
        log.debug('created native contract instance',
                  template=nc_address.encode('hex'),
                  instance=self._msg.to.encode('hex'))
        return res, gas, memoryview(self._msg.to).tolist()
Beispiel #16
0
def tester_state(deploy_key, private_keys, tester_blockgas_limit):
    tester_state = tester.state()

    # special addresses 1 to 5
    alloc = {
        int_to_addr(i): {'wei': 1}
        for i in range(1, 5)
    }

    for privkey in [deploy_key] + private_keys:
        address = privatekey_to_address(privkey)
        alloc[address] = {
            'balance': DEFAULT_BALANCE,
        }

    for account in tester.accounts:
        alloc[account] = {
            'balance': DEFAULT_BALANCE,
        }

    db = ethereum.db.EphemDB()
    env = ethereum.config.Env(
        db,
        ethereum.config.default_config,
    )
    genesis_overwrite = {
        'nonce': zpad(data_decoder('0x00006d6f7264656e'), 8),
        'difficulty': quantity_decoder('0x20000'),
        'mixhash': zpad(b'\x00', 32),
        'coinbase': address_decoder('0x0000000000000000000000000000000000000000'),
        'timestamp': 0,
        'extra_data': b'',
        'gas_limit': tester_blockgas_limit,
        'start_alloc': alloc,
    }
    genesis_block = ethereum.blocks.genesis(
        env,
        **genesis_overwrite
    )

    # enable DELEGATECALL opcode
    genesis_block.number = genesis_block.config['HOMESTEAD_FORK_BLKNUM'] + 1

    tester_state.db = db
    tester_state.env = env
    tester_state.block = genesis_block
    tester_state.blocks = [genesis_block]

    return tester_state
Beispiel #17
0
def tester_state(deploy_key, private_keys, tester_blockgas_limit):
    tester_state = tester.state()

    # special addresses 1 to 5
    alloc = {
        int_to_addr(i): {'wei': 1}
        for i in range(1, 5)
    }

    for privkey in [deploy_key] + private_keys:
        address = privatekey_to_address(privkey)
        alloc[address] = {
            'balance': DEFAULT_BALANCE,
        }

    for account in tester.accounts:
        alloc[account] = {
            'balance': DEFAULT_BALANCE,
        }

    db = ethereum.db.EphemDB()
    env = ethereum.config.Env(
        db,
        ethereum.config.default_config,
    )
    genesis_overwrite = {
        'nonce': zpad(data_decoder('0x00006d6f7264656e'), 8),
        'difficulty': quantity_decoder('0x20000'),
        'mixhash': zpad(b'\x00', 32),
        'coinbase': address_decoder('0x0000000000000000000000000000000000000000'),
        'timestamp': 0,
        'extra_data': b'',
        'gas_limit': tester_blockgas_limit,
        'start_alloc': alloc,
    }
    genesis_block = ethereum.blocks.genesis(
        env,
        **genesis_overwrite
    )

    # enable DELEGATECALL opcode
    genesis_block.number = genesis_block.config['HOMESTEAD_FORK_BLKNUM'] + 1

    tester_state.db = db
    tester_state.env = env
    tester_state.block = genesis_block
    tester_state.blocks = [genesis_block]

    return tester_state
Beispiel #18
0
 def OP_CALLCODE():
     subgas, 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, msgtop.compustate, '', meminstart, meminsz) or \
             not mem_extend(mem, msgtop.compustate, '', memoutstart, memoutsz):
         return drop(OUT_OF_GAS)
     if msgtop.compustate.gas < subgas:
         return drop(out_of_gas_exception('subcall gas', gas, msgtop.compustate, ''))
     msgtop.compustate.gas -= subgas
     data = [0] * ((meminsz >> 5) + 1)
     copy32(mem, data, meminstart, 0, meminsz)
     call_msg = Message(msgtop.to, msgtop.to, value, subgas, data, meminsz)
     special[0] = 'call'
     special[1] = call_msg
     special[2] = block.get_code(utils.int_to_addr(to))
     special[3] = memoutstart
     special[4] = memoutsz
    class TestTSC(nc.NativeContract):

        address = utils.int_to_addr(2051)
        owner = nc.Scalar('address')

        def own(ctx, returns=None):
            if ctx.owner == '\0' * 20:
                ctx.owner = ctx.tx_origin
                assert ctx.owner == ctx.tx_origin

        def assert_owner(ctx):
            if ctx.tx_origin != ctx.owner:
                raise RuntimeError('not owner')

        @nc.constant
        def protected(ctx, returns='uint32'):
            ctx.assert_owner()
            return 1
Beispiel #20
0
    class TestTSC(nc.TypedStorageContract):

        address = utils.int_to_addr(2050)
        a = nc.Scalar('uint32')
        b = nc.List('uint16')
        c = nc.Dict('uint32')

        def _safe_call(ctx):
            # skalar
            assert ctx.a == 0
            ctx.a = 1
            assert ctx.a == 1

            ctx.a = 2
            assert ctx.a == 2

            # list
            assert isinstance(ctx.b, nc.List)
            ctx.b[0] = 10
            assert ctx.b[0] == 10

            ctx.b[1000] = 12
            assert ctx.b[1000] == 12

            assert len(ctx.b) == 1001
            ctx.b[1000] = 66
            assert ctx.b[1000] == 66
            assert len(ctx.b) == 1001

            ctx.b.append(99)
            assert len(ctx.b) == 1002
            ctx.b.append(99)
            assert len(ctx.b) == 1003

            # mapping
            assert isinstance(ctx.c, nc.Dict)
            key = b'test'
            assert ctx.c[key] == 0
            ctx.c[key] = 33
            assert ctx.c[key] == 33
            ctx.c[key] = 66
            assert ctx.c[key] == 66

            return 1, 1, []
def custom_chain(tester, alloc={}, genesis_gas_limit=4712388, min_gas_limit=5000, startgas=3141592):
    # alloc
    for i in range(9):
        alloc[utils.int_to_addr(i)] = {'balance': 1}
    # genesis
    from ethereum.genesis_helpers import mk_basic_state
    header = {
        "number": 0, "gas_limit": genesis_gas_limit,
        "gas_used": 0, "timestamp": 1467446877, "difficulty": 1,
        "uncles_hash": '0x'+utils.encode_hex(utils.sha3(rlp.encode([])))
    }
    genesis = mk_basic_state(alloc, header, tester.get_env(None))
    # tester
    tester.languages['viper'] = compiler.Compiler()
    tester.STARTGAS = startgas
    c = tester.Chain(alloc=alloc, genesis=genesis)
    c.chain.env.config['MIN_GAS_LIMIT'] = min_gas_limit
    c.mine(1)
    return c
Beispiel #22
0
 def OP_CALL():
     subgas, to, value, meminstart, meminsz, memoutstart, memoutsz = \
         stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop()
     if max(meminstart + meminsz, memoutstart + memoutsz) > len(mem) << 5:
         if not mem_extend(mem, msgtop.compustate, '', meminstart, meminsz) or \
                 not mem_extend(mem, msgtop.compustate, '', memoutstart, memoutsz) or \
                 msgtop.compustate.gas < subgas:
             return drop(OUT_OF_GAS)
     msgtop.compustate.gas -= subgas
     if block.get_balance(msgtop.to) >= value:
         data = [0] * ((meminsz >> 5) + 1)
         copy32(mem, data, meminstart, 0, meminsz)
         to = utils.int_to_addr(to)
         call_msg = Message(msgtop.to, to, value, subgas, data, meminsz)
         special[0] = 'call'
         special[1] = call_msg
         special[2] = block.get_code(to)
         special[3] = memoutstart
         special[4] = memoutsz
     else:
         stk.append(0)
Beispiel #23
0
    def __init__(self, num_accounts=len(keys)):
        self.temp_data_dir = tempfile.mkdtemp()
        self.db = db.EphemDB()
        self.env = Env(self.db)
        self.last_tx = None

        initial_balances = {}

        for i in range(num_accounts):
            account = accounts[i]
            initial_balances[account] = {'wei': 10 ** 24}

        for i in range(1, 5):
            address = int_to_addr(i)
            initial_balances[address] = {'wei': 1}

        self.block = blocks.genesis(
            self.env,
            start_alloc=initial_balances,
        )
        self.blocks = [self.block]
        self.block.timestamp = 1410973349
        self.block.coinbase = DEFAULT_ACCOUNT
        self.block.gas_limit = 10 ** 9
Beispiel #24
0
    def __init__(self, num_accounts=len(keys)):
        self.temp_data_dir = tempfile.mkdtemp()
        self.db = db.EphemDB()
        self.env = Env(self.db)
        self.last_tx = None

        initial_balances = {}

        for i in range(num_accounts):
            account = accounts[i]
            initial_balances[account] = {'wei': 10**24}

        for i in range(1, 5):
            address = int_to_addr(i)
            initial_balances[address] = {'wei': 1}

        self.block = blocks.genesis(
            self.env,
            start_alloc=initial_balances,
        )
        self.blocks = [self.block]
        self.block.timestamp = 1410973349
        self.block.coinbase = DEFAULT_ACCOUNT
        self.block.gas_limit = 10**9
Beispiel #25
0
accounts = []
keys = []

for account_number in range(10):
    keys.append(sha3(to_string(account_number)))
    accounts.append(privtoaddr(keys[-1]))

k0, k1, k2, k3, k4, k5, k6, k7, k8, k9 = keys[:10]
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = accounts[:10]

base_alloc = {}
minimal_alloc = {}
for a in accounts:
    base_alloc[a] = {'balance': 10**24}
for i in range(1, 9):
    base_alloc[int_to_addr(i)] = {'balance': 1}
    minimal_alloc[int_to_addr(i)] = {'balance': 1}
minimal_alloc[accounts[0]] = {'balance': 10**18}

# Initialize languages
languages = {}

try:
    import serpent
    languages['serpent'] = serpent
except ImportError:
    pass

from ethereum.tools._solidity import get_solidity
_solidity = get_solidity()
if _solidity:
Beispiel #26
0
from mk_sendmany import mk_multisend_code, get_multisend_gas
from ethereum.tools import tester2
from ethereum import utils

# from ethereum.slogging import get_logger, configure_logging
# logger = get_logger()
# configure_logging(':trace')

c = tester2.Chain()
args = {utils.int_to_addr(10000 + i**3): i**3 for i in range(1, 101)}
c.tx(to=b'',
     value=sum(args.values()),
     data=mk_multisend_code(args),
     startgas=get_multisend_gas(args),
     gasprice=20 * 10**9)
for addr, value in args.items():
    assert c.head_state.get_balance(addr) == value
print("Test successful")
Beispiel #27
0
 def test_init(self):
     assert self.s.block.get_code(self.c.address) != ''
     assert utils.int_to_addr(self.s.block.get_storage_data(self.c.address, 0)) == tester.a0
Beispiel #28
0
    METROPOLIS_STATEROOT_STORE=0x10,
    METROPOLIS_BLOCKHASH_STORE=0x20,
    METROPOLIS_WRAPAROUND=65536,
    METROPOLIS_GETTER_CODE=decode_hex('6000355460205260206020f3'),
    METROPOLIS_DIFF_ADJUSTMENT_CUTOFF=9,
    # Constantinople fork
    CONSTANTINOPLE_FORK_BLKNUM=2**100,
    # DAO fork
    DAO_FORK_BLKNUM=1920000,
    DAO_FORK_BLKHASH=decode_hex(
        '4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb'),
    DAO_FORK_BLKEXTRA=decode_hex('64616f2d686172642d666f726b'),
    DAO_WITHDRAWER=utils.normalize_address(
        '0xbf4ed7b27f1d666546e30d74d50d173d20bca754'),
    # Anti-DoS fork
    ANTI_DOS_FORK_BLKNUM=2463000,
    SPURIOUS_DRAGON_FORK_BLKNUM=2675000,
    CONTRACT_CODE_SIZE_LIMIT=0x6000,
    # Default consensus strategy: ethash, poa, casper, pbft
    CONSENSUS_STRATEGY='ethash',
    # Serenity fork
    SERENITY_FORK_BLKNUM=2**99,
    PREV_HEADER_DEPTH=256,
    SYSTEM_ENTRY_POINT=utils.int_to_addr(2**160 - 2),
    SERENITY_HEADER_VERIFIER=utils.int_to_addr(255),
    SERENITY_HEADER_POST_FINALIZER=utils.int_to_addr(254),
    SERENITY_GETTER_CODE=decode_hex(
        '60ff331436604014161560155760203560003555005b6000355460205260206020f3'),
    # Custom specials
    CUSTOM_SPECIALS={},
)
class EventNAC(nc.NativeABIContract):
    address = utils.int_to_addr(2005)
    events = [Shout]

    def afunc(ctx, a='uint16', b='uint16', returns=None):
        ctx.Shout(a, b, 3)
Beispiel #30
0
from ethereum.tools import tester as t
from ethereum import utils, common, transactions, abi
from casper_initiating_transactions import mk_initializers, casper_config, \
    viper_rlp_decoder_address, sig_hasher_address, purity_checker_address, casper_abi, purity_checker_abi
from viper import compiler
import serpent
from ethereum.slogging import LogRecorder, configure_logging, set_level
config_string = ':info,eth.vm.log:trace,eth.vm.op:trace,eth.vm.stack:trace,eth.vm.exit:trace,eth.pb.msg:trace,eth.pb.tx:debug'
#configure_logging(config_string=config_string)
import rlp
alloc = {}
for i in range(9):
    alloc[utils.int_to_addr(i)] = {'balance': 1}
alloc[t.a0] = {'balance': 10**22}
alloc[t.a1] = {'balance': 10**22}
s = t.Chain(alloc=alloc)
t.languages['viper'] = compiler.Compiler()
t.gas_limit = 9999999
t.STARTGAS = 2000000
s.mine(1)

EPOCH_LENGTH = casper_config["epoch_length"]

code_template = """
~calldatacopy(0, 0, 128)
~call(3000, 1, 0, 0, 128, 0, 32)
return(~mload(0) == %s)
"""


def mk_validation_code(address):
Beispiel #31
0
def get_finalizer_code():
    global _finalizer_code
    if not _finalizer_code:
        import serpent
        _finalizer_code = get_contract_code(
            serpent.compile(open(finalizer_path).read()))
    return _finalizer_code


# The Casper-specific config declaration
casper_config = copy.deepcopy(default_config)
casper_config['HOMESTEAD_FORK_BLKNUM'] = 0
casper_config['METROPOLIS_FORK_BLKNUM'] = 0
casper_config['SERENITY_FORK_BLKNUM'] = 0
# config['CASPER_ADDR'] == config['SERENITY_HEADER_VERIFIER']
casper_config['CASPER_ADDR'] = utils.int_to_addr(255)
casper_config['RLP_DECODER_ADDR'] = utils.int_to_addr(253)
casper_config['HASH_WITHOUT_BLOOM_ADDR'] = utils.int_to_addr(252)
casper_config['MAX_UNCLE_DEPTH'] = 0
casper_config['PREV_HEADER_DEPTH'] = 1
casper_config['CONSENSUS_STRATEGY'] = 'casper'

_casper_ct = None


def get_casper_ct():
    import serpent
    global _casper_ct
    if not _casper_ct:
        _casper_ct = abi.ContractTranslator(
            serpent.mk_full_signature(open(casper_path).read()))
Beispiel #32
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')
class EchoContract(nc.NativeContractBase):
    address = utils.int_to_addr(2000)

    def _safe_call(self):
        res, gas, data = 1, self._msg.gas, self._msg.data.data
        return res, gas, data
    class TestTSC(nc.TypedStorageContract):

        address = utils.int_to_addr(2050)
        a = nc.Scalar('uint32')
        b = nc.List('uint16')
        c = nc.Dict('uint32')
        d = nc.IterableDict('uint256')
        e = nc.IterableDict('string')

        def _safe_call(ctx):
            # skalar
            assert ctx.a == 0
            ctx.a = 1
            assert ctx.a == 1

            ctx.a = 2
            assert ctx.a == 2

            # list
            assert isinstance(ctx.b, nc.List)
            ctx.b[0] = 10
            assert ctx.b[0] == 10

            ctx.b[1000] = 12
            assert ctx.b[1000] == 12

            assert len(ctx.b) == 1001
            ctx.b[1000] = 66
            assert ctx.b[1000] == 66
            assert len(ctx.b) == 1001

            ctx.b.append(99)
            assert len(ctx.b) == 1002
            ctx.b.append(99)
            assert len(ctx.b) == 1003

            # mapping
            assert isinstance(ctx.c, nc.Dict)
            key = b'test'
            assert ctx.c[key] == 0
            ctx.c[key] = 33
            assert ctx.c[key] == 33
            ctx.c[key] = 66
            assert ctx.c[key] == 66

            k = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17q'
            v = 2146209080

            ctx.c[k] = v
            assert ctx.c[k] == v

            # iterable dict

            ctx.d[k] = v
            assert len(ctx.d) == 1
            assert ctx.d[k] == v
            ctx.d[k] = 0

            N = 10
            for i in range(1, N + 1):
                v = i**2
                k = bytes(i)
                ctx.d[k] = v
                assert ctx.d[k] == v
                assert len(list(ctx.d.keys())) == i
                assert set(ctx.d.keys()) == set(
                    [bytes(j) for j in range(1, i + 1)])
                assert set(ctx.d.values()) == set(
                    [j**2 for j in range(1, i + 1)])

            # iterable dict with strings
            N = 10
            for i in range(1, N + 1):
                v = str(i**2)
                k = bytes(i)
                ctx.e[k] = v
                # log.DEV('kv', k=k, v=v)
                assert ctx.e[k] == v, ctx.e[k]
                assert len(list(ctx.e.keys())) == i
                assert set(ctx.e.keys()) == set(
                    [bytes(j) for j in range(1, i + 1)])
                assert set(ctx.e.values()) == set(
                    [str(j**2) for j in range(1, i + 1)])

            print list(ctx.e.keys())
            print list(ctx.e.values())
            print len(list(ctx.e.keys()))

            return 1, 1, []
class SampleNAC(nc.NativeABIContract):
    address = utils.int_to_addr(2001)

    def initialize(ctx, a='int8', c='bool', d='uint8[]'):
        "Constructor (can a constructor return anything?)"

    def afunc(ctx, a='uint16', b='uint16', returns='uint16'):
        return a * b

    def bfunc(ctx, a='uint16', returns='uint16'):
        return ctx.afunc(a, 2)  # direct native call

    def cfunc(ctx, a='uint16', returns=['uint16', 'uint16']):
        return a, a  # returns tuple

    def ccfunc(ctx, a='uint16', returns=['uint16']):
        return [a]

    def dfunc(ctx, a='uint16[2]', returns='uint16'):  # FAILS
        return a[0] * a[1]

    def efunc(ctx, a='uint16[]', returns='uint16'):
        return a[0] * a[1]

    def ffunc(ctx, returns='uint16[2]'):
        return [1, 2]

    def ffunc2(ctx, returns=['uint16[2]']):
        return [[1, 2]]

    def gfunc(ctx, returns='address[]'):
        return ['\x00' * 20] * 3

    def void_func(ctx, a='uint16', returns=None):
        return

    def noargs_func(ctx, returns='uint16'):
        return 42

    def add_property(ctx, returns=None):
        ctx.dummy = True  # must fail

    def special_vars(ctx, returns=None):
        def _is_address(a):
            return isinstance(a, bytes) and len(a) == 20

        assert ctx.msg_data
        assert _is_address(ctx.msg_sender)
        assert ctx.msg_value == 0
        assert ctx.tx_gasprice
        assert _is_address(ctx.tx_origin)
        assert _is_address(ctx.block_coinbase)
        assert ctx.block_difficulty
        assert ctx.block_number == 0
        assert ctx.block_gaslimit
        assert 0 == ctx.get_balance(ctx.address)
        assert _is_address(ctx.address)
        assert ctx.balance == 0
        assert ctx.balance == ctx.get_balance(ctx.address)
        if ctx.block_number > 0:
            assert ctx.get_block_hash(ctx.block_number -
                                      1) == ctx.block_prevhash

    def test_suicide(ctx, returns=None):
        ctx.suicide(ctx.block_coinbase)

    def get_address(ctx, returns='string'):
        return ctx.address
Beispiel #36
0
    def test_init_market(self):
        self.init_market()

        assert utils.int_to_addr(self.m.first_currency()) == self.c1.address
        assert utils.int_to_addr(self.m.second_currency()) == self.c2.address
Beispiel #37
0
    DAO_FORK_BLKHASH=decode_hex(
        '4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb'),
    DAO_FORK_BLKEXTRA=decode_hex('64616f2d686172642d666f726b'),
    CHILD_DAO_LIST=list(map(utils.normalize_address, child_dao_list)),
    DAO_WITHDRAWER=utils.normalize_address(
        '0xbf4ed7b27f1d666546e30d74d50d173d20bca754'),
    # Anti-DoS fork
    ANTI_DOS_FORK_BLKNUM=2463000,
    SPURIOUS_DRAGON_FORK_BLKNUM=2675000,
    CONTRACT_CODE_SIZE_LIMIT=0x6000,
    # Default consensus strategy: ethash, poa, casper, pbft
    CONSENSUS_STRATEGY='ethash',
    # Serenity fork
    SERENITY_FORK_BLKNUM=2**99,
    PREV_HEADER_DEPTH=256,
    SYSTEM_ENTRY_POINT=utils.int_to_addr(2**160 - 2),
    SERENITY_HEADER_VERIFIER=utils.int_to_addr(255),
    SERENITY_HEADER_POST_FINALIZER=utils.int_to_addr(254),
    SERENITY_GETTER_CODE=decode_hex(
        '60ff331436604014161560155760203560003555005b6000355460205260206020f3'
    ),
    # Custom specials
    CUSTOM_SPECIALS={},
)
assert default_config['NEPHEW_REWARD'] == \
    default_config['BLOCK_REWARD'] // 32


class Env(object):
    def __init__(self, db=None, config=None, global_config=None):
        self.db = EphemDB() if db is None else db
Beispiel #38
0
 def test_init(self):
     assert self.s.block.get_code(self.c.address) != ''
     assert utils.int_to_addr(
         self.s.block.get_storage_data(self.c.address, 0)) == tester.a0
     assert self.c.size() == 0
     assert self.c.top() == 0