Skip to content

Commit 232c853

Browse files
committed
add deploy_eth
1 parent 1229747 commit 232c853

File tree

5 files changed

+390
-0
lines changed

5 files changed

+390
-0
lines changed

2024/06/deploy_eth.md

Lines changed: 358 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,358 @@
1+
# [eth节点部署](/2024/06/deploy_eth.md)
2+
3+
## 创世区块
4+
5+
大致要部署两个模块(server) 一个是execution layer/client例如geth,reth 另一个是consensus layer/client例如prysm(go),lighthouse(rust)
6+
7+
```
8+
sudo add-apt-repository -y ppa:ethereum/ethereum
9+
sudo apt-get install `ethereum`
10+
# installed: abigen bootnode clef ethereum evm geth rlpdump
11+
```
12+
13+
eth网络的部署需要很多个进程很多的配置,好多报错我没部署起来,gpt4老用pow的配置文件教我部署eth导致报错 ` only PoS networks are supported, please transition old ones with Geth v1.13.x`
14+
15+
算了还是用 docker 部署吧
16+
17+
> error getting credentials - err: exec: "docker-credential-desktop.exe": executable file not found in $PATH
18+
19+
应该是之前docker desktop版本卸载后残留的问题 删掉 `~/.docker/config.json``"credsStore": "desktop.exe"`
20+
21+
```
22+
root@tokyo:~/eth-pos-devnet# docker-compose up
23+
WARN[0000] /root/eth-pos-devnet/docker-compose.yml: `version` is obsolete
24+
[+] Running 6/6
25+
✔ Container eth-pos-devnet-geth-remove-db-1
26+
✔ Container eth-pos-devnet-create-beacon-chain-genesis-1
27+
✔ Container eth-pos-devnet-beacon-chain-1
28+
✔ Container eth-pos-devnet-geth-genesis-1
29+
✔ Container eth-pos-devnet-geth-1
30+
✔ Container eth-pos-devnet-validator-1
31+
Attaching to beacon-chain-1, create-beacon-chain-genesis-1, geth-1, geth-genesis-1, geth-remove-db-1, validator-1
32+
create-beacon-chain-genesis-1 | time="2024-06-19T04:05:24Z" level=info msg="Specified a chain config file: /consensus/config.yml" prefix=genesis
33+
create-beacon-chain-genesis-1 | time="2024-06-19T04:05:24Z" level=fatal msg="Could not generate beacon(灯塔) chain genesis state" error="could not set config params: version 0x05000000 for fork electra in config interop conflicts with existing config named=mainnet: configset cannot add config with conflicting fork version schedule" prefix=genesis
34+
create-beacon-chain-genesis-1 exited with code 1
35+
geth-remove-db-1 exited with code 0
36+
```
37+
38+
https://github.com/OffchainLabs/eth-pos-devnet/issues/49
39+
40+
```
41+
root@tokyo:~/eth-pos-devnet# git diff consensus/
42+
diff --git a/consensus/config.yml b/consensus/config.yml
43+
index 372cd8f..3057ad1 100644
44+
--- a/consensus/config.yml
45+
+++ b/consensus/config.yml
46+
@@ -20,6 +20,8 @@ MAX_WITHDRAWALS_PER_PAYLOAD: 16
47+
48+
DENEB_FORK_VERSION: 0x20000093
49+
50+
51+
+ELECTRA_FORK_VERSION: 0x20000094
52+
```
53+
54+
主要是镜像用latest的锅,换成这个锁版本的 `https://github.com/ivy-net/eth-pos-devnet/tree/wn/lock-down-images` 就好了
55+
56+
所以minimal单节点的eth网络至少需要三个进程:
57+
- geth
58+
- beacon-chain
59+
- validator
60+
61+
- execution_client: Validates transactions and blocks
62+
- sonsensus_client: Determines which blocks are part of the chain
63+
64+
## geth console
65+
66+
```
67+
docker exec -it eth-pos-devnet-geth-1 /bin/sh
68+
geth attach http://localhost:8545
69+
```
70+
71+
### 列出所有钱包和最新一个区块有多少交易
72+
73+
```
74+
> eth.blockNumber
75+
1145
76+
> eth.getBlock(1145)
77+
{
78+
baseFeePerGas: 7,
79+
difficulty: 0,
80+
extraData: "0xd883010e06846765746888676f312e32322e34856c696e7578",
81+
gasLimit: 30000000,
82+
gasUsed: 0,
83+
hash: "0x371b783a6274552c0a7aef2bc9e4c3a97caac02128091de5277ab706638802a2",
84+
...
85+
}
86+
> eth.accounts
87+
["0x123463a4b065722e99115d6c222f267d9cabb524"]
88+
> eth.getBalance(eth.accounts[0])
89+
2e+22
90+
> personal.unlockAccount(eth.accounts[0])
91+
Unlock account 0x123463a4b065722e99115d6c222f267d9cabb524
92+
Passphrase:
93+
#初始地址不知道密码重新创建两个钱包算了
94+
> personal.newAccount()
95+
Passphrase:
96+
Repeat passphrase:
97+
"0x4Fc09F0c1a03E79c01B5b2E20624a4229f73372b"
98+
> personal.newAccount()
99+
Passphrase:
100+
Repeat passphrase:
101+
"0xC692CafEce97dBfcB7D41dBa05aF3f77AF61d543"
102+
> eth.accounts
103+
["0x123463a4b065722e99115d6c222f267d9cabb524", "0x4fc09f0c1a03e79c01b5b2e20624a4229f73372b", "0xc692cafece97dbfcb7d41dba05af3f77af61d543"]
104+
> a1="0x4Fc09F0c1a03E79c01B5b2E20624a4229f73372b"
105+
"0x4Fc09F0c1a03E79c01B5b2E20624a4229f73372b"
106+
> a2="0xC692CafEce97dBfcB7D41dBa05aF3f77AF61d543"
107+
"0xC692CafEce97dBfcB7D41dBa05aF3f77AF61d543"
108+
> eth.sendTransaction({from:a1, to:a2, value:1000})
109+
Error: insufficient funds for transfer
110+
at web3.js:6387:9(39)
111+
at send (web3.js:5116:62(29))
112+
at <eval>:1:20(9)
113+
```
114+
115+
### admin api
116+
117+
docker inspect 7e6229b8a41c | grep md -A18
118+
119+
原来 eth-pos-devnet repo 默认没有开权限 于是我改了下 docker compose yml 就好了
120+
121+
```
122+
> admin.nodeInfo
123+
{
124+
enode: "enode://4e62f4038eb7c1292af7c1b608a201210afb81f11b1a7d1cc07d51120a7400930c75ac10be146bd4c77da2b2faa7a0c65feecac43565938096550841a95e92ce@127.0.0.1:30303?discport=0",
125+
enr: "enr:-Jy4QB-WY96O_O-Bcu3-PXsPljKJgjIxciwipw1zNfFqGWnKUvP7F0rYCgv8eiYyVcJZhUBH2RWTqPiv883Ue8_6xK-GAZAw7SXlg2V0aMfGhPfMbZGAgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQJOYvQDjrfBKSr3wbYIogEhCvuB8RsafRzAfVESCnQAk4RzbmFwwIN0Y3CCdl8",
126+
id: "a5f3e3921729be2b81a7696bc3c1bf338c5be9acd4a0a7426019ecd0011ca7cd",
127+
ip: "127.0.0.1",
128+
listenAddr: "[::]:30303",
129+
name: "Geth/v1.14.3-stable-ab48ba42/linux-amd64/go1.22.3",
130+
...
131+
}
132+
> admin.peers
133+
```
134+
135+
### metamask连local network
136+
137+
metamask 添加自定义网络只需要chainId和一个 rpc url 也就是 http://localhost:8545 我把wsl的docker端口用vscode remote port forward映射出来 通过 eth.chainId(用于区分不同的以太坊网络例如主网/测试网) 获取到16进制的链id转换成32382十进制
138+
139+
由于创世区块中验证者节点绑定的钱包密码我不知道是多少,不知道密码也能调用交易api转账,但添加进metamask是需要密码的所以得重新创建几个钱包
140+
141+
- The network launches with a Validator Deposit Contract deployed at address 0x4242424242424242424242424242424242424242. This can be used to onboard new validators into the network by depositing 32 ETH into the contract
142+
- The default account used in the go-ethereum node is address 0x123463a4b065722e99115d6c222f267d9cabb524 which comes seeded with ETH for use in the network. This can be used to send transactions, deploy contracts, and more
143+
- The default account, 0x123463a4b065722e99115d6c222f267d9cabb524 is also set as the fee recipient for transaction fees proposed validators in Prysm. This address will be receiving the fees of all proposer activity
144+
145+
```
146+
> eth.chainId()
147+
"0x7e7e"
148+
```
149+
150+
#### 1ether=10**9Gwei=10**18wei
151+
152+
execution/genesis.json
153+
154+
```
155+
"alloc": {
156+
"123463a4b065722e99115d6c222f267d9cabb524": {
157+
"balance": "0x43c33c1937564800000"
158+
},
159+
}
160+
161+
>>> 0x43c33c1937564800000 * 10 ** -18
162+
20000.0
163+
```
164+
165+
验证者节点的钱包有两万个eth,所有交易的gas费都收到这个钱包里面
166+
167+
#### 创建钱包并转账
168+
169+
```
170+
> personal.newAccount()
171+
Passphrase:
172+
Repeat passphrase:
173+
"0x4Fc09F0c1a03E79c01B5b2E20624a4229f73372b"
174+
> eth.sendTransaction({from:eth.accounts[0], to:eth.accounts[1], value:web3.toWei(1000, "ether")})
175+
"0x97d097214b4ab4e162476ec7c3bd2f57ab0bd8b522237bfd95e2b69696c2f839"
176+
> eth.getTransaction(_)
177+
```
178+
179+
于是创建出钱包密钥json文件 eth-pos-devnet/execution/keystore/UTC--2024-06-19T15-42-56.835783384Z--4fc09f0c1a03e79c01b5b2e20624a4229f73372b
180+
181+
> {"address":"4fc09f0c1a03e79c01b5b2e20624a4229f73372b","crypto":{"cipher":"aes-128-ctr","ciphertext":"6f2aa8eea55e6549d2ff32d65fe52e3d139aacbb7d13a382958ec1bb54ac39b6","cipherparams":{"iv":"6c9b1240c5eea46e9fed00454f212ae4"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"b2b07aaec4e4a2d732ffbc747e75c7350cb995446ff27366209b51bc8e56935e"},"mac":"3c7f72a0e455f7daff048732dc928069cc1cd667748837d704a393729c5b3984"},"id":"b7081a79-773e-4c88-94cc-050cf73840ce","version":3}
182+
183+
上传json文件和passphrase就能将钱包导入到metamask的local network中了
184+
185+
![](metamask_local_network_1000eth.png)
186+
187+
## eth tx数据格式
188+
189+
![](metamask_tx_detail.png)
190+
191+
```
192+
> eth.getTransaction('0xbbe98d6c2dd7340238768203cc5ffc4dcceaa2d46ff297e1887f718aa4f2649a')
193+
{
194+
# 用于 EIP-2930 中的交易类型,指定交易中访问的地址和存储键,以减少 Gas 消耗
195+
accessList: [],
196+
blockHash: "0x5d73c1ff6faa50b0f2ec31ee2fc84dfe6b3b9cde97347b54a011c503ae74ef77",
197+
blockNumber: 1332,
198+
chainId: "0x7e7e",
199+
from: "0x4fc09f0c1a03e79c01b5b2e20624a4229f73372b",
200+
# 交易中指定的最大 Gas 限额
201+
gas: 21000,
202+
# 每单位 Gas 的价格 1gwei
203+
gasPrice: 1000000007,
204+
hash: "0xbbe98d6c2dd7340238768203cc5ffc4dcceaa2d46ff297e1887f718aa4f2649a",
205+
# 智能合约调用的入参 0x 表示没有入参
206+
input: "0x",
207+
# 交易中指定的每单位 Gas 的最大费用(单位为 Wei),用于 EIP-1559 交易
208+
maxFeePerGas: 1000000007,
209+
# 交易中指定的每单位 Gas 的最大优先费用(单位为 Wei),用于 EIP-1559 交易
210+
maxPriorityFeePerGas: 1000000007,
211+
# 发送方账户的交易计数器,确保交易的唯一性和顺序
212+
nonce: 0,
213+
# 交易签名的一部分
214+
r: "0x8a6b9631770a5136534481643de71cd9e8520819f6e0ff476f4fde6bcb8df3a7",
215+
# 交易签名的一部分
216+
s: "0x6f8a5e89569c391a5c2384fd5ea693c6c09320fc6c9bc5af1c54e911ee01d8a4",
217+
to: "0x123463a4b065722e99115d6c222f267d9cabb524",
218+
# 交易在区块中的索引,一个区块可以包含多个tx
219+
transactionIndex: 0,
220+
# 0x2 表示 EIP-1559 交易
221+
type: "0x2",
222+
# 交易签名的一部分,表示恢复 ID
223+
v: "0x1",
224+
# 转账的eth数量单位wei
225+
value: 50000000000000000000,
226+
# 用于 EIP-1559 交易的额外签名字段
227+
yParity: "0x1"
228+
}
229+
# 要调用转账收据接口才能获取实际花了多少gas
230+
> eth.getTransactionReceipt('0xbbe98d6c2dd7340238768203cc5ffc4dcceaa2d46ff297e1887f718aa4f2649a')
231+
{
232+
blockHash: "0x5d73c1ff6faa50b0f2ec31ee2fc84dfe6b3b9cde97347b54a011c503ae74ef77",
233+
blockNumber: 1332,
234+
contractAddress: null,
235+
cumulativeGasUsed: 21000,
236+
effectiveGasPrice: 1000000007,
237+
from: "0x4fc09f0c1a03e79c01b5b2e20624a4229f73372b",
238+
gasUsed: 21000,
239+
logs: [],
240+
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
241+
status: "0x1",
242+
to: "0x123463a4b065722e99115d6c222f267d9cabb524",
243+
transactionHash: "0xbbe98d6c2dd7340238768203cc5ffc4dcceaa2d46ff297e1887f718aa4f2649a",
244+
transactionIndex: 0,
245+
type: "0x2"
246+
}
247+
248+
> eth.getBlock(1332)
249+
{
250+
# 基础 Gas 费率
251+
baseFeePerGas: 7,
252+
# Represents the amount of gas used for blob transactions in the block. Blobs are a feature related to data availability in the Ethereum protocol.
253+
blobGasUsed: 0,
254+
# (deprecated)
255+
difficulty: 0,
256+
# The excess gas used for blob transactions beyond the base level
257+
excessBlobGas: 0,
258+
# 额外数据,可以包含任意信息,通常由矿工或验证者添加
259+
extraData: "0xd883010e03846765746888676f312e32322e33856c696e7578",
260+
# 当前区块的最大 Gas 限额。这个值限制了区块中可以包含的最大 Gas 数量
261+
gasLimit: 30000000,
262+
# 当前区块中已经使用的 Gas 数量
263+
gasUsed: 21000,
264+
hash: "0x5d73c1ff6faa50b0f2ec31ee2fc84dfe6b3b9cde97347b54a011c503ae74ef77",
265+
# 日志布隆过滤器,用于快速查找区块中的事件日志
266+
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
267+
miner: "0x123463a4b065722e99115d6c222f267d9cabb524",
268+
# A hash used in the mining process to prove that a sufficient amount of computation has been done.
269+
mixHash: "0x7b139e6541c9a8f5fd325a51da53aeb96a834600d80b9cfbe5f9e91832f2a45f",
270+
# (deprecated)A value used in the mining process to find a hash that meets the difficulty target
271+
nonce: "0x0000000000000000",
272+
number: 1332,
273+
parentBeaconBlockRoot: "0xd26b91bf37086ac925e4bffc359f6db8bc78c0ad9d9f7b0a052cf1132be4285c",
274+
parentHash: "0x45504d2c5e71811a8d27e5b52ff4099f6125d1c239bae1868d96bb3193f43482",
275+
# The root of the receipts trie of the block, which is a cryptographic commitment to all the receipts of the transactions in the block.
276+
receiptsRoot: "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa",
277+
# The SHA3 hash of the uncles data in the block
278+
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
279+
# The size of the block in bytes
280+
size: 731,
281+
# The root of the state trie of the block, which is a cryptographic commitment to the state of all accounts.
282+
stateRoot: "0x2accd9532755a6603103e5a91d30daf05468f1b2b52954d5bf1eb124b7916613",
283+
timestamp: 1718813646,
284+
totalDifficulty: 1,
285+
transactions: ["0xbbe98d6c2dd7340238768203cc5ffc4dcceaa2d46ff297e1887f718aa4f2649a"],
286+
transactionsRoot: "0x14657e3e4926c1bcb0ae3acbde958b8f0a7bd43d787895ed273af50ed95229b6",
287+
# An array of uncle block hashes included in this block
288+
# 未能成为主链一部分的有效区块。由于以太坊的区块生成速度较快,有时会出现多个矿工几乎同时挖出区块的情况。这些区块中只有一个能成为主链的一部分,其他的则成为叔块
289+
uncles: [],
290+
# An array of withdrawals included in this block
291+
# 验证者可以将他们的eth质押到信标链上以帮助保护网络。withdrawals 字段包含了从质押合约中提取的记录
292+
withdrawals: [],
293+
withdrawalsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
294+
}
295+
```
296+
297+
### Orphan Blocks
298+
btc orphan blocks类似eth uncles也是因为最长链原则或数据竞争导致未能合并到主链的有效区块,区别就是eth的验证者产出uncles也会得到奖励而btc没奖励
299+
300+
### eth stateRoot
301+
302+
`stateRoot` 是以太坊区块头中的一个重要字段,但它不仅仅是所有钱包余额的哈希摘要。它实际上是整个以太坊状态的一个Merkle Patricia树的根哈希。让我们详细解释一下:
303+
304+
### 如何分析交易有没有调用智能合约
305+
306+
- to: "0x123463a4b065722e99115d6c222f267d9cabb524":需要进一步确认这个地址是否是智能合约地址。如果这个地址是一个普通的以太坊地址,那么这可能是一个普通的ETH转账
307+
- input: "0x":input 字段为空,表示没有附加数据。这通常意味着这是一笔普通的ETH转账,而不是调用智能合约
308+
- gasUsed: 21000:消耗的gas正好是 21,000,这是一个普通ETH转账的标准gas费用
309+
310+
列出所有智能合约地址需要遍历区块链中的所有账户地址,并检查每个地址是否包含代码
311+
312+
- 检查是不是合约 **eth.getCode(addr)!="0x"**
313+
- 检查是不是钱包 eth.getBalance 或 eth.getTransactionCount(获取nonce)
314+
315+
### 以太坊状态(State)
316+
317+
以太坊状态包括以下几个方面:
318+
1. **账户余额**:每个账户的以太币余额。
319+
2. **账户的存储数据**:智能合约账户的存储数据。
320+
3. **账户的代码**:智能合约账户的代码。
321+
4. **账户的nonce**:每个账户的交易计数器,用于防止重放攻击。
322+
323+
#### Merkle Patricia 树
324+
325+
以太坊使用一种叫做Merkle Patricia树的数据结构来存储整个状态。Merkle Patricia树是一种混合数据结构,结合了Merkle树和Patricia树的特点。它具有以下优点:
326+
- **高效的验证**:Merkle树的特性使得我们可以高效地验证某个数据是否包含在树中。
327+
- **紧凑的存储**:Patricia树的特性使得我们可以高效地存储和检索数据。
328+
329+
#### stateRoot
330+
331+
`stateRoot` 是当前区块中整个以太坊状态的Merkle Patricia树的根哈希。它不仅仅是所有账户余额的哈希,而是整个状态的哈希。具体来说,它包含了以下内容的哈希:
332+
- 所有账户的余额
333+
- 所有账户的存储数据
334+
- 所有账户的代码
335+
- 所有账户的nonce
336+
337+
`stateRoot` 是当前以太坊区块中整个状态的一个Merkle Patricia树的根哈希。它不仅包含了所有账户的余额,还包括了账户的存储数据、代码和nonce。因此,它是整个以太坊状态的一个完整的哈希摘要,而不仅仅是钱包余额的哈希。
338+
339+
## 总结下常用的api
340+
341+
|api|作用|
342+
|---|---|
343+
|admin.nodeInfo|
344+
|admin.peers|
345+
|admin.dataDir|获取存放密钥等数据的路径|
346+
|eth.chainId|metamask添加自定义网络需要|
347+
|eth.accounts|
348+
|web3.fromWei(amount, 'ether')|将eth.getBalance的返回值转为eth|
349+
|web3.fromWei(amount, 'ether')|将eth.getBalance的返回值转为eth|
350+
351+
352+
## eth的rust生态
353+
354+
- execution_client: reth(包含revm?)
355+
- consensus_client: lighthouse
356+
- rpc/api_sdk: https://github.com/alloy-rs/alloy
357+
358+
另外经典的mev(solidity)实现: https://github.com/libevm/subway
104 KB
Loading

2024/06/metamask_tx_detail.png

12.5 KB
Loading

2024/06/mev.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# [MEV](/2024/06/mev.md)
2+
3+
一些layer1的量化方式 我记得lxdao有个朋友的博士课题是跟滑点相关,估计有很多滑点相关的套利策略 量化策略吧?
4+
我了解到的关键词有DEX高滑点埋伏,afterrunning,sandwich attacks等
5+
6+
<https://x.com/LXDAO_Official/status/1803032424395501699>
7+
8+
> 跨链 MEV 捕获,最小价值流失
9+
10+
[flashbot](https://foresightnews.pro/article/detail/42395)
11+
12+
[how to prevent prevent bribery - flashbot issue](https://github.com/flashbots/mev-boost/issues/111)
13+
14+
> Flashbots 的核心基础设施是中继器(relay),其作用是收集来自不同参与者网络的交易包,并将它们转发给矿工。中继器可以验证交易的有效性,防止恶意交易的出现。同时,中继器还能帮助矿工更好地利用 MEV,从而提高他们的收益
15+
16+
https://www.jito.wtf/ SOL贿赂验证者
17+
18+
19+
老板想问链上做什么 能盈利的
20+
aptos MEV
21+
如果aptos的MEV不赚钱就转成juipier那样的聚合器赚价差 大单拆分后出现价差套利 然后应用做火了要aptos基金会的钱
22+
dev获利
23+
借贷协议套利
24+
25+
26+
## 工作安排
27+
学习eth经典MEV实现subway的三种池子算法:uniswapV2,V3,稳定币池子
28+
不一定要部署aptos全节点,用rpc也可以,全节点是为了优化获取mempool
29+
去bsc/l2/evm去测试,不交易,只发现价差
30+
下单机,研究uniswap怎样下单,怎样计算

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
- [文章列表 - 吴翱翔的博客](/)
22
- [正在读的书](/books.md)
33
- **2024-06**
4+
- [MEV](/2024/06/mev.md)
5+
- [eth节点部署](/2024/06/deploy_eth.md)
46
- [python导入路径不同类id不同](2024/06/python3_same_class_different_import_path_class_id_not_same.md)
57
- [暗黑4评测](/2024/06/diablo4_review.md)
68
- [做市商对冲](/2024/06/market_maker_hedge.md)

0 commit comments

Comments
 (0)