python ethereum 代码分析《2》

python ethereum 代码分析 《2》

python 版本以太坊

pyethapp 模块

本章主要介绍pyethapp 模块中的ChainService 和 PoWService

一些关键概念

totalDifficulty 总难度:
total difficulty总难度是当前某条链所有区块难度的总和,total difficulty被用来指示最长的那一条链,某个节点如果想从其他节点同步数据的话,他会选择total difficulty最大的那一条链来同步数据。值得注意的是uncle block的difficulty也被计算到totalDifficulty中去,以太坊白皮书中的幽灵协议阐述了为什么这么设计

uncle block 叔叔区块:也是矿工挖出来的区块,它也是合法的,但是发现的稍晚,或者是网络传输稍慢,而没有能成为最长的链上的区块
以太坊十几秒的出块间隔,大大增加了孤块的产生,并且降低了安全性。通过鼓励引用叔块,使引用主链获得更多的安全保证(因为孤块本身也是合法的)
区块可以不引用,或者最多引用两个叔块
叔块必须是区块的前2层~前7层的祖先的直接的子块
被引用过的叔块不能重复引用
引用叔块的区块,可以获得挖矿报酬的1/32,也就是5*1/32=0.15625 Ether。最多获得2*0.15625=0.3125 Ether
参考资料http://blog.csdn.net/superswords/article/details/76445278
https://zhuanlan.zhihu.com/p/28928827

head_candidate 候选头区块: 矿工本地的候选头区块,相当于一个临时区块,head_candidate一直存在并且矿工会一直更新。矿工将交易打包进这个区块,计算出随机数后将次区块作为新区块广播出去。

contract :合约,本身也是一个账户。每当一个交易指向一个合约账户时,该交易transaction的data属性作为该合约的输入执行该合约。

以太坊基本的一些概念:http://ethdocs.org/en/latest/contracts-and-transactions/index.html

ChainService 和 PowService的关系

chain service负责区块链的同步和更新,处理连接的各个节点的eth_protocol数据包,以及交易和区块的广播; pow service是矿工挖矿的服务,计算出’幸运值’后告知chain service,chain service 将区块写入区块链并广播出去。

矿工将交易打包,更新head_candidate

    @property
    def head_candidate(self):
        if self._head_candidate_needs_updating:
            self._head_candidate_needs_updating = False
            # Make a copy of self.transaction_queue because
            # make_head_candidate modifies it.
            txqueue = copy.deepcopy(self.transaction_queue)
            #将交易打包,引用uncle区块,执行交易中的合约,更新区块状态
            self._head_candidate, self._head_candidate_state = make_head_candidate(
                self.chain, txqueue, timestamp=int(time.time()))
        return self._head_candidate

chain 实例的_on_new_head回调

    def _on_new_head(self, block):
        log.debug('new head cbs', num=len(self.on_new_head_cbs))
        self.transaction_queue = self.transaction_queue.diff(
            block.transactions)
        self._head_candidate_needs_updating = True
        #cb是pow service的回调函数mine_head_candidate,更新head_candidate并开始挖矿
        for cb in self.on_new_head_cbs:
            cb(block)

powservice的回调

    def mine_head_candidate(self, _=None):
        #打包当前交易队里中的交易并更新head_candidate
        hc = self.chain.head_candidate
        if not self.active or self.chain.is_syncing:
            return
        elif (hc.transaction_count == 0 and
              not self.app.config['pow']['mine_empty_blocks']):
            return

        log.debug('mining', difficulty=hc.difficulty)
        #开始挖矿
        self.ppipe.put(('mine', dict(mining_hash=hc.mining_hash,
                                     block_number=hc.number,
                                     difficulty=hc.difficulty)))

计算出幸运值后,调用chain.add_mined_block写入区块链并广播

    #成功找到幸运值
    def recv_found_nonce(self, bin_nonce, mixhash, mining_hash):
        log.info('nonce found', mining_hash=mining_hash.encode('hex'))
        #再次打包交易,更新head_candidate
        block = self.chain.head_candidate
        if block.mining_hash != mining_hash:
            log.warn('mining_hash does not match')
            return False
        block.header.mixhash = mixhash
        block.header.nonce = bin_nonce
        #添加新块并广播
        if self.chain.add_mined_block(block):
            log.debug('mined block %d (%s) added to chain' % (
                block.number, encode_hex(block.hash[:8])))
            return True
        else:
            log.debug('failed to add mined block %d (%s) to chain' % (
                block.number, encode_hex(block.hash[:8])))
            return False
    def add_mined_block(self, block):
        log.debug('adding mined block', block=block)
        assert isinstance(block, Block)
        #添加新块
        if self.chain.add_block(block):
            log.debug('added', block=block, ts=time.time())
            assert block == self.chain.head
            self.transaction_queue = self.transaction_queue.diff(block.transactions)
            self._head_candidate_needs_updating = True
            #广播新块
            self.bro
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值