Aspect 编程

Aspect 编程引入了一种围绕连接点模型 (JPM) 构建的强大范式。该模型围绕三个关键组件展开:

aspect-programming-overview-0845bac66e004bb8535332fba714b500.png

Aspect 编程概述

为说明 Aspect 编程的工作原理,考虑一个包含大量存款的保险库智能合约。目标是在运行时保护智能合约,使其免受可能非法重定向存款的潜在威胁。一个 Aspect 示例被设计用于监督和验证智能合约执行后的保险库变更。如果检测到资金流动异常,此 Aspect 将取消可疑事务。此 Aspect 的执行在智能合约执行后、事务调用合约时启动。

Aspect 和Join Points

一个 Aspect 被设计为clas,是基础 Aspect 接口的扩展。它包含指示Join Points的方法,添加的逻辑可以在这些方法中交织。以下是一个示例:

class Aspect implements IPostTxExecuteJP {
/**
      * postTxExecute is a join-point invoked post the completion of transaction execution but prior to state commitment.
      *
      * @param ctx context of the designated join-point
      * @return outcome of the Aspect's execution
      */
    postTxExecute(input: PostTxExecuteInput): void {
        if (ethereum.parseMethodSig(ctx.tx.content.data) == ethereum.computeMethodSig('withdraw')) {
            const withdrawAmount = ...// extract withdraw amount from calldata via context.tx.content.data
            const vaultBalance = new VauleState(ctx, ctx.tx.content.to).get('vauleBalance').current();// state change wrapper class generated by aspect-tool
            if (vaultBalance != withdrawAmount) {
                sys.revert('Error: Balance discrepancy detected.');
            }
        }
    }
}

在上述示例中,postTxExecute 方法充当join point的入口,在 EVM 完成事务后发挥作用。

PostTxExecuteCtx 对象表示运行时上下文,提供了对原始事务及其在当前join point上的细节的洞察。它被传递给join point方法,促进其与正在进行的事务的交互。

示例 Aspect 在事务期间检查智能合约的 withdraw 函数的调用。如果被调用,事务参数中的预期提款金额将与保险库的实时资金流动进行交叉检查。发现差异(通常是编码错误或恶意攻击)时,Aspect 将激活 revert() 函数,通过运行时上下文的事务管理对象来撤销该事务。

部署与绑定

要将一个 Aspect 集成到区块链中,其字节码需要嵌入到一个部署事务中。这个事务与一个 Aspect 系统合约交互,将 Aspect 的字节码记录到区块链的全局状态中。这允许验证者访问字节码,使其在激活时能够执行 Aspect 的逻辑。

然而,一个 Aspect 只有在绑定到特定智能合约时才会启动。它需要智能合约所有者使用其外部拥有的账户 (EOA) 签署一个绑定事务 - 该账户应绕过智能合约的 isOwner(address) returns (bool) 方法的检查。这个事务包含智能合约地址和 Aspect ID,并在执行时涉及 Aspect 系统合约,将智能合约和 Aspect 在区块链的全局状态中绑定起来。这确保只有智能合约的合法所有者可以绑定 Aspect,防止任何未授权的绑定尝试。

在成功执行部署和绑定事务后,Aspect 被集成到区块链并绑定到智能合约中,增强了合约的功能并提高了其安全性。