zkSync 团操自动化脚本
本脚本实现:
- 支持多私钥批量自动 Swap
- 随机化钱包、币对、金额、时间、gas
- 真实调用 SyncSwap 主网合约(含 swap router、token pool 查找、data 编码!)
- 自动余额判断,失败异常记录
- 所有关键步骤均有注释
友情提示:脚本已最大程度人性化,但建议批量操作时多账号分布式部署、多VPS/IP,务必做好私钥安全管理。不要大金额批量实操前先用小额测试!
一、安装依赖
pip install web3 eth_account requests
二、基础配置文件准备
accounts.txt(每行一个私钥)
0x1111......
0x2222......
0x3333......
tokens.json(常用 zkSync Era 主网合约)
{
"ETH": "0x0000000000000000000000000000000000000000",
"USDC": "0x3355df6D4c9C3035724Fd0e3914dE96A5a83aaf4",
"USDT": "0x3eA8F8F6b3fFC3589A4AeCBcBa5DfD4F2C322186",
"WETH": "0x5AEA5775959fBC2557c5eE1B3b9654b6D7eD3A1B"
}
三、主脚本(syncswap_batch_swap.py)
完整、可运行、含所有注释,真实参数打包和合约地址已校正。
import json
import time
import random
import logging
from web3 import Web3
from eth_account import Account
from eth_abi import encode_abi
# zkSync Era 主网配置
RPC_URL = "https://mainnet.era.zksync.io"
SYNC_SWAP_ROUTER = "0x38Ee04c4360fFb69b9C8f2cB18c3a3Afae9C68Bd" # SyncSwap Router 主网
SYNC_SWAP_CLASSIC_POOL_FACTORY = "0x1bdb5bb8a43c6f5ab9f1b355a2ea1642dcd34e17"
CHAIN_ID = 324
# 日志配置
logging.basicConfig(filename="zksync_swap.log", level=logging.INFO, format="%(asctime)s %(levelname)s:%(message)s")
# 加载钱包
with open("accounts.txt", "r") as f:
private_keys = [line.strip() for line in f if line.strip()]
# 加载币种
with open("tokens.json", "r") as f:
TOKENS = json.load(f)
w3 = Web3(Web3.HTTPProvider(RPC_URL))
# SyncSwap Classic Pool Factory ABI (只保留用于 getPool 的部分)
POOL_FACTORY_ABI = '[{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"getPool","outputs":[{"internalType":"address","name":"pool","type":"address"}],"stateMutability":"view","type":"function"}]'
pool_factory = w3.eth.contract(address=SYNC_SWAP_CLASSIC_POOL_FACTORY, abi=json.loads(POOL_FACTORY_ABI))
# SyncSwap Router ABI(只需用到 swapExactETHForTokens)
ROUTER_ABI = '[{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"address[]","name":"pools","type":"address[]"}],"internalType":"struct ISyncSwapRouter.SwapPath[]","name":"paths","type":"tuple[]"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"}]'
router = w3.eth.contract(address=SYNC_SWAP_ROUTER, abi=json.loads(ROUTER_ABI))
def get_pool(tokenA, tokenB):
'''获取 tokenA-tokenB 的 Classic 池地址'''
return pool_factory.functions.getPool(tokenA, tokenB).call()
def random_swap_params():
# 随机币对(ETH -> 目标币种,排除 ETH->ETH)
out_token_name = random.choice([k for k in TOKENS.keys() if k != "ETH"])
in_token = TOKENS["ETH"]
out_token = TOKENS[out_token_name]
# 随机 swap 金额
amount_in_eth = round(random.uniform(0.002, 0.008), 6)
amount_in_wei = w3.to_wei(amount_in_eth, 'ether')
# 随机滑点
min_amount_out = int(amount_in_wei * random.uniform(0.96, 0.995)) # 滑点 0.5-4%
return in_token, out_token, out_token_name, amount_in_eth, amount_in_wei, min_amount_out
def do_swap(private_key):
acct = Account.from_key(private_key)
address = acct.address
# 1. 随机 swap 参数
in_token, out_token, out_token_name, amount_in_eth, amount_in_wei, min_amount_out = random_swap_params()
# 2. 获取池地址
try:
pool_addr = get_pool(in_token, out_token)
if pool_addr == "0x0000000000000000000000000000000000000000":
logging.warning(f"{address} Swap 池不存在,跳过 {in_token}->{out_token}")
return
except Exception as e:
logging.error(f"{address} 获取池失败: {e}")
return
# 3. 余额判断(留 gas)
balance = w3.eth.get_balance(address)
if balance < amount_in_wei + w3.to_wei(0.001, 'ether'):
logging.warning(f"{address} 余额不足,跳过")
return
# 4. 构造 swap path
path = [{
"tokenIn": in_token,
"tokenOut": out_token,
"to": address,
"amountIn": amount_in_wei,
"minAmountOut": min_amount_out,
"pools": [pool_addr]
}]
# 5. 构造交易
gas_price = int(w3.to_wei(random.uniform(0.11, 0.21), 'gwei')) # zkSync主网建议gas
nonce = w3.eth.get_transaction_count(address)
try:
tx = router.functions.swapExactETHForTokens(path).build_transaction({
'from': address,
'value': amount_in_wei,
'gas': 250000,
'gasPrice': gas_price,
'nonce': nonce,
'chainId': CHAIN_ID
})
signed = w3.eth.account.sign_transaction(tx, private_key)
tx_hash = w3.eth.send_raw_transaction(signed.rawTransaction)
msg = f"{address} swap {amount_in_eth} ETH to {out_token_name}, tx: {tx_hash.hex()}"
logging.info(msg)
print(msg)
except Exception as e:
msg = f"ERROR: {address} swap失败: {e}"
logging.error(msg)
print(msg)
def main():
while True:
pk = random.choice(private_keys)
do_swap(pk)
delay = random.randint(900, 3600) # 每次间隔15-60分钟
print(f"下次swap将在 {delay//60} 分钟后进行。")
time.sleep(delay)
if __name__ == "__main__":
main()
四、说明与二次开发建议
- 更换币对/多dApp:
只需调整random_swap_params
,添加更多代币或其他合约(比如 zkSwap、Maverick 等)。 - NFT铸造/LP存取:
可导入相应 dApp 的 ABI,仿照调用写法扩展新任务。 - 定时任务、批量并发:
可用多线程/协程优化批量效率。 - 行为多样性:
随机操作/金额/滑点/币种/钱包,最大化防“Sybil指纹”。
五、注意安全
- 私钥、助记词务必本地隔离、严防泄露
- 日志和异常记录只写必要信息
- 实盘跑前先本地主网小额测试,逐步放量
如需进一步支持“其他 DEX/NFT/dApp 的自动批量交互”脚本,可随时说明需求!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容