Page 155 - 《软件学报》2021年第6期
P. 155

韩宁  等:以太坊中间语言的可执行语义                                                              1729


                 足时抛出异常;
             (6)  函数 transferFrom:从指定账户 from 向指定账户 to 转移数量为 amount 的代币,若账户 from 不允许本
                 账户提取额度 amount、from 余额不足或账户 to 接受数量为 amount 的代币会引起溢出,则抛出异常.

         6.2   代币合约的形式化及类型检查
             本节在 Isabelle/HOL 中对 MyToken 代币合约进行形式化建模,并利用已形式化的类型检查函数对其进行
         类型检查.代币合约的形式化代码 mytoken_code 如下所示,该代码由 1 段派遣程序(dispatcher)、6 个接口函数、
         13 个辅助函数的形式化构成:
             definition mytoken_code::block where
               “mytoken_code=Blk(dispatch_logic_my_token@[total_supply_func,...,(*函数定义*),...,log_func])”
             派遣程序是由 if 表达式和 switch 表达式组成的表达式列表,如下所示,其主要功能是根据用户调用合约时
         所提供的输入数据将调用转到合约中具体的接口函数.
             1.   definition dispatch_logic_my_token::“expr list” where
             2.      “dispatch_logic_my_token=[
             3.         EIf (EFunCall b_gt_id[EFunCall b_callvalue_id[ ],lit_zero]) (Blk[revert_zz_call]),
             4.         ESwitch (EFunCall f_selector_id[ ])
             5.            [
             6.               (((NL 0x095ea7b3):L U256),
             7.                  Blk[(EFunCall f_approve_id
             8.                     [EFunCall f_decode_as_address_id[lit_zero],EFunCall f_decode_as_uint_id[lit_one]])]),
             9.               …
             10.             (((NL 0xa9059cbb):L U256),
             11.                 Blk[(EFunCall f_transfer_id
             12.                   [EFunCall f_decode_as_address_id[lit_zero],EFunCall f_decode_as_uint_id[lit_one]])]),
             13.          ]
             14.          (Some (Blk[revert_zz_call]))
             15.    ]”
             该部分(形式化)代码首先判断调用合约时是否存在以太坊原生数字货币的转账.由于代币合约管理代币而
         非以太坊原生数字货币,故不接受原生数字货币转账,当该转账数额大于 0 时,使合约异常终止,回滚状态(第 3
         行).若无原生数字货币转移发生,则正式进入派遣逻辑,利用 selector 函数得到全局状态中交易输入数据 input
         的前 4 个字节,并把该 4 个字节作为 switch 表达式中的变量表达式(第 4 行),利用变量表达式分别与 switch 中各
         个匹配项进行匹配:匹配成功,则执行该匹配项中的代码;否则,执行默认项中的代码.每个匹配项中的常量值(如
         第 6 行的 0x095ea7b3)为对应函数签名的哈希值,这是对 Solidity 语言实现中所用约定的反映.实际上,使用 Yul
         语言直接编写合约,不一定遵循该规范进行.
             在 Isabelle/HOL 中执行代码块类型检查函数 type_b 所得结果“True”表明,MyToken 合约为良类型,即该合
         约的派遣程序以及所有函数定义均满足类型规则.
                            value “type_b [] {} fte_blk_mytoken mytoken_code”  结果:(“True”:: “bool”)

         6.3   接口函数执行的模拟
             本节演示 MyToken 合约在 Isabelle/HOL 中按照小步语义的执行,具体考虑用户输入引起合约中 transfer_
         func 函数执行的情况.
             定义初始全局栈 gstk_token_contract,其中:唯一的全局栈帧含有全局状态 gs_init 和一局部栈;唯一的局部
         栈帧含有 MyToken 合约代码 mytoken_code.
   150   151   152   153   154   155   156   157   158   159   160