0%

ganache | 简介

ganache 可以分叉 evm 链。

为什么要分叉 evm 链

有的时候,我们需要部署合约,然后进行测试,来判断合约的有效性。

但是,我们为什么不部署在测试网呢?

这是因为,如果我们要部署闪电贷之类的合约,肯定要依附于 dex 的各种数据,但是,测试网没有这些生态。所以,我们硬分叉之后的网络,在具备这些生态数据的同时,还具备测试账号。

非常好用。这里说一下 ganache 分叉主网的一些特性。

  • 分叉后,你本地相当于有主网网络了
  • 当你和本地网络进行写交互的时候,就会出块,否则不出块
  • eth 和 bsc 都可以「其他我没测试」

使用

安装

npm install -g ganache-cli

启动

~$ ganache-cli

启动选项

下面可能有的横杠是两道。

  • -a–accounts: 指定启动时要创建的测试账户数量。
  • -e–defaultBalanceEther: 分配给每个测试账户的ether数量,默认值为100
  • -br –blockTime: 指定自动挖矿的blockTime,以秒为单位。默认值为0,表示不进行自动挖矿。
  • -d–deterministic: 基于预定的助记词(mnemonic)生成固定的测试账户地址。
  • -n–secure: 默认锁定所有测试账户,有利于进行第三方交易签名。
  • -m–mnemonic: 用于生成测试账户地址的助记词。
  • -p–port: 设置监听端口,默认值为8545
  • -h–hostname: 设置监听主机,默认值同NodeJSserver.listen()
  • -s–seed: 设置生成助记词的种子。.
  • -g–gasPrice: 设定Gas价格,默认值为20000000000
  • -l–gasLimit: 设定Gas上限,默认值为90000
  • -f–fork: 从一个运行中的以太坊节点客户端软件的指定区块分叉。输入值应当是该节点旳HTTP地址和端口,例如http://localhost:8545。可选使用@标记来指定具体区块,例如:http://localhost:8545@1599200
  • -i 或–networkId:指定网络id。默认值为当前时间,或使用所分叉链的网络id`。
  • –db: 设置保存链数据的目录。如果该路径中已经有链数据,ganache-cli`将用它初始化链而不是重新创建。
  • `–debug:输出VM操作码,用于调试。
  • –mem:输出ganache-cli`内存使用统计信息,这将替代标准的输出信息。
  • –noVMErrorsOnRPCResponse:不把失败的交易作为RPC错误发送。开启这个标志使错误报告方式兼容其他的节点客户端,例如gethParity

特殊选项

  • –account: 指定账户私钥和账户余额来创建初始测试账户。可多次设置:

$ ganache-cli --account="<privatekey>,balance" [--account="<privatekey>,balance"]

注意私钥长度为64字符,必须使用0x前缀的16进制字符串。账户余额可以是整数,也可以是0x前缀的17进制字符串,单位为wei

使用–account选项时,不会自动创建HD钱包。

-u–unlock: 解锁指定账户,或解锁指定序号的账户。可以设置多次。当与–secure选项同时使用时,这个选项将改变指定账户的锁定状态:

$ ganache-cli --secure --unlock "0x1234..." --unlock "0xabcd..."

也可以指定一个数字,按序号解锁账号:

$ ganache-cli --secure -u 0 -u 1

存在的坑

分叉 bsc 之后的测试账号,它的 bnb 不能兑换成 wbnb

经过我测试,测试账号确实不能用,所以我都是解锁一个主网上的账户,比如,先在主网一个账户上充上 bnb,然后

ganache-cli --fork https://bsc-dataseed.binance.org/  --unlock "主网账号"

在后面测试中,使用这个账号进行测试。

ps: 2022-7-8

  • 使用下面的连接更稳定

ganache-cli --fork.url wss://bsc-mainnet.nodereal.io/ws/v1/63ef6cb
  • 测试账号,可以通过 dexswapExactETHForTokensbnb 转化为任意 BRC20,包括 WBNB

代码

下面,我分叉了 bsc ,然后,进行 pancakeswap 操作。

  • 自动计算池子深度
  • 自动进行 approve 绑定
  • 自动进行 swap 操作,看是否符合量化 coin 要求

ps: 2022-7-10

下面探寻哪些币符合量化的方式有一点过时了,请参考最新的博客。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
import time

from web3 import Web3

from Config.contract import BSC_BUSD
from coin.coin import bsc

pancake_abi_Factory = """
[{"inputs":[{"internalType":"address","name":"_feeToSetter","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token0","type":"address"},{"indexed":true,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"PairCreated","type":"event"},{"constant":true,"inputs":[],"name":"INIT_CODE_PAIR_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allPairs","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"allPairsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"createPair","outputs":[{"internalType":"address","name":"pair","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"feeTo","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"feeToSetter","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"getPair","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_feeTo","type":"address"}],"name":"setFeeTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_feeToSetter","type":"address"}],"name":"setFeeToSetter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]
"""

pancake_Router_abi = """[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
"""

pair_abi = """
[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0Out","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Out","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint112","name":"reserve0","type":"uint112"},{"indexed":false,"internalType":"uint112","name":"reserve1","type":"uint112"}],"name":"Sync","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MINIMUM_LIQUIDITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"burn","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getReserves","outputs":[{"internalType":"uint112","name":"_reserve0","type":"uint112"},{"internalType":"uint112","name":"_reserve1","type":"uint112"},{"internalType":"uint32","name":"_blockTimestampLast","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_token0","type":"address"},{"internalType":"address","name":"_token1","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"kLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"price0CumulativeLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"price1CumulativeLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"skim","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount0Out","type":"uint256"},{"internalType":"uint256","name":"amount1Out","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"swap","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"sync","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"token0","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]
"""

pancake_Factory = Web3.toChecksumAddress("0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73")
pancake_Route = Web3.toChecksumAddress("0x10ed43c718714eb63d5aa57b78b54704e256024e")

w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:8545"))

base = bsc.get("base")
coins = bsc.get("coin")
contract_usdt = w3.eth.contract(
address=Web3.toChecksumAddress(base.get("USDT")), abi=BSC_BUSD)

contract_pancake_Router = w3.eth.contract(
address=Web3.toChecksumAddress(pancake_Route), abi=pancake_Router_abi)

contract_pancake_Factory = w3.eth.contract(
address=Web3.toChecksumAddress(pancake_Factory), abi=pancake_abi_Factory)

U = {
"BUSD": 1,
"USDT": 1,
"ETH": 2944,
"CAKE": 6.5,
"WBNB": 380,
"USDC": 1,
}


def chizi(symbol, address):
print(f"检测池子深度: {symbol}")
max_coin = ""
max_usdt = 0
max_pair = ""
for base_symbol, base_address in base.items():
index = 1
pair = contract_pancake_Factory.functions.getPair(Web3.toChecksumAddress(address),
Web3.toChecksumAddress(base_address)).call()
if address < base_address:
index = 2
if pair != "0x0000000000000000000000000000000000000000":
contract_coin2 = w3.eth.contract(
address=Web3.toChecksumAddress(pair), abi=pair_abi)
data = contract_coin2.functions.getReserves().call()
if index == 1:
base_liqu = data[0] / (10 ** 18)
coin_liqu = data[1] / (10 ** 18)
else:
base_liqu = data[1] / (10 ** 18)
coin_liqu = data[0] / (10 ** 18)

tmp_base = base_liqu * U.get(base_symbol)
if tmp_base > max_usdt:
max_coin = base_symbol
max_usdt = tmp_base
max_pair = pair
print(f"池子深度检测完毕,目前,最大 symbol 为 {max_coin} 深度为 {max_usdt}")
return max_coin, max_pair


def get_coin_contract(coin_address):
contract_coin = w3.eth.contract(
address=Web3.toChecksumAddress(coin_address), abi=BSC_BUSD)
return contract_coin


def approve(wallet_address, wallet_private, coin_address):
nonce = w3.eth.getTransactionCount(wallet_address)
print(f"开始 approve: nonce {nonce}")
contract_coin = get_coin_contract(coin_address)
tx_dic = contract_coin.functions.approve(pancake_Route,
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff).buildTransaction(
{
'gas': 300000,
'gasPrice': w3.eth.gasPrice,
'nonce': nonce,
})
sign_tx = w3.eth.account.signTransaction(tx_dic, wallet_private)
txn_hash = w3.eth.sendRawTransaction(sign_tx.rawTransaction)
print(Web3.toHex(txn_hash))
while 1:
_nonce = w3.eth.getTransactionCount(wallet_address)
if _nonce != nonce:
print("approve 成功")
break
time.sleep(5)


def get_usdt(wallet_address):
balance = contract_usdt.functions.balanceOf(wallet_address).call()
return balance


def get_wbnb(wallet_address):
balance = contract_usdt.functions.balanceOf(wallet_address).call()
return balance


def get_coin(contract, decimal_coin, wallet_address):
contract_coin = w3.eth.contract(
address=Web3.toChecksumAddress(contract), abi=BSC_BUSD)
balance = contract_coin.functions.balanceOf(wallet_address).call()
return balance


def encode_swap(coin_amount, base_amount, paths, wallet_address):
deadline = int(time.time()) + 300
tx_dic = contract_pancake_Router.functions.swapExactTokensForTokens(
int(coin_amount),
int(base_amount - base_amount * 0.01),
paths,
# Web3.toChecksumAddress(cex_address),
Web3.toChecksumAddress(wallet_address),
deadline
). \
buildTransaction(
{
'gas': 500000,
}
)
return tx_dic


def send_transaction(tx_dic, wallet_address, wallet_private):
nonce = w3.eth.getTransactionCount(wallet_address)
tx_dic["nonce"] = nonce
tx_dic['gasPrice'] = w3.eth.gasPrice
# print(nonce)
sign_tx = w3.eth.account.signTransaction(tx_dic, private_key=wallet_private)
txn_hash = w3.eth.sendRawTransaction(sign_tx.rawTransaction)
return Web3.toHex(txn_hash)


def get_wait_receipt(tx):
data = w3.eth.wait_for_transaction_receipt(tx)
return data


# 刚开始的账号没有 usdt 需要进行兑换
def swap_usdt(wallet_address, wallet_private):
nonce = w3.eth.getTransactionCount(wallet_address)
bnb = w3.eth.get_balance(wallet_address)
usdt = get_usdt(wallet_address)
print(f"开始兑换 usdt,nonce : {nonce} bnb:{bnb} usdt:{usdt}")
deadline = int(time.time()) + 300
dex_sell_paths = [Web3.toChecksumAddress(bsc.get("base").get("WBNB")),
Web3.toChecksumAddress(bsc.get("base").get("USDT"))]

tx_dic = contract_pancake_Router.functions.swapExactETHForTokens(
0,
dex_sell_paths,
Web3.toChecksumAddress(wallet_address),
deadline,
). \
buildTransaction(
{
'from': Web3.toChecksumAddress(wallet_address),
'gas': 5000000,
'value': Web3.toWei(0.01, 'ether')
}
)
tx = send_transaction(tx_dic, wallet_address, wallet_private)
# print(get_wait_receipt(tx))
while 1:
_nonce = w3.eth.getTransactionCount(wallet_address)
if _nonce != nonce:
print("approve 成功")
break
time.sleep(5)
usdt = get_usdt(wallet_address)
print(f"兑换后 usdt: {usdt}")


def swap(coin, max_u, pair, wallet_address, wallet_private):
nonce = w3.eth.getTransactionCount(wallet_address)
print(coin)
coin_contract = bsc.get("coin").get(coin).get("address")
coin_pair = max_u
if coin_pair != "USDT":
dex_sell_paths = [Web3.toChecksumAddress(coin_contract),
Web3.toChecksumAddress(bsc.get("base").get(coin_pair)),
Web3.toChecksumAddress(bsc.get("base").get("USDT"))]
dex_buy_paths = [Web3.toChecksumAddress(bsc.get("base").get("USDT")),
Web3.toChecksumAddress(bsc.get("base").get(coin_pair)),
Web3.toChecksumAddress(coin_contract)]
else:
dex_sell_paths = [Web3.toChecksumAddress(coin_contract),
Web3.toChecksumAddress(bsc.get("base").get("USDT"))]
dex_buy_paths = [Web3.toChecksumAddress(bsc.get("base").get("USDT")), Web3.toChecksumAddress(coin_contract)]
usdt = get_usdt(wallet_address)
print(f"\t usdt: {usdt / (10 ** 18)}")
tx_dic = encode_swap(usdt, 0, dex_buy_paths, wallet_address)
tx = send_transaction(tx_dic, wallet_address, wallet_private)
get_wait_receipt(tx)
while 1:
__nonce = w3.eth.getTransactionCount(wallet_address)
if __nonce > nonce:
nonce = w3.eth.getTransactionCount(wallet_address)
break
time.sleep(3)
coin_balance = get_coin(coin_contract, bsc.get("coin").get(coin).get("decimal"), wallet_address)
print(f'\t coin: {coin_balance / (10 ** bsc.get("coin").get(coin).get("decimal"))}')

tx_dic = encode_swap(coin_balance, 0, dex_sell_paths,
wallet_address)
tx = send_transaction(tx_dic, wallet_address, wallet_private)
data = get_wait_receipt(tx)
# print(data)
while 1:
__nonce = w3.eth.getTransactionCount(wallet_address)
if __nonce > nonce:
nonce = w3.eth.getTransactionCount(wallet_address)
break
time.sleep(3)

usdt = get_usdt(wallet_address)
print(f"\t usdt: {usdt / (10 ** 18)}")


if __name__ == '__main__':
max_coin, max_pair = chizi("CP", "0x82C19905B036bf4E329740989DCF6aE441AE26c1")
approve("解锁账号",
"解锁账号的密钥",
"0x82C19905B036bf4E329740989DCF6aE441AE26c1")
swap_usdt("解锁账号",
"解锁账号的密钥")
swap("CP", max_coin, max_pair, "解锁账号",
"解锁账号的密钥")
请我喝杯咖啡吧~