文章目錄
- python與以太坊智能合約互動
-
- 需要做一個輪詢腳本
- 思路
- 上代碼
-
- 1.配置
- 2.交易必備的方法和對象
-
- w3節點對象
- 發送交易方法封裝
- swapContract.py
- main.py
python與以太坊智能合約互動
先說一下為啥選擇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)。套利機會很少,不能人在盯着,需要配一套可以自動查詢并且發送交易的程式。
思路
腳本需要實作的是一直在查詢是否有套利機會,如果有就發起交易。
上代碼
https://github.com/MLY0813/FlashSwapForCofixAndUni/tree/main/FlashSwapForCofixAndUni
https://github.com/MLY0813/SwapCofixAndUni/tree/main/CofixAndUni
1.配置
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]
}
- ROPSTEN_URL:以太坊測試網的節點位址
- MAINNET_URL:以太坊主網的節點位址
- CONTRACT_ADDRESS:套利合約的位址
- WALLET_PRIVATEKEY:執行套利交易的錢包私鑰(需要私鑰簽名交易)
- WALLET_ADDRESS:執行套利交易的錢包位址
- ETH_SPAN:套利所使用的資金規模,暫定以300ETH為跨度
2.交易必備的方法和對象
w3節點對象
發送交易方法封裝
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(均價),後者是在均價的基礎上按需求增加。
swapContract.py
主要包含套利合約的ABI,拼接調用initiateFlashLoan方法的交易。“initiateFlashLoan”是觸發套利合約套利的方法。
def initiateFlashLoan(ethAmount):
tx_dix = contractObj.functions.initiateFlashLoan(ethAmount).buildTransaction({
'from': SETTING["WALLET_ADDRESS"],
'gas': 1200000
})
return tx_dix
main.py
在主函數中主要實作了輪詢的方法,這裡用到了以太坊的機制“預估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)