ABAP simulation implementation of blockchain technology

Ideas

The ABAP code in this article is a simple blockchain simulation implementation, mainly used to demonstrate and understand the basic concepts of blockchain. The main functions and implementation logic of the code will be explained line by line below.

  1. Reporting Statement:

    REPORT zblockchain.
    

    This is the statement of the ABAP report, used to create an independent ABAP report program.

  2. Parameter declaration:

    PARAMETERS: diffle TYPE char5 default '00000',
                noblock TYPE i DEFAULT 2.
    

    Two input parameters are declared here. diffle is a character parameter with a length of 5, and noblock is an integer parameter used to control the number of blocks in the generated blockchain. and workload.

  3. Data Statement:

    DATA: blockdata TYPE zcl_abap_blockchain_tool=>tt_block,
          blockdataline LIKE LINE OF blockdata,
          timestamp TYPE timestamp,
          combineddata TYPE string,
          prevblockdata LIKE LINE OF blockdata,
          nonce TYPE i VALUE 1,
          noncestring TYPE string,
          flag TYPE c,
          difflength TYPE i,
          gethash TYPE REF TO cl_abap_message_digest.
    

    These statements declare the data structures used to store blockchain data, timestamps, proof-of-work (nonces), and other auxiliary variables.

  4. Creation of initial block:

    blockdataline-index = 0.
    blockdataline-data = 'Jerry first Genesis block'.
    blockdataline-phash = '000000'.
    GET TIME STAMP FIELD timestamp.
    blockdataline-timestamp = timestamp.
    blockdataline-nonce = 0.
    

    These statements are used to create the initial block of the blockchain, often called the “genesis block.” It sets the block index, data, the hash of the previous block, timestamp and other information, and initializes the nonce of the proof of work.

  5. Calculate the hash of the initial block:

    CONCATENATE blockdataline-index blockdataline-data blockdataline-phash blockdataline-timestamp blockdataline-nonce INTO combineddata.
    CALL METHOD cl_abap_message_digest=>calculate_hash_for_char
      EXPORTING
        if_algorithm = 'SHA1'
        if_data = combineddata
      IMPORTING
        ef_hashstring = blockdataline-chash.
    APPEND blockdataline TO blockdata.
    

    This code combines the various attributes of the block into a string, then calculates the hash value of this string using the SHA-1 hashing algorithm, and stores the hash value in blockdataline-chash . Finally, the genesis block is added to blockdata.

  6. Generate subsequent blocks:

    noblock = noblock - 1.
    difflength = strlen(diffle).
    DO noblock TIMES.
    

    This part of the code uses a loop to generate more chunks. The noblock parameter controls the number of blocks to be generated.

  7. Set the properties of the new block:

    blockdataline-index = sy-tabix.
    CONCATENATE `Jerry's Block ` blockdataline-index INTO blockdataline-data SEPARATED BY '-'.
    READ TABLE blockdata INTO prevblockdata INDEX blockdataline-index.
    

    This code is used to set the index and data for the new block and try to read the data of the previous block to get the hash of the previous block.

  8. Compute proof of work:

    GET TIME STAMP FIELD timestamp.
    blockdataline-timestamp = timestamp.
    WHILE flag EQ abap_false.
    

    Next, a loop is used to calculate the proof of work until a hash that meets the criteria is found. This process involves continuously increasing the nonce and recalculating the hash value until the specified condition is met (the first digits of blockdataline-chash are equal to diffle).

  9. Update hash:

    noncestring = nonce.
    CONCATENATE blockdataline-index blockdataline-data blockdataline-phash blockdataline-timestamp noncestring INTO combineddata.
    CALL METHOD cl_abap_message_digest=>calculate_hash_for_char
      EXPORTING
        if_algorithm = 'SHA1'
        if_data = combineddata
      IMPORTING
        ef_hashstring = blockdataline-chash.
    

    On each loop iteration, the nonce is appended to the block data, the hash is recalculated, and stored in blockdataline-chash.

  10. Check the proof-of-work conditions:

    IF blockdataline-chash(difflength) = diffle.
      flag = 'X'.
      blockdataline-nonce = nonce.
      APPEND blockdataline TO blockdata.
      nonce = 1.
      CLEAR: blockdataline.
    ENDIF.
    

    When a hash value that meets the criteria is found, the loop is exited, the value of the nonce and the new block are added to the blockchain data, and the relevant variables are reset.

  11. Clear flag:

    CLEAR flag.
    

    Clears the flag flag used in the loop.

  12. Datasheet Statement:

    DATA: g_alv_tree TYPE REF TO cl_gui_alv_tree,
          gt_data TYPE STANDARD TABLE OF zcl_abap_blockchain_tool=>ty_displayed_node,
          ok_code LIKE sy-ucomm,
          save_ok LIKE sy-ucomm,
          ls_data LIKE LINE OF gt_data.
    

    This section declares the relevant variables used to create data tables and ALV trees.

  13. Initialization of blockchain tools:

    DATA(lo_tool) = NEW zcl_abap_blockchain_tool(blockdata).
    

    Created a blockchain tool object that will consume the previously generated blockchain data.

  14. Generation of field catalog:

    DATA(lt_fieldcat) = lo_tool->get_fieldcat_by_data( ls_data ).
    

    Generate a field catalog that defines the column properties of the ALV table.

  15. Definition of tag fields:

    PERFORM change_label.
    

    Call the change_label subroutine to change the

Column definition labels.

  1. Screen call:

    CALL SCREEN 100.
    

    Call screen number 100, where the ALV table will be displayed.

  2. Define label subroutine:

    DEFINE define_label.
    ...
    END-OF-DEFINITION.
    

    This is a subroutine that defines labels and other properties for fields. This subroutine is called in the change_label subroutine to define the column’s label, width, and other properties.

  3. Initialize the ALV tree:

    FORM init_tree.
    ...
    ENDFORM.
    

    This subroutine initializes the ALV tree, including setting the title and display of the ALV table.

  4. Create the ALV tree:

    FORM create_tree.
    ...
    ENDFORM.
    

    This subroutine is used to create an ALV tree and display data in an ALV table.

  5. Build a hierarchical title:

    FORM build_hierarchy_header CHANGING p_hierarchy_header TYPE treev_hhdr.
    ...
    ENDFORM.
    

    This subroutine is used to construct the hierarchical title of the ALV tree, specifying the title and width of the tree.

  6. Exit the program:

    FORM exit_program.
    ...
    ENDFORM.
    

    This subroutine is used to exit the program.

  7. PBO module (Process Before Output):

    MODULE pbo OUTPUT.
    ...
    ENDMODULE.
    

    This module is used to process data before outputting it to the screen, including setting the screen’s title and menu.

  8. PAI module (Process After Input):

    MODULE pai INPUT.
    ...
    ENDMODULE.
    

    This module is used to process user input, including responding to user exit requests and other input operations.

In summary, this ABAP code implements a simple blockchain simulation, including the creation of initial blocks, calculation of proof of work, and display of blockchain data. Through the blockchain tool object and ALV tree table, users can view and explore the generated blockchain data. This example is mainly used to educate and demonstrate the basic principles and workings of blockchain.

Complete source code

* &---------------------------------------------- --------------------------*
* & Report ZBLOCKCHAIN
* &------------------------------------------------- -----------------------*
* &
* &------------------------------------------------- -----------------------*
REPORT zblockchain.

PARAMETERS: diffle TYPE char5 default '00000',
            noblock TYPE i DEFAULT 2.

DATA:blockdata TYPE zcl_abap_blockchain_tool=>tt_block .

DATA:blockdataline LIKE LINE OF blockdata,
     timestamp TYPE timestamp,
     combineddata TYPE string,
     prevblockdata LIKE LINE OF blockdata,
     nonce TYPE i VALUE 1,
     noncestring TYPE string,
     flag TYPE c,
     difflength TYPE i,
     gethash TYPE REF TO cl_abap_message_digest.

blockdataline-index = 0.
blockdataline-data = 'Jerry first Genesis block'.
blockdataline-phash = '000000'.
GET TIME STAMP FIELD timestamp.
blockdataline-timestamp = timestamp.
blockdataline-nonce = 0.
CONCATENATE blockdataline-index blockdataline-data blockdataline-phash blockdataline-timestamp blockdataline-nonce INTO combineddata.
CALL METHOD cl_abap_message_digest=>calculate_hash_for_char
  EXPORTING
    if_algorithm = 'SHA1'
    if_data = combineddata
  IMPORTING
    ef_hashstring = blockdataline-chash.
APPEND blockdataline TO blockdata.

noblock = noblock - 1.
difflength = strlen(diffle).

DO noblock TIMES.
  blockdataline-index = sy-tabix.
  CONCATENATE `Jerry's Block ` blockdataline-index INTO blockdataline-data SEPARATED BY '-'.
  READ TABLE blockdata INTO prevblockdata INDEX blockdataline-index.
  IF sy-subrc EQ 0.
    blockdataline-phash = prevblockdata-chash.
  ENDIF.
  GET TIME STAMP FIELD timestamp.
  blockdataline-timestamp = timestamp.

  WHILE flag EQ abap_false.
    noncestring = nonce.
    CONCATENATE blockdataline-index blockdataline-data blockdataline-phash blockdataline-timestamp noncestring INTO combineddata.
    CALL METHOD cl_abap_message_digest=>calculate_hash_for_char
      EXPORTING
        if_algorithm = 'SHA1'
        if_data = combineddata
      IMPORTING
        ef_hashstring = blockdataline-chash.

    IF blockdataline-chash(difflength) = diffle.
      flag = 'X'.
      blockdataline-nonce = nonce.
      APPEND blockdataline TO blockdata.
      nonce = 1.
      CLEAR:blockdataline.
    ENDIF.
    nonce = nonce + 1.
  ENDWHILE.
  CLEAR flag.
ENDDO.

DATA: g_alv_tree TYPE REF TO cl_gui_alv_tree,
      gt_data TYPE STANDARD TABLE OF zcl_abap_blockchain_tool=>ty_displayed_node,
      ok_code LIKE sy-ucomm,
      save_ok LIKE sy-ucomm,
      ls_data LIKE LINE OF gt_data.
  FIELD-SYMBOLS:  TYPE LINE OF LVC_T_FCAT.

  DATA(lo_tool) = NEW zcl_abap_blockchain_tool( blockdata ).
  DATA(lt_fieldcat) = lo_tool->get_fieldcat_by_data(ls_data).
  PERFORM change_label.
  CALL SCREEN 100.

DEFINE define_label.

  READ TABLE lt_fieldcat ASSIGNING  INDEX &1.
  -seltext = -reptext = -scrtext_m = -scrtext_s = -scrtext_l = & amp;2.
  -outputlen = & amp;3.

END-OF-DEFINITION.

FORM change_label.
  define_label 1 'Block Data' 20.
  define_label 2 'Hash' 40.
  define_label 3 'Nonce' 10.
  define_label 4 'Timestamp' 20.

ENDFORM.
FORM init_tree.
  g_alv_tree = lo_tool->get_tree( ).
  DATA l_hierarchy_header TYPE treev_hhdr.
  PERFORM build_hierarchy_header CHANGING l_hierarchy_header.
  CALL METHOD g_alv_tree->set_table_for_first_display
    EXPORTING
      is_hierarchy_header = l_hierarchy_header
    CHANGING
      it_fieldcatalog = lt_fieldcat
      it_outtab = gt_data.
  PERFORM create_tree.
  g_alv_tree->frontend_update( ).
  lo_tool->expand( ).
ENDFORM.
FORM create_tree.
  lo_tool->render_tree( ).
ENDFORM.
FORM build_hierarchy_header CHANGING p_hierarchy_header TYPE treev_hhdr.
  p_hierarchy_header-heading = 'BlockChain list'.
  p_hierarchy_header-width = 30.
  p_hierarchy_header-width_pix = ' '.
ENDFORM.

FORM exit_program.
  LEAVE PROGRAM.
ENDFORM.

MODULE pbo OUTPUT.
  SET PF-STATUS 'MAIN100'.
  SET TITLEBAR 'MAINTITLE'.
  IF g_alv_tree IS INITIAL.
    PERFORM init_tree.
    CALL METHOD cl_gui_cfw=>flush
      EXCEPTIONS
        cntl_system_error = 1
        cntl_error = 2.
    ASSERT sy-subrc = 0.
  ENDIF.
ENDMODULE.

MODULE pai INPUT.
  save_ok = ok_code.
  CLEAR ok_code.
  CASE save_ok.
    WHEN 'EXIT' OR 'BACK' OR 'CANC'.
      PERFORM exit_program.
    WHEN OTHERS.
      CALL METHOD cl_gui_cfw=>dispatch.
  ENDCASE.
  CALL METHOD cl_gui_cfw=>flush.
ENDMODULE.