合约调用合约?

听到这里读者可能会犯糊涂,什么?合约还能被合约调用吗?

是的,可以。

在以太坊中执行代码的一台虚拟机可以启动另一台虚拟机来执行部分指令。这两台虚拟机都将在一个挖矿节点上运行,形成多线程并行。这称之为“合约调用合约”。 常见的合约调用合约的场景,例如某合约在执行计算时候需要调用 SafeMath 之类的安全数学计算库,而该库早已用合约的形式部署在以太坊网络上。 则该合约可以通过直接调用SafeMath库合约为自己服务。整个调用过程如图 7-6 所示。

  • 在调用时发送方将发出 CALL的虚拟机指令,并将环境变量例如 msg.sender (合约调用者)等变量设置好。
  • 启动另一台虚拟机运行被调用方的代码,得出结果后通过 RETURN 虚拟机指令发还给调用方的内存区,完成调用过程。
../_images/Picture50.png

以太坊虚拟机合约调用合约,并返回值的过程

这里就有一个取舍:如果调用方在编译初期将库合约编译入自己的代码,则可以省去外部调用的步骤,节省每次调用的花费,但相应地自身代码的篇幅会变长。如果调用方在编译初期不将库合约编入自身代码,则保留了灵活性,将来改动库合约不会影响到调用方的代码。这点颇和 Windows 平台的动态链接库DLL有几分相似。在实际应用中,往往将简单的库函数打包进入自己的合约代码,减少对外调用的次数,增加安全性。