Sur le marché des crypto-monnaies, les opportunités de trading sont souvent éphémères, en particulier les opportunités d’arbitrage, qui peuvent ne durer que quelques minutes. Si vous vous fiez aux opérations manuelles, les utilisateurs risquent de ne pas être en mesure de saisir la meilleure opportunité à temps ou de manquer le meilleur prix. Par exemple, il y a quelque temps, en raison de l’attaque de pirate informatique sur Bybit, l’USDe a été découplé, ce qui a provoqué une forte fluctuation de son prix. À cette époque, le taux de rendement annualisé obtenu en achetant et en rachetant des sUSDe dépassait 300 %. Cette fenêtre de rendement élevé dure généralement très peu de temps et il est difficile pour le trading manuel de suivre le rythme du marché sans définir d’ordres à l’avance. Par conséquent, la fonction de placement d’ordres est devenue un outil important pour les utilisateurs d’échanges décentralisés (DEX), améliorant considérablement l’efficacité des transactions.
Plusieurs DEX offrent une fonctionnalité d’ordre limité, chacun avec des implémentations et des structures de frais différentes. Prenons Cow Swap et Odos comme exemples. Le principe de base est d’utiliser sa fonction d’agrégation pour surveiller la liquidité et les prix de plusieurs DEX en temps réel. Lorsque le prix du marché atteint les conditions limites, l’ordre sera déclenché par le preneur et le contrat intelligent exécutera automatiquement la transaction et paiera les frais de gaz. Cow stocke également les commandes des utilisateurs hors chaîne, qui sont ensuite comparées de manière compétitive par un groupe de nœuds décentralisés appelés « Solvers », mais sont finalement exécutées sur la chaîne. En bref, bien que le GAS soit exonéré, les bénéfices supplémentaires générés par les transactions effectuées par ces DEX pour vous peuvent couvrir les frais de GAS.
Mais cela pose un problème : si l’un de vos ordres est en attente à un prix de 90 U et que l’agrégateur constate que le prix d’un DEX donné est tombé à 80 U, il exécutera la transaction pour vous. Votre ordre est finalement exécuté à un prix de 90 U, générant un bénéfice de 10 U. Comment ce bénéfice est-il réparti ? Dans la pratique, les différentes plateformes gèrent la situation différemment. Prenons l’exemple de Cow Swap, son mécanisme stipule clairement que lorsque le prix d’exécution est meilleur que le prix limite, le surplus généré (c’est-à-dire les 10U) sera divisé entre la plateforme et l’utilisateur, Cow Swap prenant 50 % et l’utilisateur obtenant les 50 % restants. Odos déposera tout surplus dans le coffre-fort. En substance, votre ordre est arbitré sans risque par la bourse DEX.
De plus, afin d’économiser les frais de transaction, les ordres DEX sont des transactions agrégées, c’est-à-dire que de nombreuses transactions sont regroupées de temps en temps, et ETH a un bloc de 12 secondes, ce qui entraînera la perte de certaines opportunités possibles. Bien sûr, DEX présente encore de nombreux avantages, tels que la recherche de plus de chemins, la correspondance hors ligne, l’économie de GAS, etc., qui sont suffisants pour la plupart des utilisateurs.
Par rapport aux ordres agrégés du DEX, le trading direct via des contrats intelligents présente des avantages uniques. Tout d’abord, les utilisateurs ont un contrôle total sur la logique d’exécution des commandes et sur tous les gains. Deuxièmement, passer vos propres commandes évite le délai de conditionnement des transactions agrégées et permet de réagir plus rapidement aux changements du marché, en particulier en saisissant les opportunités dans les 12 secondes en cas de forte volatilité. De plus, les ordres personnalisés en attente peuvent définir de manière flexible des conditions complexes (telles que le trading de portefeuille multi-actifs ou le stop profit et le stop loss) sans être limités par les fonctions prédéfinies de la plateforme. Cependant, cela nécessite certaines compétences en programmation, il faut payer les frais de gaz soi-même et il peut y avoir des risques de sécurité sur la chaîne. Par conséquent, passer vos propres commandes convient aux utilisateurs avancés qui ont de solides capacités techniques et recherchent des rendements maximaux.
Si vous souhaitez exploiter des contrats intelligents avec vos propres programmes, la sécurité de vos clés privées est sans aucun doute votre plus grande préoccupation. La solution que j’ai trouvée consiste à utiliser Python pour chiffrer ma clé privée hors ligne et à stocker le texte chiffré sur le serveur hébergeant l’hôte. Le mot de passe déchiffré est transmis via les paramètres du robot de la plateforme FMZ, et le programme s’exécute sur l’hôte, le lit et le déchiffre (il peut être supprimé après exécution). De cette façon, même si votre serveur est piraté, il n’y aura pas de problème, mais vous devez toujours faire attention à ne pas divulguer votre compte FMZ. Comme il ne s’agit que d’un seul texte en clair hors réseau, la sécurité est acceptable. Le code spécifique est le suivant, qui peut être exécuté localement hors réseau
from web3 import Web3 # Web3.py 是与以太坊区块链交互的Python库
import json # 用于处理JSON数据
import time # 用于设置时间间隔
import requests # 用于发送HTTP请求
from cryptography.fernet import Fernet
import base64
import hashlib
from datetime import datetime
from hexbytes import HexBytes
def generate_key(password: str) -> bytes:
"""通过用户密码生成 AES 密钥"""
return base64.urlsafe_b64encode(hashlib.sha256(password.encode()).digest())
def encrypt_private_key(private_key: str, password: str) -> str:
"""使用密码加密私钥"""
key = generate_key(password)
cipher = Fernet(key)
return cipher.encrypt(private_key.encode()).decode()
def decrypt_private_key(encrypted_key: str, password: str) -> str:
"""使用密码解密私钥"""
key = generate_key(password)
cipher = Fernet(key)
return cipher.decrypt(encrypted_key.encode()).decode()
def save_key_to_file(key, file_path):
# 将加密密钥保存到txt文件
with open(file_path, 'w') as file:
file.write(key)
def load_key_from_file(file_path):
# 从txt文件读取加密密钥
with open(file_path, 'r') as file:
return str(file.read())
def main():
encrypt_key = encrypt_private_key('my_private_key', 'password') # my_private_key是自己的私钥,password是自己设置的密码
save_key_to_file(encrypt_key,'encrypt_key.txt')
print("加密后的私钥", encrypt_key)
decrypt_key = decrypt_private_key(load_key_from_file('encrypt_key.txt'), 'password')
print("解密的私钥", decrypt_key)
Web3.py est une puissante bibliothèque Python permettant d’interagir avec le réseau Ethereum. Installez-le avec la commande suivante : pip install web3. Sa fonction est de simplifier la communication entre les développeurs et les nœuds Ethereum et de prendre en charge des opérations telles que l’interrogation des soldes, l’appel de contrats intelligents et l’envoi de transactions. Par exemple, vérifier le solde d’un compte ne nécessite que quelques lignes de code, ce qui fait de Web3.py un outil idéal pour créer des DApps ou automatiser des transactions.
python
from web3 import Web3
w3 = Web3(Web3.HTTPProvider('你的RPC地址'))
balance = w3.eth.get_balance('0x某个地址')
print(w3.from_wei(balance, 'ether'))
RPC (Remote Procedure Call) est une interface de communication fournie par le nœud Ethereum, qui interagit avec la blockchain en envoyant des requêtes JSON via le protocole HTTP ou WebSocket. Par exemple, eth_blockNumber peut interroger la hauteur du dernier bloc. En raison du coût élevé de l’exécution d’un nœud local, les développeurs s’appuient généralement sur des fournisseurs RPC tiers. Les choix courants incluent :
from web3 import Web3
w3 = Web3(Web3.HTTPProvider('https://eth-mainnet.g.alchemy.com/v2/你的API密钥'))
print(w3.is_connected())
Il est recommandé d’utiliser Alchemy. Comparé à Infura de MetaMask, Alchemy offre un quota gratuit plus élevé. Après inscription, vous pouvez obtenir l’adresse RPC, par exemple https://eth-mainnet.g.alchemy.com/v2/votre clé API, et la configurer sur Web3.py.
En prenant comme exemple le pool Crve de sDAI/sUSDe https://curve.fi/dex/ethereum/pools/factory-stable-ng-102/swap/, vous pouvez facilement trouver les adresses des deux jetons et l’adresse du pool.

L’ABI définit les modalités d’interaction avec le contrat ; il est donc nécessaire de l’obtenir. Consultez le contrat sur ethscan : https://etherscan.io/address/0x167478921b907422f8e88b43c4af2b8bea278d3a#code. Vous pouvez consulter l’ABI sur la page du contrat et le copier directement.
Commencez par lier le portefeuille ETH. Si l’adresse de votre portefeuille est imprimée, cela signifie que l’opération a réussi.
def main():
# 文件路径
file_path = 'encrypted_key.txt'
# 从文件中读取加密的私钥
encrypted_private_key = load_key_from_file(file_path)
private_key = decrypt_private_key(encrypted_private_key, Password) #Password为密码,定义为策略的参数
web3 = Web3(Web3.HTTPProvider(HTTPProvider)) # HTTPProvider为RPC的链接,定义为参数
account = web3.eth.account.from_key(private_key)
address = account.address # 获取账户的公开地址
Log('链接账户', address)
Voici le processus d’obtention du prix. Finalement, hors frais de GAS, l’investissement actuel de 100 000 SDAI générera un bénéfice de 335 U après une semaine. Cela peut paraître un peu compliqué, mais ce n’est en fait pas difficile à comprendre.
# --------------- 合约设置 ---------------
# Curve.fi sDAI/sUSDe 池合约地址和ABI
pool_address = '0x167478921b907422F8E88B43C4Af2B8BEa278d3A' # Curve池子的合约地址
# 以下是简化的ABI,仅包含我们需要的函数
pool_abi = json.loads('''[{"stateMutability":"view","type":"function","name":"get_dy","inputs":[{"name":"i","type":"int128"},{"name":"j","type":"int128"},{"name":"dx","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]}]''')
# 创建池子合约对象
pool_contract = web3.eth.contract(address=pool_address, abi=pool_abi)
# ERC20 代币标准合约ABI
erc20_abi = json.loads('''[
{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"type":"function"},
{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"type":"function"},
{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}
]''')
sdai_address = '0x83F20F44975D03b1b09e64809B757c47f942BEeA' # sDAI代币的合约地址
susde_address = '0x9D39A5DE30e57443BfF2A8307A4256c8797A3497' # sUSDE代币的合约地址
# 池子中代币的索引
SDAI_INDEX = 0 # sDAI代币在池子中的索引
SUSDE_INDEX = 1 # sUSDE代币在池子中的索引
# 创建代币合约对象
sdai_contract = web3.eth.contract(address=sdai_address, abi=erc20_abi)
susde_contract = web3.eth.contract(address=susde_address, abi=erc20_abi)
SUSDE_PRICE = 1.1623 #这个价格是ethena官网价格,1周后可赎回
SDAI_PRICE = 1.15 #sDAI是收益代币,价值会累计,目前价格1.15
try:
SDAI_DECIMALS = sdai_contract.functions.decimals().call()
SUSDE_DECIMALS = susde_contract.functions.decimals().call()
except:
# 如果无法获取,假设为标准的18位精度
SDAI_DECIMALS = 18
SUSDE_DECIMALS = 18
amount_in = 100000
amount_out = pool_contract.functions.get_dy(
SDAI_INDEX, # 输入代币索引
SUSDE_INDEX, # 输出代币索引
int(amount_in * 10**SDAI_DECIMALS) # 输入数量(wei)
).call()
profit = SUSDE_PRICE * amount_out / 10**SUSDE_DECIMALS - amount_in * SDAI_PRICE
Log(round(profit, 2), round(amount_out / 10**SUSDE_DECIMALS, 2))
Enfin, nous utilisons des sondages pour obtenir des prix en continu et passer une commande lorsque le bénéfice attendu est atteint. Notez ce code.Ceci n’est qu’un exemple de code, ne l’utilisez pas directementLes lecteurs peuvent rencontrer divers problèmes dans la pratique, mais l’IA est actuellement très puissante et peut répondre à de nombreuses questions. Elle peut également contribuer directement à l’écriture de code. L’éditeur de code de FMZ intègre également ChatGPT, qui peut être utilisé plus fréquemment.
def execute_trade(amount_in, min_amount_out, direction):
gas_price = web3.eth.gas_price
index_in = SUSDE_INDEX
index_out = SDAI_INDEX
if direction == 'buy':
index_in = SDAI_INDEX
index_out = SUSDE_INDEX
# 第二步:执行代币交换交易
swap_tx = pool_contract.functions.exchange(
index_in, # 输入代币索引
index_out, # 输出代币索引
int(amount_in*10**SDAI_DECIMALS), # 输入数量
int(min_amount_out*10**SUSDE_DECIMALS) # 最小输出数量(考虑滑点)
).build_transaction({
'from': address, # 交易发送方
'gas': 600000, # gas限制
'gasPrice': int(2*gas_price) ,
'nonce': web3.eth.get_transaction_count(address), # 获取新的nonce值
})
# 签名并发送交换交易
signed_swap_tx = web3.eth.account.sign_transaction(swap_tx, private_key)
swap_tx_hash = web3.eth.send_raw_transaction(signed_swap_tx.rawTransaction)
Log(f"交换交易已提交,交易哈希: {swap_tx_hash.hex()}")
def get_buy_profit(amount_in):
amount_out = pool_contract.functions.get_dy(
SDAI_INDEX, # 输入代币索引
SUSDE_INDEX, # 输出代币索引
int(amount_in * 10**SDAI_DECIMALS) # 输入数量(wei)
).call()
return SUSDE_PRICE * amount_out / 10**SUSDE_DECIMALS - amount_in * SDAI_PRICE, amount_out / 10**SUSDE_DECIMALS
def main():
while True:
try:
sdai_balance = sdai_contract.functions.balanceOf(address).call() / 10**SDAI_DECIMALS
susde_balance = susde_contract.functions.balanceOf(address).call() / 10**SUSDE_DECIMALS
amount_in = 100000 #交易的DAI数量
profit, amount_out = get_buy_profit(amount_in)
LogStatus(f"SDAI数量:{sdai_balance}, SUSDE数量:{susde_balance}, 收益:{profit}")
if profit > 1000 and sdai_balance > amount_in: #利润空间
Log("\n开始执行SDAI->SUSDE交易...")
execute_trade(amount_in, 0.999*amount_out, 'buy') #一定要设置滑点
wait_time = 3 # 等待时间(秒)
time.sleep(wait_time)
except Exception as e:
# 全局错误处理
print(f"程序发生错误: {e}")
print("60秒后重试...")
time.sleep(60) # 出错后等待更长时间
Les opérations on-chain sont relativement risquées pour les novices. Outre le risque de fuite de clé privée mentionné précédemment, il existe divers autres risques :
Pour les novices en trading on-chain, ils doivent apprendre les bases : comprendre des concepts tels que le gaz, le glissement, le MEV, etc. Commencez toujours par une petite quantité et augmentez progressivement. Surveillez les transactions à l’aide d’un outil comme Etherscan. Il vaut mieux rater une opportunité que de risquer de perdre son capital.