之前写了基于DYDX闪电贷在Cofix和Uniswap之间套利,只要解释了套利合约中的逻辑以及怎么调用其中涉及到的各个合约(cofix,weth,dydx,uniswap)。套利机会很少,不能人在盯着,需要配一套可以自动查询并且发送交易的程序。
先说一下为啥选择python,因为简单。之前用swift(iOS)实现了和以太坊交互,太恶心了。。。 python需要用到一个库web3.py。 文档:https://web3py.readthedocs.io/en/stable/ github:https://github.com/ethereum/web3.py
之前写了基于DYDX闪电贷在Cofix和Uniswap之间套利,只要解释了套利合约中的逻辑以及怎么调用其中涉及到的各个合约(cofix,weth,dydx,uniswap)。套利机会很少,不能人在盯着,需要配一套可以自动查询并且发送交易的程序。
graph LR
A[套利脚本] -- 生成 --> B((触发套利合约的交易))
B((触发套利合约的交易))--查询是否有套利空间-->C[以太坊]
脚本需要实现的是一直在查询是否有套利机会,如果有就发起交易。
https://github.com/MLY0813/FlashSwapForCofixAndUni/tree/main/FlashSwapForCofixAndUni https://github.com/MLY0813/SwapCofixAndUni/tree/main/CofixAndUni
SETTING = {
"ROPSTEN_URL": "XXX",
"MAINNET_URL": "XXX",
"CONTRACT_ADDRESS": "XXX",
"WALLET_PRIVATEKEY": "XXX",
"WALLET_ADDRESS": "XXX",
"ETH_SPAN": [1800, 2100, 2400, 2700, 3000, 3300, 3600, 3900]
}
w3 = Web3(Web3.HTTPProvider(SETTING["MAINNET_URL"]))
def sendTransation(tx_dic):
nonce = w3.eth.getTransactionCount(SETTING["WALLET_ADDRESS"])
tx_dic["nonce"] = nonce
tx_dic['gasPrice'] = w3.eth.gasPrice
sign_tx = w3.eth.account.signTransaction(tx_dic, private_key=SETTING["WALLET_PRIVATEKEY"])
return w3.eth.sendRawTransaction(sign_tx.rawTransaction)
def sendTransationWithMoreGas(tx_dic, gwei):
nonce = w3.eth.getTransactionCount(SETTING["WALLET_ADDRESS"])
tx_dic["nonce"] = nonce
tx_dic['gasPrice'] = w3.eth.gasPrice + w3.toWei(gwei, 'gwei')
sign_tx = w3.eth.account.signTransaction(tx_dic, private_key=SETTING["WALLET_PRIVATEKEY"])
return w3.eth.sendRawTransaction(sign_tx.rawTransaction)
sendTransation和sendTransationWithMoreGas的区别在于前者使用的是默认gasprice(均价),后者是在均价的基础上按需求增加。
主要包含套利合约的ABI,拼接调用initiateFlashLoan方法的交易。“initiateFlashLoan”是触发套利合约套利的方法。
def initiateFlashLoan(ethAmount):
tx_dix = contractObj.functions.initiateFlashLoan(ethAmount).buildTransaction({
'from': SETTING["WALLET_ADDRESS"],
'gas': 1200000
})
return tx_dix
在主函数中主要实现了轮询的方法,这里用到了以太坊的机制“预估gas”。套利合约需要检测有没有套利空间,cofix和uniswap都有很复杂的交易计算,没必要在脚本中完全模拟出双方的交易计算从而判断有没有套利空间是否需要发交易。estimateGas可以预估出套利交易的gas消耗(不准,仅供参考)。我们实际想要知道的是是否有套利空间,因为在套利合约中已经判断了资金量不能少。所以可以假设estimateGas正常返回数据代表此刻有套利空间,如果异常代表没有套利空间。 在代码中使用try,捕捉异常来判断发起交易的时机。
for num in SETTING["ETH_SPAN"]:
now = int(time.time())
timeArray = time.localtime(now)
tx_dic = initiateFlashLoan(w3.toWei(num, "ether"))
try:
tx_dic_gas = w3.eth.estimateGas(tx_dic)
except ValueError:
print("unlucky", time.strftime("%Y--%m--%d %H:%M:%S", timeArray))
else:
print("success")
sendTransationWithMoreGas(tx_dic, "2")
time.sleep(20)
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!