本文介绍了如何创建 Uniswap V4 的第一个Hook,包括必需的库、合约结构和安全风险等内容。通过逐步引导,读者可以了解到如何实现自定义流动性池行为以及注意事项,并给出了完整的Hook模板代码。

你好,勇敢的 DeFi 探险者!所以你听说了这些新颖的 Uniswap V4 hooks,并且想:“嘿,我可能也可以做一个!”好了,系好安全带,因为我们即将踏上探索自定义流动性池行为的刺激之旅。别担心,我会成为你的可信赖向导,我们一起完成这段旅程!
在我们深入代码之前,让我们谈谈这次旅程中需要准备的东西。你可能在想:“我需要什么来开始?”好问题!以下是我们的基本装备:
Hooks 库:
把它想象成你的瑞士军刀。它具有定义你的 hook 能做什么的各种工具。
BEFORE_SWAP_FLAG、AFTER_SWAP_FLAG),以及用于验证和调用 hooks 的函数。PoolKey 和 PoolId:
这些就像你的地图和指南针。它们帮助你在广阔的流动性池中导航。
PoolKey 是一个结构,唯一标识一个池,而 PoolId 是 PoolKey 的更节能的表示。Currency 库:
这是你的通用翻译器,帮助你与原生代币(如 ETH)和 ERC20 代币进行交流。
BaseHook 合约:
把它看作是你的帐篷——一个坚实的基础来搭建并庇护你免受智能合约开发的恶劣环境。
“但等等,”你可能会问,“我真的需要所有这些吗?”相信我,每个部分在你的 hook 创作冒险中都扮演着至关重要的角色。让我们建立我们的基础营地,看看这一切是如何结合在一起的!
首先,让我们创建我们的 hook 合约。下面是我们将要开始的基本结构:
import {BaseHook} from "@uniswap/v4-periphery/contracts/BaseHook.sol";
import {Hooks} from "@uniswap/v4-core/contracts/libraries/Hooks.sol";
import {IPoolManager} from "@uniswap/v4-core/contracts/interfaces/IPoolManager.sol";
import {PoolKey} from "@uniswap/v4-core/contracts/types/PoolKey.sol";
import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/contracts/types/PoolId.sol";
import {Currency, CurrencyLibrary} from "@uniswap/v4-core/contracts/types/Currency.sol";
import {FixedPointMathLib} from "solmate/src/utils/FixedPointMathLib.sol";
contract MyAwesomeHook is BaseHook {
    using StateLibrary for IPoolManager;
    using PoolIdLibrary for PoolKey;
    using CurrencyLibrary for Currency;
    using FixedPointMathLib for uint256;
    constructor(IPoolManager _poolManager) BaseHook(_poolManager) {}
    // 更多激动人心的内容在后面!
}让我们分析这些 ‘using’ 语句并理解它们的意义:
using StateLibrary for IPoolManager;:这使得与池状态的高效交互成为可能。它允许你直接在 IPoolManager 对象上调用 StateLibrary 函数,简化池流动性或交换数据的查询等操作。using PoolIdLibrary for PoolKey;:这简化了 PoolKey 结构与 PoolId 之间的转换。它对需要识别特定池的操作非常关键,例如,将 hooks 指向特定交易对。using CurrencyLibrary for Currency;:这一语句增强了你与不同代币类型一致交互的能力。它使得可以直接在 Currency 对象上使用 CurrencyLibrary 函数,从而简化代币转账、余额检查和其他代币相关操作。using FixedPointMathLib for uint256;:这提供了对精确数学操作的访问,对于 DeFi 应用至关重要。它允许你对 uint256 数字进行定点运算,这对于准确的价格计算、费用计算和其他财务操作至关重要。这些 ‘using’ 语句是编写高效、可读和节省 gas 的 hook 代码的关键。它们提供了语法糖,使得你在处理这些复杂的 DeFi 概念时,能够编写更直观的代码。
接下来,我们需要告诉 Uniswap 我们的 hook 可以做什么。这就像为你的露营活动填写许可证:
function getHookPermissions() public pure override returns (Hooks.Permissions memory) {
    return Hooks.Permissions({
        beforeInitialize: false,
        afterInitialize: false,
        beforeAddLiquidity: false,
        afterAddLiquidity: false,
        beforeRemoveLiquidity: false,
        afterRemoveLiquidity: false,
        beforeSwap: false,
        afterSwap: false,
        beforeDonate: false,
        afterDonate: false,
        beforeSwapReturnDelta: false,
        afterSwapReturnDelta: false,
        afterAddLiquidityReturnDelta: false,
        afterRemoveLiquidityReturnDelta: false
    });
}现在,你可能会摸着头思考:“等一下,我们真的需要这个函数吗?我以为 Uniswap 会根据合约地址来判断使用哪个 hook。”
你说得没错,机智的露营者!Uniswap 确实会根据合约地址来决定调用哪个 hooks。这个 getHookPermissions() 函数更像是我们人类的“视觉辅助”。它帮助开发者(例如我们)快速查看 hook 应该做什么,而无需深入底层地址分析的细节。
你可能在想:“那么,我应该麻烦实现这个吗?”答案是肯定的!虽然它对 Uniswap 的操作不是严格必要,但对于其他开发者(包括你未来的自己)来说,它非常有用,可以更快速地了解你的代码。
要使用一个 hook,你需要将对应的权限设置为 true。例如,如果你希望你的 hook 在交换前后执行一些操作,你可以将 beforeSwap 和 afterSwap 设置为 true。
Uniswap 如何从合约地址读取这些权限的复杂性是一个有趣的话题,但这就像高级野外生存技巧——我们会将其留到另一次探险中。现在,让我们专注于搭建我们的基本营地!
现在是有趣的部分——让我们添加一些自定义行为!我们将实现 beforeSwap 函数:
function beforeSwap(address sender, PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata data)
    external
    override
    returns (bytes4)
{
    // 你的魔法在这里实现!
    console.log("啊,有一笔交易即将发生,来自", sender);
    // 不要忘记这部分!
    return BaseHook.beforeSwap.selector;
}“那句 return 语句怎么回事?”你问?好眼力!那是在告诉 Uniswap,“是的,我们做了我们的事情,你可以继续了。”
恭喜你,勇敢的开发者!你刚刚创建了自己的第一个 Uniswap V4 hook。但你怎么实际使用它呢?好问题!
beforeSwap 函数将会被执行!在我们结束这次冒险之前,让我们谈谈在你开发 hooks 时需要注意的一些重要事项。即使在这个早期阶段,意识到潜在的陷阱和安全风险也是至关重要的:
记住,在 DeFi 中,你的操作涉及到真正的价值。代码中的小错误可能会导致重大的财务损失。始终谨慎行事,并不断学习安全最佳实践。
恭喜你!你刚刚迈出了进入 Uniswap V4 hooks 世界的第一步。让我们回顾一下你所取得的成就:
getHookPermissions() 函数,这是定义你的 hook 能力的关键。beforeSwap 函数,作为你 hook 逻辑的起点。为了帮助你快速上手,这里有你第一个 Uniswap V4 hook 的完整模板。你可以将其复制粘贴到你的开发环境中,作为起始点:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {BaseHook} from "@uniswap/v4-periphery/contracts/BaseHook.sol";
import {Hooks} from "@uniswap/v4-core/contracts/libraries/Hooks.sol";
import {IPoolManager} from "@uniswap/v4-core/contracts/interfaces/IPoolManager.sol";
import {PoolKey} from "@uniswap/v4-core/contracts/types/PoolKey.sol";
import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/contracts/types/PoolId.sol";
import {Currency, CurrencyLibrary} from "@uniswap/v4-core/contracts/types/Currency.sol";
import {FixedPointMathLib} from "solmate/src/utils/FixedPointMathLib.sol";
contract MyAwesomeHook is BaseHook {
    using PoolIdLibrary for PoolKey;
    using CurrencyLibrary for Currency;
    using FixedPointMathLib for uint256;
    constructor(IPoolManager _poolManager) BaseHook(_poolManager) {}
    function getHookPermissions() public pure override returns (Hooks.Permissions memory) {
        return Hooks.Permissions({
            beforeInitialize: false,
            afterInitialize: false,
            beforeAddLiquidity: false,
            afterAddLiquidity: false,
            beforeRemoveLiquidity: false,
            afterRemoveLiquidity: false,
            beforeSwap: true,
            afterSwap: false,
            beforeDonate: false,
            afterDonate: false,
            beforeSwapReturnDelta: false,
            afterSwapReturnDelta: false,
            afterAddLiquidityReturnDelta: false,
            afterRemoveLiquidityReturnDelta: false
        });
    }
    function beforeSwap(address sender, PoolKey calldata key, IPoolManager.SwapParams calldata params, bytes calldata data)
        external
        override
        returns (bytes4)
    {
        // 你的自定义逻辑在这里实现
        console.log("交易发起者是", sender);
        return BaseHook.beforeSwap.selector;
    }
}这个模板包括所有必要的导入、基本合约结构和 beforeSwap hook 的简单实现。你可以根据需要对其进行修改和扩展,探索更复杂的 hook 行为。
在这里,可能性是巨大的:
beforeSwap 函数。afterSwap 或 beforeAddLiquidity,以影响交易的不同方面。Uniswap V4 生态系统是你可以探索和塑造的。你的下一个步骤可能会引领去涉及去中心化金融的下一个重大突破!
你接下来将构建什么?
https://www.linkedin.com/in/carlos-vendrell-felici/
https://github.com/ZealynxSecurity

- 原文链接: medium.com/@bloqarl/how-...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
 
                如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!