Exemplo n.º 1
0
 def sender(self):
     if not self._sender:
         # Determine sender
         if self.r == 0 and self.s == 0:
             self._sender = null_address
         else:
             if self.v in (27, 28):
                 vee = self.v
                 sighash = utils.sha3(rlp.encode(self, UnsignedTransaction))
             elif self.v >= 37:
                 vee = self.v - self.network_id * 2 - 8
                 assert vee in (27, 28)
                 rlpdata = rlp.encode(rlp.infer_sedes(self).serialize(self)[
                                      :-3] + [self.network_id, '', ''])
                 sighash = utils.sha3(rlpdata)
             else:
                 raise InvalidTransaction("Invalid V value")
             if self.r >= secpk1n or self.s >= secpk1n or self.r == 0 or self.s == 0:
                 raise InvalidTransaction("Invalid signature values!")
             pub = ecrecover_to_pub(sighash, vee, self.r, self.s)
             if pub == b'\x00' * 64:
                 raise InvalidTransaction(
                     "Invalid signature (zero privkey cannot sign)")
             self._sender = utils.sha3(pub)[-20:]
     return self._sender
Exemplo n.º 2
0
    def sender(self):

        if not self._sender:
            # Determine sender
            if self.v:
                if self.r >= N or self.s >= N or self.v < 27 or self.v > 28 \
                or self.r == 0 or self.s == 0:
                    raise InvalidTransaction("Invalid signature values!")
                log.debug('recovering sender')
                rlpdata = rlp.encode(self, UnsignedTransaction)
                rawhash = utils.sha3(rlpdata)

                pk = PublicKey(flags=ALL_FLAGS)
                try:
                    pk.public_key = pk.ecdsa_recover(
                        rawhash,
                        pk.ecdsa_recoverable_deserialize(
                            zpad(utils.bytearray_to_bytestr(int_to_32bytearray(self.r)), 32) + zpad(utils.bytearray_to_bytestr(int_to_32bytearray(self.s)), 32),
                            self.v - 27
                        ),
                        raw=True
                    )
                    pub = pk.serialize(compressed=False)
                except Exception:
                    raise InvalidTransaction("Invalid signature values (x^3+7 is non-residue)")

                if pub[1:] == b"\x00" * 32:
                    raise InvalidTransaction("Invalid signature (zero privkey cannot sign)")
                pub = encode_pubkey(pub, 'bin')
                self._sender = utils.sha3(pub[1:])[-20:]
                assert self.sender == self._sender
            else:
                self._sender = 0
        return self._sender
Exemplo n.º 3
0
    def __init__(self,
                 nonce,
                 gasprice,
                 startgas,
                 to,
                 value,
                 data,
                 v=0,
                 r=0,
                 s=0):
        self.data = None

        to = utils.normalize_address(to, allow_blank=True)
        assert len(to) == 20 or len(to) == 0
        super(Transaction, self).__init__(nonce, gasprice, startgas, to, value,
                                          data, v, r, s)
        self.logs = []

        if self.gasprice >= TT256 or self.startgas >= TT256 or \
                self.value >= TT256 or self.nonce >= TT256:
            raise InvalidTransaction("Values way too high!")
        if self.startgas < self.intrinsic_gas_used:
            raise InvalidTransaction("Startgas too low")

        log.debug('deserialized tx', tx=encode_hex(self.hash)[:8])
Exemplo n.º 4
0
    def __init__(self, nonce, gasprice, startgas, to, value, data, v=0, r=0, s=0):
        if len(to) in (40, 48):
            to = decode_hex(to)
        if len(to) == 24:
            to = utils.check_and_strip_checksum(to)
        assert len(to) == 20 or len(to) == 0
        super(Transaction, self).__init__(nonce, gasprice, startgas, to, value, data, v, r, s)
        self.logs = []

        if self.gasprice >= TT256 or self.startgas >= TT256 or \
                self.value >= TT256 or self.nonce >= TT256:
            raise InvalidTransaction("Values way too high!")
        if self.startgas < intrinsic_gas_used(self):
            raise InvalidTransaction("Startgas too low")

        log.debug('deserialized tx', tx=encode_hex(self.hash)[:8])
Exemplo n.º 5
0
    def __init__(self,
                 nonce,
                 gasprice,
                 startgas,
                 to,
                 value,
                 data,
                 v=0,
                 r=0,
                 s=0,
                 sender=None,
                 network=None):
        # self.data = None

        to = utils.normalize_address(to, allow_blank=True)

        super(Transaction, self).__init__(nonce, gasprice, startgas, to, value,
                                          data, v, r, s)

        if self.gasprice >= TT256 or self.startgas >= TT256 or \
                self.value >= TT256 or self.nonce >= TT256:
            raise InvalidTransaction("Values way too high!")

        if sender:
            self._sender = bytes.fromhex(sender[2:])
        if network:
            self.network = network
Exemplo n.º 6
0
def config_fork_specific_validation(config, blknum, tx):
    # (1) The transaction signature is valid;
    _ = tx.sender
    if blknum >= config['CONSTANTINOPLE_FORK_BLKNUM']:
        tx.check_low_s_metropolis()
    else:
        if tx.sender == null_address:
            raise InvalidTransaction("EIP86 transactions not available yet")
        if blknum >= config['HOMESTEAD_FORK_BLKNUM']:
            tx.check_low_s_homestead()
    if blknum >= config["SPURIOUS_DRAGON_FORK_BLKNUM"]:
        if tx.network_id not in (None, config["NETWORK_ID"]):
            raise InvalidTransaction("Wrong network ID")
    else:
        if tx.network_id is not None:
            raise InvalidTransaction("Wrong network ID")
    return True
Exemplo n.º 7
0
    def sign(self, key):
        """Sign this transaction with a private key.

        A potentially already existing signature would be overridden.
        """
        if key in (0, '', '\x00' * 32):
            raise InvalidTransaction("Zero privkey cannot sign")
        rawhash = utils.sha3(rlp.encode(self, UnsignedTransaction))
        self.v, self.r, self.s = ecdsa_raw_sign(rawhash, key)
        self.sender = utils.privtoaddr(key)
        return self
Exemplo n.º 8
0
 def sender(self):
     if not self._sender:
         # Determine sender
         if self.v:
             if self.r >= N or self.s >= P or self.v < 27 or self.v > 28 or self.r == 0 or self.s == 0:
                 raise InvalidTransaction("Invalid signature values!")
             log.debug('recovering sender')
             rlpdata = rlp.encode(self, UnsignedTransaction)
             rawhash = utils.sha3(rlpdata)
             pub = ecdsa_raw_recover(rawhash, (self.v, self.r, self.s))
             if pub is False:
                 raise InvalidTransaction("Invalid signature values (x^3+7 is non-residue)")
             if pub == (0, 0):
                 raise InvalidTransaction("Invalid signature (zero privkey cannot sign)")
             pub = encode_pubkey(pub, 'bin')
             self._sender = utils.sha3(pub[1:])[-20:]
             assert self.sender == self._sender
         else:
             self._sender = 0
     return self._sender
Exemplo n.º 9
0
 def sender(self):
     if not self._sender:
         # Determine sender
         if self.v:
             if self.r >= N or self.s >= P or self.v < 27 or self.v > 28:
                 raise InvalidTransaction("Invalid signature values!")
             log.debug('recovering sender')
             rlpdata = rlp.encode(self, UnsignedTransaction)
             rawhash = utils.sha3(rlpdata)
             pub = encode_pubkey(
                 ecdsa_raw_recover(rawhash, (self.v, self.r, self.s)),
                 'bin')
             self._sender = utils.sha3(pub[1:])[-20:]
             assert self.sender == self._sender
         else:
             self._sender = 0
     return self._sender
Exemplo n.º 10
0
    def __init__(self,
                 nonce,
                 gasprice,
                 startgas,
                 to,
                 value,
                 data,
                 v=0,
                 r=0,
                 s=0):
        # self.data = None

        to = utils.normalize_address(to, allow_blank=True)

        super(Transaction, self).__init__(nonce, gasprice, startgas, to, value,
                                          data, v, r, s)

        if self.gasprice >= TT256 or self.startgas >= TT256 or \
                self.value >= TT256 or self.nonce >= TT256:
            raise InvalidTransaction("Values way too high!")
Exemplo n.º 11
0
def validate_transaction(state, tx):

    # (1) The transaction signature is valid;
    if not tx.sender:  # sender is set and validated on Transaction initialization
        raise UnsignedTransaction(tx)

    assert config_fork_specific_validation(
        state.config, state.block_number, tx)

    # (2) the transaction nonce is valid (equivalent to the
    #     sender account's current nonce);
    req_nonce = 0 if tx.sender == null_address else state.get_nonce(tx.sender)
    if req_nonce != tx.nonce:
        raise InvalidNonce(rp(tx, 'nonce', tx.nonce, req_nonce))

    # (3) the gas limit is no smaller than the intrinsic gas,
    # g0, used by the transaction;
    if tx.startgas < tx.intrinsic_gas_used:
        raise InsufficientStartGas(
            rp(tx, 'startgas', tx.startgas, tx.intrinsic_gas_used))

    # (4) the sender account balance contains at least the
    # cost, v0, required in up-front payment.
    total_cost = tx.value + tx.gasprice * tx.startgas

    if state.get_balance(tx.sender) < total_cost:
        raise InsufficientBalance(
            rp(tx, 'balance', state.get_balance(tx.sender), total_cost))

    # check block gas limit
    if state.gas_used + tx.startgas > state.gas_limit:
        raise BlockGasLimitReached(
            rp(tx, 'gaslimit', state.gas_used + tx.startgas, state.gas_limit))

    # EIP86-specific restrictions
    if tx.sender == null_address and (tx.value != 0 or tx.gasprice != 0):
        raise InvalidTransaction(
            "EIP86 transactions must have 0 value and gasprice")

    return True
Exemplo n.º 12
0
    def __init__(self,
                 nonce,
                 gasprice,
                 startgas,
                 to,
                 value,
                 data,
                 v=0,
                 r=0,
                 s=0):
        if len(to) == 40:
            to = decode_hex(to)
        assert len(to) == 20 or len(to) == 0
        super(Transaction, self).__init__(nonce, gasprice, startgas, to, value,
                                          data, v, r, s)
        self.logs = []

        if self.gasprice >= TT256 or self.startgas >= TT256 or \
                self.value >= TT256 or self.nonce >= TT256:
            raise InvalidTransaction("Values way too high!")

        log.debug('deserialized tx', tx=self.hash.encode('hex')[:8])
Exemplo n.º 13
0
    def sign(self, key):
        """Sign this transaction with a private key.

        A potentially already existing signature would be overridden.
        """
        if key in (0, '', b'\x00' * 32, '0' * 64):
            raise InvalidTransaction("Zero privkey cannot sign")
        rawhash = utils.sha3(rlp.encode(self, UnsignedTransaction))

        if len(key) == 64:
            # we need a binary key
            key = encode_privkey(key, 'bin')

        pk = PrivateKey(key, raw=True)
        signature = pk.ecdsa_recoverable_serialize(
            pk.ecdsa_sign_recoverable(rawhash, raw=True))
        signature = signature[0] + utils.bytearray_to_bytestr([signature[1]])
        self.v = utils.safe_ord(signature[64]) + 27
        self.r = big_endian_to_int(signature[0:32])
        self.s = big_endian_to_int(signature[32:64])

        self.sender = utils.privtoaddr(key)
        return self
Exemplo n.º 14
0
 def check_low_s_homestead(self):
     if self.s > secpk1n // 2 or self.s == 0:
         raise InvalidTransaction("Invalid signature S value!")
Exemplo n.º 15
0
 def check_low_s_metropolis(self):
     if self.s > secpk1n // 2:
         raise InvalidTransaction("Invalid signature S value!")
Exemplo n.º 16
0
 def check_low_s(self):
     if self.s > N // 2 or self.s == 0:
         raise InvalidTransaction("Invalid signature S value!")