def call_backend_verify(self, pubkey: PublicKey, signature: Signature, msg_hash: bytes) -> bool: """ Verifies a hex string signature and message hash are from the provided public key. """ is_valid_sig = signature.verify_msg_hash(msg_hash, pubkey) sig_pubkey = signature.recover_public_key_from_msg_hash(msg_hash) return is_valid_sig and (sig_pubkey == pubkey)
def ecrecover(signature, message): message_hash = to_bytes(hexstr=message) message_hash = solidityKeccak( ['string', 'bytes32'], ['\x19Ethereum Signed Message:\n32', message_hash]) _signature = Signature(to_bytes(hexstr=signature)) public_key = _signature.recover_public_key_from_msg_hash(message_hash) return public_key.to_checksum_address()
def get_posw_info( config: POSWConfig, header: Header, stakes: int, block_cnt: Dict[bytes, int], stake_per_block: Optional[int] = None, signer: Optional[bytes] = None, ) -> Optional[PoSWInfo]: if (not (config.ENABLED and header.create_time >= config.ENABLE_TIMESTAMP) or header.height == 0): return None # evaluate stakes before the to-be-added block coinbase_recipient = header.coinbase_address.recipient required_stakes_per_block = stake_per_block or config.TOTAL_STAKE_PER_BLOCK block_threshold = min(config.WINDOW_SIZE, stakes // required_stakes_per_block) cnt = block_cnt.get(coinbase_recipient, 0) diff = header.difficulty ret = lambda success: PoSWInfo( diff // config.get_diff_divider(header.create_time) if success else diff, block_threshold, # mined blocks should include current one, assuming success posw_mined_blocks=cnt + 1, ) # fast path if block_threshold == 0: return ret(False) # need to check signature if signer is specified. only applies for root chain if signer: check(isinstance(header, RootBlockHeader)) if signer == bytes(20): return ret(False) block_sig = Signature(header.signature) try: pubk = block_sig.recover_public_key_from_msg_hash( header.get_hash_for_mining()) except BadSignature: return ret(False) if pubk.to_canonical_address() != signer: return ret(False) return ret(cnt < block_threshold)
def test_sign(): # 对应智能合约 keccak256(abi.encodePacked(uint40(commitLastBlock), commit)); commitLastBlock = unhexlify('%010x' % 0xb34464) # 和uint40对应 commit = unhexlify( '24027f1fe6692863385b95ab253f0700a35d03a8967dff8588e2de6b066b44e4') h = keccak(commitLastBlock + commit) print(hexlify(h)) #正确keccak结果, 正确是: A5CA2F7474A762F6EA97585911E0CC48FB1282D53A0A602056B61216AF7637FD sig = '2e608766579a55fffd6d7872e89d56642980358160b877fdb00855e716a8cbeb' sig += '3faac77026378c125f5ead4bb0cbf303554ba85d9920d158a9aacecfa2ada6a8' sig += '00' # 27 sig = unhexlify(sig) sg = Signature(sig) pubk = sg.recover_public_key_from_msg_hash(h) print(pubk.to_checksum_address() ) # 正确的应是 0xb00b5ca7ec0502f2f269e99b91ebbccbce9cccec pass