首页 > 代码库 > 源码阅读 etherum-transactions.py

源码阅读 etherum-transactions.py

  交易(transaction.py)的结构:

fields = [
(‘nonce‘, big_endian_int),
(‘gasprice‘, big_endian_int),
(‘startgas‘, big_endian_int),
(‘to‘, utils.address),
(‘value‘, big_endian_int),
(‘data‘, binary),
(‘v‘, big_endian_int),
(‘r‘, big_endian_int),
(‘s‘, big_endian_int),
]

__init__方法:

to参数初始化:to = utils.normalize_address(to, allow_blank=True)

关于上面的normalize_address方法

def normalize_address(x, allow_blank=False):
    if is_numeric(x):
        return int_to_addr(x)
    if allow_blank and x in {‘‘, b‘‘}:
        return b‘‘
    if len(x) in (42, 50) and x[:2] in {‘0x‘, b‘0x‘}://如果前两个字符问0x,截取从第三个字符开始的所有字符串
        x = x[2:]
    if len(x) in (40, 48):
        x = decode_hex(x)
    if len(x) == 24:
        assert len(x) == 24 and sha3(x[:20])[:4] == x[-4:] //比较哈希值
        x = x[:20]
    if len(x) != 20:
        raise Exception("Invalid address format: %r" % x)
    return x

  回到transactions.py方法:

使用父类构造方法初始化

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

 通过gas 判断交易是否合法:

  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")

  

def sender(self)方法:通过签名和公钥验证账号合法性

 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 = http://www.mamicode.com/rlp.encode(self, UnsignedTransaction)"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

  sender的setter函数:

    @sender.setter
    def sender(self, value):
        self._sender = value

def intrinsic_gas_used(self)方法:

 @property
    def intrinsic_gas_used(self):
    	#计算0位数量
        num_zero_bytes = str_to_bytes(self.data).count(ascii_chr(0))
        #计算非0位数量
        num_non_zero_bytes = len(self.data) - num_zero_bytes
        return (opcodes.GTXCOST
                + opcodes.GTXDATAZERO * num_zero_bytes
                + opcodes.GTXDATANONZERO * num_non_zero_bytes)

  

 

源码阅读 etherum-transactions.py