时间:2022-04-28 16:19:25
函数在定义后,可以通过调用的方式,让当前代码跳转到被调用的函数中进行执行,调用前的函数局部变量都会被保存起来不会丢失,被调用的函数运行结束后,恢复到调用函数的下一行继续执行代码,之前的局部变量也能继续访问。函数内的局部变量只能在函数体中使用,函数调用结束后,这些局部变量都会被释放并且失效。
实际实现中,我们把跨合约调用涉及到的合约,放到一个工程下,根据规则修改合约的包结构,删除不需要的文件。然后生成初始化代码,把涉及到的合约对象放到Map中,在执行跨合约调用时,从Map中取出对应的合约执行相应的方法即可。编译生成一个可执行文件,并在Docker中执行该文件。
写代码时,对有重复利用价值的功能代码模块可以抽象出函数(包括抽象出函数参数和返回值)。在调用点调用时,可以想象为适当处理好函数参数和返回值后,将函数体扩充到该位置。递归调用也是如此,就是将自己的函数体扩充到自己的调用点(可能也有参数迭代)。
这里以目前相对较新的抽取壳为例,回顾上文代码方法调用和代码加载的章节,不论加固的抽取和还原方法如何,最终还是要回到解释执行的(至少在JIT之前),因为加密的代码在安装时并没有被AOT优化。而且为了保证原始代码逻辑不变,对应加密方法在实际运行之前肯定需要被正确解密还原。
注意:如果在通过底层函数delegatecall发起调用时需要访问存储中的变量,那么这两个合约的存储布局需要一致,以便被调用的合约代码可以正确地通过变量名访问合约的存储变量。这不是指在库函数调用(高级的调用方式)时所传递的存储变量指针需要满足那样情况。