55 lines
1.4 KiB
Python
55 lines
1.4 KiB
Python
import ethereum.utils
|
|
import rlp
|
|
from rlp.sedes import big_endian_int, binary
|
|
from web3.auto import w3
|
|
|
|
from utils.utils import get_sender, sign
|
|
|
|
from .exceptions import InvalidTxSignatureException
|
|
|
|
|
|
class Transaction(rlp.Serializable):
|
|
|
|
fields = [
|
|
('uid', big_endian_int),
|
|
('prev_block', big_endian_int),
|
|
('denomination', big_endian_int),
|
|
('new_owner', ethereum.utils.address),
|
|
('sig', binary),
|
|
]
|
|
|
|
def __init__(
|
|
self, uid, prev_block, denomination, new_owner, sig=b'\x00' * 65
|
|
):
|
|
self.uid = uid
|
|
self.prev_block = prev_block
|
|
self.denomination = denomination
|
|
self.new_owner = ethereum.utils.normalize_address(new_owner)
|
|
self.sig = sig
|
|
self.spent = False # not part of the rlp
|
|
self.make_mutable()
|
|
|
|
@property
|
|
def hash(self):
|
|
if self.prev_block != 0:
|
|
ret = w3.sha3(rlp.encode(self, UnsignedTransaction))
|
|
else:
|
|
ret = w3.soliditySha3(['uint64'], [self.uid])
|
|
return ret
|
|
|
|
@property
|
|
def merkle_hash(self):
|
|
return w3.sha3(rlp.encode(self))
|
|
|
|
@property
|
|
def sender(self):
|
|
if self.sig == b'\x00' * 65:
|
|
raise InvalidTxSignatureException('Tx not signed')
|
|
return get_sender(self.hash, self.sig)
|
|
|
|
def sign(self, key):
|
|
self.sig = sign(self.hash, key)
|
|
|
|
|
|
UnsignedTransaction = Transaction.exclude(['sig'])
|