源代码如下:
*&---------------------------------------------------------------------*
*& 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 timestampl,
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: <field> 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 <field> INDEX &1.
<field>-seltext = <field>-reptext = <field>-scrtext_m = <field>-scrtext_s = <field>-scrtext_l = &2.
<field>-outputlen = &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.
代码解释如下:
首先,它定义了一个报告 ZBLOCKCHAIN
,该报告有两个参数 diffle
和 noblock
。 diffle
是一个五个字符的字符串,用于定义区块链的难度,而 noblock
是一个整数,用于定义区块链中区块的数量。
然后,它定义了一些数据对象,包括 blockdata
,它是一个表,用于存储区块链中的区块; blockdataline
,它代表一个区块,包含了区块的索引、数据、前一个区块的哈希值、时间戳和随机数; timestamp
是一个时间戳; combineddata
是一个字符串,用于存储区块的信息,并用于生成哈希值; prevblockdata
用于存储前一个区块的信息; nonce
是一个随机数,用于生成哈希值; noncestring
是 nonce
的字符串表示; flag
是一个标志,用于控制循环; difflength
是 diffle
的长度; gethash
是一个对象引用,用于生成哈希值。
接下来,它创建了创世区块,也就是区块链的第一个区块。创世区块的索引为 0,数据为 Jerry first Genesis block
,前一个区块的哈希值为 000000
,时间戳为当前时间,随机数为 0。然后,它将这些信息连接成一个字符串,然后调用 cl_abap_message_digest=>calculate_hash_for_char
方法生成哈希值,并将哈希值存储在 blockdataline-chash
中。最后,它将 blockdataline
添加到 blockdata
中。
接着,它创建了其余的区块。这是通过一个循环实现的,循环的次数是 noblock - 1
。在每次循环中,它首先设置区块的索引和数据,然后读取前一个区块的信息,将其哈希值设置为当前区块的 phash
,设置当前区块的时间戳,然后在一个内部循环中,生成随机数,连接区块的信息,生成哈希值,如果哈希值的前 difflength
个字符和 diffle
相等,那么就退出内部循环,将当前区块添加到 blockdata
中,否则,增加随机数,然后继续内部循环。