class ExtCodeHashOperation extends AbstractOperation {

  @Override
  public OperationResult execute(final MessageFrame frame, final EVM evm) {
    try {
      final Address address = Words.toAddress(frame.popStackItem());
      final boolean accountIsWarm =
          frame.warmUpAddress(address) || gasCalculator().isPrecompile(address);
      final Optional<Gas> optionalCost = accountIsWarm ? warmCost : coldCost;
      if (frame.getRemainingGas().compareTo(optionalCost.get()) < 0) {
        return new OperationResult(
            optionalCost, Optional.of(ExceptionalHaltReason.INSUFFICIENT_GAS));
      } else {
        final Account account = frame.getWorldState().get(address);
        if (account == null || account.isEmpty()) {
          frame.pushStackItem(Bytes32.ZERO);
        } else {
          frame.pushStackItem(account.getCodeHash());
        }
        return new OperationResult(optionalCost, Optional.empty());
      }
    } catch (final UnderflowException ufe) {
      return new OperationResult(
          warmCost, Optional.of(ExceptionalHaltReason.INSUFFICIENT_STACK_ITEMS));
    } catch (final OverflowException ofe) {
      return new OperationResult(warmCost, Optional.of(ExceptionalHaltReason.TOO_MANY_STACK_ITEMS));
    }
  }

  public  ExtCodeHashOperation(final GasCalculator gasCalculator);

}