@@ -15,6 +15,41 @@ timezone: UTC+8
1515## Notes
1616
1717<!-- Content_START -->
18+ # 2025-08-18
19+
20+ 部署交易池
21+ 在 Uniswap V3 中,通过合约 UniswapV3Pool 来定义一个交易池子,Uniswap 最核心的交易功能在最底层就是调用了该合约的 swap 方法。
22+ 而不同的交易对,以及不同的费率和价格区间(后面会具体讲到 tickSpacing)都会部署不同的 UniswapV3Pool 合约实例来负责交易。部署交易池则是针对某一对 token 以及指定费率的和价格区间来部署一个对应的交易池,当部署完成后再次出现同样条件下的交易池则不再需要重复部署了。
23+ 部署交易池调用的是 NonfungiblePositionManager 合约的 createAndInitializePoolIfNecessary,参数为:
24+ - token0:token0 的地址,需要小于 token1 的地址且不为零地址;
25+ - token1:token1 的地址;
26+ - fee:以 1,000,000 为基底的手续费费率,Uniswap v3 前端界面支持四种手续费费率(0.01%,0.05%、0.30%、1.00%),对于一般的交易对推荐 0.30%,fee 取值即 3000;
27+ - sqrtPriceX96:当前交易对价格的算术平方根左移 96 位的值,目的是为了方便合约中的计算。
28+ 代码为:
29+ /// @inheritdoc IPoolInitializer
30+ function createAndInitializePoolIfNecessary(
31+ address token0,
32+ address token1,
33+ uint24 fee,
34+ uint160 sqrtPriceX96
35+ ) external payable override returns (address pool) {
36+ require(token0 < token1);
37+ pool = IUniswapV3Factory(factory).getPool(token0, token1, fee);
38+
39+ if (pool == address(0)) {
40+ pool = IUniswapV3Factory(factory).createPool(token0, token1, fee);
41+ IUniswapV3Pool(pool).initialize(sqrtPriceX96);
42+ } else {
43+ (uint160 sqrtPriceX96Existing, , , , , , ) = IUniswapV3Pool(pool).slot0();
44+ if (sqrtPriceX96Existing == 0) {
45+ IUniswapV3Pool(pool).initialize(sqrtPriceX96);
46+ }
47+ }
48+ }
49+
50+ 逻辑非常直观,首先将 token0,token1 和 fee 作为三元组取出交易池的地址 pool,如果取出的是零地址则创建交易池然后初始化,否则继续判断是否初始化过(当前价格),未初始化过则初始化。
51+ 我们分别看创建交易池的方法和初始化交易池的方法。
52+
1853# 2025-08-17
1954
2055区块链就像黑匣子一样是封闭的,无法与外部世界影响,智能合约本身也完全无法连接链下数据。对于现实世界中的例如:天气、比赛分数以及航班信息等都无法获取,这也是智能合约最大的痛点,极大地限制了智能合约开发者的创造力,那么有什么办法可以解决呢?
0 commit comments