Ejemplo n.º 1
0
def create_transaction(*,
                       nonce,
                       gasprice,
                       startgas,
                       to,
                       value,
                       data=b'',
                       v=None,
                       r=None,
                       s=None,
                       network_id=None):

    if to:
        to = address_decoder(to)
    else:
        to = b''

    if network_id is not None:
        if r is not None or s is not None:
            raise Exception(
                "cannot set network id at the same time as r and s values")
        v = network_id

    tx = Transaction(nonce, gasprice, startgas, to, value, data, v or 0, r
                     or 0, s or 0)
    tx._sender = None

    return tx
Ejemplo n.º 2
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
Ejemplo n.º 3
0
def casper_start_epoch(state):
    ct = get_casper_ct()
    t = Transaction(
        0,
        0,
        10**8,
        casper_config['CASPER_ADDR'],
        0,
        ct.encode(
            'newEpoch',
            [0]))
    t._sender = casper_config['CASPER_ADDR']
    apply_transaction(state, t)
Ejemplo n.º 4
0
    def sendTransaction(self, data):
        """
        extend spec to support v,r,s signed transactions
        """
        if not isinstance(data, dict):
            raise BadRequestError('Transaction must be an object')

        def get_data_default(key, decoder, default=None):
            if key in data:
                return decoder(data[key])
            return default

        to = get_data_default('to', address_decoder, b'')
        gas_key = 'gas' if 'gas' in data else 'startgas'
        startgas = get_data_default(gas_key, quantity_decoder, default_startgas)
        gasprice_key = 'gasPrice' if 'gasPrice' in data else 'gasprice'
        gasprice = get_data_default(gasprice_key, quantity_decoder, default_gasprice)
        value = get_data_default('value', quantity_decoder, 0)
        data_ = get_data_default('data', data_decoder, b'')
        v = signed = get_data_default('v', quantity_decoder, 0)
        r = get_data_default('r', quantity_decoder, 0)
        s = get_data_default('s', quantity_decoder, 0)
        nonce = get_data_default('nonce', quantity_decoder, None)
        sender = get_data_default('from', address_decoder, self.app.services.accounts.coinbase)
        assert len(sender) == 20

        # create transaction
        if signed:
            assert nonce is not None, 'signed but no nonce provided'
            assert v and r and s
        else:
            nonce = self.app.services.chain.chain.head_candidate.get_nonce(sender)

        tx = Transaction(nonce, gasprice, startgas, to, value, data_, v, r, s)
        tx._sender = None
        print tx.log_dict()
        if not signed:
            assert sender in self.app.services.accounts, 'no account for sender'
            self.app.services.accounts.sign_tx(sender, tx)
        self.app.services.chain.add_transaction(tx, origin=None)

        log.debug('decoded tx', tx=tx.log_dict())

        if to == b'':  # create
            return address_encoder(processblock.mk_contract_address(tx.sender, nonce))
        else:
            return data_encoder(tx.hash)
Ejemplo n.º 5
0
def create_transaction(*,
                       nonce,
                       gasprice,
                       startgas,
                       to,
                       value,
                       data=b'',
                       v=0,
                       r=0,
                       s=0):

    if to:
        to = address_decoder(to)
    else:
        to = b''

    tx = Transaction(nonce, gasprice, startgas, to, value, data, v, r, s)
    tx._sender = None

    return tx
Ejemplo n.º 6
0
print 'State created'

# Check pre-balance

pre_balance = state.get_balance(my_account)
pre_dao_tokens = get_dao_balance(state, my_account)
pre_withdrawer_balance = state.get_balance(withdrawer)

print 'Pre ETH (wei) balance: %d' % pre_balance
print 'Pre DAO (base unit) balance: %d' % pre_dao_tokens

# Attempt to claim the ETH without approving (should fail)

tx0 = Transaction(state.get_nonce(my_account), 0, 1000000, withdrawer, 0,
                  withdrawer_ct.encode('withdraw', [])).sign('\x33' * 32)
tx0._sender = normalize_address(my_account)
apply_transaction(state, tx0)

med_balance = state.get_balance(my_account)
med_dao_tokens = get_dao_balance(state, my_account)
med_withdrawer_balance = state.get_balance(withdrawer)

assert med_balance == pre_balance
assert med_dao_tokens == pre_dao_tokens
assert med_withdrawer_balance == pre_withdrawer_balance > 0

print 'ETH claim without approving failed, as expected'

# Approve the withdrawal

tx1 = Transaction(
Ejemplo n.º 7
0
def send_msg_transfer_value(mainchain_state, shard_state, shard_id, tx):
    urs_addr = get_urs_contract(shard_id)['addr']
    log_rctx.debug("Begin: urs.balance={}, tx.to.balance={}".format(
        shard_state.get_balance(urs_addr), shard_state.get_balance(tx.to)))

    receipt_id = tx.r
    # we should deduct the startgas of this message in advance, because
    # the message may be possibly a contract, not only a normal value transfer.
    value = tx.value - tx.gasprice * tx.startgas
    log_rctx.debug(
        "value={}, tx.value={}, tx.gasprice={}, tx.startgas={}".format(
            value, tx.value, tx.gasprice, tx.startgas))
    if value <= 0:
        return False, None

    # start transactioning
    if not send_msg_add_used_receipt(shard_state, shard_id, receipt_id):
        return False, None

    receipt_sender_hex = call_valmgr(mainchain_state, 'get_receipts__sender',
                                     [receipt_id])
    receipt_data = call_valmgr(mainchain_state, 'get_receipts__data',
                               [receipt_id])
    msg_data = (b'00' *
                12) + utils.parse_as_bin(receipt_sender_hex) + receipt_data
    msg = vm.Message(urs_addr, tx.to, value,
                     tx.startgas - tx.intrinsic_gas_used, msg_data)
    env_tx = Transaction(0, tx.gasprice, tx.startgas, b'', 0, b'')
    env_tx._sender = urs_addr
    ext = VMExt(shard_state, env_tx)
    log_rctx.debug(
        "before apply_msg: urs_addr.balance={}, tx.to.balance={}".format(
            shard_state.get_balance(urs_addr), shard_state.get_balance(tx.to)))
    # even if `transfer_value` in `apply_msg` fails, no error occurs.
    # it seems no raise in apply_msg
    result, gas_remained, data = apply_msg(ext, msg)
    log_rctx.debug(
        "after apply_msg:  urs_addr.balance={}, tx.to.balance={}".format(
            shard_state.get_balance(urs_addr), shard_state.get_balance(tx.to)))

    assert gas_remained >= 0

    gas_used = tx.startgas - gas_remained

    # Transaction failed
    if not result:
        log_rctx.debug('TX FAILED',
                       reason='out of gas',
                       startgas=tx.startgas,
                       gas_remained=gas_remained)
        shard_state.gas_used += tx.startgas
        shard_state.delta_balance(tx.to, tx.gasprice * gas_remained)
        shard_state.delta_balance(shard_state.block_coinbase,
                                  tx.gasprice * gas_used)
        output = b''
        success = 0
    # Transaction success
    else:
        log_rctx.debug('TX SUCCESS', data=data)
        shard_state.refunds += len(set(
            shard_state.suicides)) * opcodes.GSUICIDEREFUND
        if shard_state.refunds > 0:
            log_rctx.debug('Refunding',
                           gas_refunded=min(shard_state.refunds,
                                            gas_used // 2))
            gas_remained += min(shard_state.refunds, gas_used // 2)
            gas_used -= min(shard_state.refunds, gas_used // 2)
            shard_state.refunds = 0
        # sell remaining gas
        shard_state.delta_balance(tx.to, tx.gasprice * gas_remained)
        log_rctx.debug("gas_remained={}, gasprice={}".format(
            gas_remained, tx.gasprice))
        log_rctx.debug("End: urs.balance={}, tx.to.balance={}".format(
            shard_state.get_balance(urs_addr), shard_state.get_balance(tx.to)))
        shard_state.delta_balance(shard_state.block_coinbase,
                                  tx.gasprice * gas_used)
        shard_state.gas_used += gas_used
        if tx.to:
            output = utils.bytearray_to_bytestr(data)
        else:
            output = data
        success = 1

    # Clear suicides
    suicides = shard_state.suicides
    shard_state.suicides = []
    for s in suicides:
        shard_state.set_balance(s, 0)
        shard_state.del_account(s)

    # Pre-Metropolis: commit state after every tx
    if not shard_state.is_METROPOLIS() and not SKIP_MEDSTATES:
        shard_state.commit()

    # Construct a receipt
    r = mk_receipt(shard_state, success, shard_state.logs)
    _logs = list(shard_state.logs)
    shard_state.logs = []
    shard_state.add_receipt(r)
    shard_state.set_param('bloom', shard_state.bloom | r.bloom)
    shard_state.set_param('txindex', shard_state.txindex + 1)

    return success, output
Ejemplo n.º 8
0
print 'State created'

# Check pre-balance

pre_balance = state.get_balance(my_account)
pre_dao_tokens = get_dao_balance(state, my_account)
pre_withdrawer_balance = state.get_balance(withdrawer)

print 'Pre ETH (wei) balance: %d' % pre_balance
print 'Pre DAO (base unit) balance: %d' % pre_dao_tokens

# Attempt to claim the ETH without approving (should fail)

tx0 = Transaction(state.get_nonce(my_account), 0, 1000000, withdrawer, 0, withdrawer_ct.encode('withdraw', [])).sign('\x33' * 32)
tx0._sender = normalize_address(my_account)
apply_transaction(state, tx0)

med_balance = state.get_balance(my_account)
med_dao_tokens = get_dao_balance(state, my_account)
med_withdrawer_balance = state.get_balance(withdrawer)

assert med_balance == pre_balance
assert med_dao_tokens == pre_dao_tokens
assert med_withdrawer_balance == pre_withdrawer_balance > 0

print 'ETH claim without approving failed, as expected'

# Approve the withdrawal

tx1 = Transaction(state.get_nonce(my_account), 0, 1000000, dao, 0, dao_ct.encode('approve', [withdrawer, 100000 * 10**18])).sign('\x33' * 32)