源码阅读 etherum-block.py

def calc_difficulty(parent, timestamp):
    config = parent.config
    offset = parent.difficulty // config['BLOCK_DIFF_FACTOR']
    if parent.number >= (config['METROPOLIS_FORK_BLKNUM'] - 1):
        sign = max(len(parent.uncles) - ((timestamp - parent.timestamp) // config['METROPOLIS_DIFF_ADJUSTMENT_CUTOFF']), -99)
    elif parent.number >= (config['HOMESTEAD_FORK_BLKNUM'] - 1):
        sign = max(1 - ((timestamp - parent.timestamp) // config['HOMESTEAD_DIFF_ADJUSTMENT_CUTOFF']), -99)
    else:
        sign = 1 if timestamp - parent.timestamp < config['DIFF_ADJUSTMENT_CUTOFF'] else -1
    # If we enter a special mode where the genesis difficulty starts off below
    # the minimal difficulty, we allow low-difficulty blocks (this will never
    # happen in the official protocol)
    o = int(max(parent.difficulty + offset * sign, min(parent.difficulty, config['MIN_DIFF'])))
    period_count = (parent.number + 1) // config['EXPDIFF_PERIOD']
    if period_count >= config['EXPDIFF_FREE_PERIODS']:
        o = max(o + 2 ** (period_count - config['EXPDIFF_FREE_PERIODS']), config['MIN_DIFF'])
    # print('Calculating difficulty of block %d, timestamp difference %d, parent diff %d, child diff %d' % (parent.number + 1, timestamp - parent.timestamp, parent.difficulty, o))
    return o

  以上方法计算困难度

 

一个以太坊账号的类(Account):

内部的属性:

    """
    在这个类Account的参数列表中有一个参数rlp.Serializeable,应该表示一个经过序列化后的rlp编码格式的对象字符
    :ivar nonce:一个账户的nonce(表示这个账户的交易数目)
    :ivar balance:这个账户的余额
    :ivar storage: 表示这个账户的tire的根
    :ivar code_hash: 表示和账户关联的经过SHA3的哈希串
		"""
    
    fields = [
        ('nonce', big_endian_int),
        ('balance', big_endian_int),
        ('storage', trie_root),
        ('code_hash', hash32)
    ]

该类的_init_方法参数列表(self, nonce, balance, storage, code_hash, db),初始化方法如下,使用

 def __init__(self, nonce, balance, storage, code_hash, db):
        assert isinstance(db, BaseDB)
        self.db = db
        super(Account, self).__init__(nonce, balance, storage, code_hash)

以下获得code值,方法如下:(code指什么?codehash?)

    @property
    def code(self):
        """The EVM code of the account.

        This property will be read from or written to the db at each access,
        with :ivar:`code_hash` used as key.
        """
        return self.db.get(self.code_hash)

以下设置code的值

@code.setter
def code(self, value): self.code_hash = utils.sha3(value) # Technically a db storage leak, but doesn't really matter; the only # thing that fails to get garbage collected is when code disappears due # to a suicide self.db.inc_refcount(self.code_hash, value)

下面方法设置一个空白账户:

    @classmethod
    def blank_account(cls, db, initial_nonce=0):
        """Create a blank account

        The returned account will have zero nonce and balance, a blank storage
        trie and empty code.

        :param db: the db in which the account will store its code.
        """
        code_hash = utils.sha3(b'')
        db.put(code_hash, b'')
        return cls(initial_nonce, 0, trie.BLANK_ROOT, code_hash, db)

类Receipt

#state_root用于对数据库进行校验,当和其他数据库不一致的时候,表明有非法交易或者需要同步,用于校验
    fields = [
        ('state_root', trie_root),
        ('gas_used', big_endian_int),
        ('bloom', int256),
        ('logs', CountableList(processblock.Log))
    ]

类blockhead

 他的类内的属性为:

fields = [
        ('prevhash', hash32), //前一个block的32字节hash值
        ('uncles_hash', hash32), // 32字节的 经过RLP编码的uncle headers的列表
        ('coinbase', address),  //20字节的coinbase字节的地址
        ('state_root', trie_root),  // state trie的根
        ('tx_list_root', trie_root),  // 
        ('receipts_root', trie_root),
        ('bloom', int256),
        ('difficulty', big_endian_int), //区块的难度
        ('number', big_endian_int),  //区块祖先的个数 
        ('gas_limit', big_endian_int),
        ('gas_used', big_endian_int), //这个区块上所有的交易消耗的gas
        ('timestamp', big_endian_int),
        ('extra_data', binary),   ///最多1024字节
        ('mixhash', binary),
        ('nonce', Binary(8, allow_empty=True)) //32字节 作为占位符或者去构成工作量证明
    ]

  这些属性的初始化如下:

 def __init__(self,
                 prevhash=default_config['GENESIS_PREVHASH'],  //default 在etherum下的config包中  GENESIS_PREVHASH=b'\x00' * 32,
                 uncles_hash=utils.sha3rlp([]),  
                 coinbase=default_config['GENESIS_COINBASE'],//GENESIS_COINBASE=b'\x00' * 20,
                 state_root=trie.BLANK_ROOT,
                 tx_list_root=trie.BLANK_ROOT,
                 receipts_root=trie.BLANK_ROOT,
                 bloom=0,
                 difficulty=default_config['GENESIS_DIFFICULTY'],
                 number=0,
                 gas_limit=default_config['GENESIS_GAS_LIMIT'], //GENESIS_GAS_LIMIT=3141592
                 gas_used=0,
                 timestamp=0,
                 extra_data='',
                 mixhash=default_config['GENESIS_MIXHASH'],
                 nonce=''):
        # at the beginning of a method, locals() is a dict of all arguments
        fields = {k: v for k, v in locals().items() if k != 'self'}
        if len(fields['coinbase']) == 40:
            fields['coinbase'] = decode_hex(fields['coinbase'])
        assert len(fields['coinbase']) == 20
        self.block = None
        super(BlockHeader, self).__init__(**fields)

  

 

  

 

posted @ 2016-11-22 19:20  sunalive  Views(452)  Comments(0)    收藏  举报