3
fokus pada
1444
Pengikut

Bagaimana untuk melaksanakan penempatan pesanan dalam pertukaran terdesentralisasi - Mengambil Curve sebagai contoh

Dicipta dalam: 2025-03-13 14:28:33, dikemas kini pada: 2025-03-14 17:27:53
comments   1
hits   933

Mengapa saya perlu membuat pesanan?

Dalam pasaran mata wang kripto, peluang dagangan selalunya sekejap, terutamanya peluang arbitraj, yang mungkin hanya bertahan selama beberapa minit. Jika anda bergantung pada operasi manual, pengguna mungkin tidak dapat merebut peluang terbaik dalam masa atau terlepas harga terbaik. Sebagai contoh, suatu ketika dahulu, disebabkan oleh serangan penggodam ke atas Bybit, USDe telah dipisahkan, menyebabkan harganya sangat berubah-ubah. Pada masa itu, kadar pulangan tahunan melalui pembelian sUSDe dan menebusnya melebihi 300%. Tetingkap hasil tinggi ini biasanya bertahan untuk masa yang sangat singkat, dan sukar untuk perdagangan manual untuk mengikuti rentak pasaran tanpa menetapkan pesanan terlebih dahulu. Oleh itu, fungsi penempatan pesanan telah menjadi alat penting untuk pengguna pertukaran terdesentralisasi (DEX), meningkatkan kecekapan transaksi dengan ketara.

Prinsip dan kekurangan pesanan DEX

Berbilang DEX menawarkan fungsi pesanan had, setiap satu dengan pelaksanaan dan struktur yuran yang berbeza. Ambil Cow Swap dan Odos sebagai contoh. Prinsip terasnya ialah menggunakan fungsi agregatornya untuk memantau kecairan dan harga berbilang DEX dalam masa nyata. Apabila harga pasaran memenuhi syarat had, pesanan akan dicetuskan oleh pengambil, dan kontrak pintar akan secara automatik melaksanakan transaksi dan membayar yuran gas. Cow juga menyimpan pesanan pengguna di luar rantaian, yang kemudiannya dipadankan secara kompetitif oleh sekumpulan nod terdesentralisasi yang dipanggil “Penyelesai”, tetapi akhirnya dilaksanakan dalam rantaian. Ringkasnya, walaupun GAS dikecualikan, keuntungan tambahan yang dijana oleh transaksi yang diselesaikan oleh DEX ini untuk anda boleh menampung yuran GAS.

Tetapi ini menimbulkan masalah: jika salah satu pesanan anda belum selesai pada harga 90U dan agregator memantau bahawa harga DEX tertentu telah turun kepada 80U, pesanan anda akhirnya dilaksanakan pada harga 90U, menjana keuntungan sebanyak 10U. Bagaimana keuntungan ini diagihkan? Dalam operasi sebenar, platform berbeza mengendalikannya secara berbeza. Mengambil Cow Swap sebagai contoh, mekanismenya dengan jelas menetapkan bahawa apabila harga pelaksanaan lebih baik daripada harga had, lebihan yang dijana (iaitu, 10U) akan dibahagikan antara platform dan pengguna, dengan Cow Swap mengambil 50% dan pengguna mendapat baki 50%. Odos akan mendepositkan sebarang lebihan ke dalam peti besi. Pada dasarnya, pesanan anda ditimbangtarakan tanpa risiko oleh pertukaran DEX.

Di samping itu, untuk menjimatkan yuran transaksi, pesanan DEX ialah urus niaga agregat, iaitu, banyak urus niaga dibungkus bersama-sama sekali-sekala, dan ETH mempunyai blok 12 saat, yang akan mengakibatkan kehilangan beberapa kemungkinan peluang. Sudah tentu, DEX masih mempunyai banyak kelebihan, seperti mencari lebih banyak laluan, padanan luar talian, menjimatkan GAS, dll., yang cukup untuk kebanyakan pengguna.

Kelebihan membuat pesanan dengan program anda sendiri

Berbanding dengan bergantung pada pesanan agregat DEX, berdagang secara langsung melalui kontrak pintar mempunyai kelebihan unik. Pertama, pengguna mempunyai kawalan penuh ke atas logik pelaksanaan pesanan dan semua pendapatan. Kedua, membuat pesanan anda sendiri mengelakkan kelewatan pembungkusan transaksi agregat dan boleh bertindak balas terhadap perubahan pasaran dengan lebih cepat, terutamanya merebut peluang dalam masa 12 saat semasa turun naik yang tinggi. Di samping itu, pesanan tersuai belum selesai boleh menetapkan keadaan kompleks secara fleksibel (seperti perdagangan portfolio berbilang aset atau hentikan untung dan hentikan kerugian) tanpa dihadkan oleh fungsi pratetap platform. Walau bagaimanapun, ini memerlukan kemahiran pengaturcaraan tertentu, dan seseorang itu perlu membayar sendiri yuran gas, dan mungkin terdapat risiko keselamatan pada rantaian. Oleh itu, membuat pesanan anda sendiri sesuai untuk pengguna lanjutan yang mempunyai keupayaan teknikal yang kukuh dan mengejar pulangan maksimum.

Perlindungan kunci peribadi

Jika anda ingin mengendalikan kontrak pintar dengan program anda sendiri, keselamatan kunci peribadi anda sudah pasti menjadi kebimbangan terbesar anda. Penyelesaian yang saya hasilkan ialah menggunakan Python untuk menyulitkan kunci peribadi saya sendiri di luar talian, dan menyimpan teks sifir yang disulitkan pada pelayan yang menjalankan hos Kata laluan yang dinyahsulit dihantar menggunakan parameter robot platform FMZ, dan program berjalan pada hos dan membaca dan menyahsulitnya (ia boleh dipadamkan selepas program dijalankan). Dengan cara ini, walaupun pelayan anda digodam, tidak akan ada masalah, tetapi anda masih perlu berhati-hati untuk tidak membocorkan akaun FMZ anda. Memandangkan ia hanya melibatkan satu plaintext luar rangkaian, keselamatan boleh diterima. Kod khusus adalah seperti berikut, yang boleh dijalankan secara tempatan di luar grid

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)

Persediaan sebelum memautkan ETH

Web3.py ialah perpustakaan Python yang berkuasa untuk berinteraksi dengan rangkaian Ethereum. Pasangnya dengan arahan berikut: pip install web3. Fungsinya adalah untuk memudahkan komunikasi antara pembangun dan nod Ethereum, dan menyokong operasi seperti menyoal baki, memanggil kontrak pintar, dan menghantar transaksi. Contohnya, menyemak baki akaun hanya memerlukan beberapa baris kod, menjadikan Web3.py alat yang ideal untuk membina DApps atau mengautomasikan transaksi.

python
from web3 import Web3
w3 = Web3(Web3.HTTPProvider('你的RPC地址'))
balance = w3.eth.get_balance('0x某个地址')
print(w3.from_wei(balance, 'ether'))

RPC (Panggilan Prosedur Jauh) ialah antara muka komunikasi yang disediakan oleh nod Ethereum, yang berinteraksi dengan rantaian blok dengan menghantar permintaan JSON melalui protokol HTTP atau WebSocket. Contohnya, eth_blockNumber boleh menanyakan ketinggian blok terkini. Disebabkan oleh kos yang tinggi untuk menjalankan nod tempatan, pembangun biasanya bergantung pada penyedia RPC pihak ketiga. Pilihan biasa termasuk:

  • Infura: Perkhidmatan lalai MetaMask, mudah digunakan tetapi dengan kuota percuma yang rendah (100,000 permintaan setiap hari).
  • Alkimia: Prestasi unggul, kuota percuma yang tinggi dan sokongan untuk lebih banyak ciri.
  • QuickNode: Sesuai untuk keperluan prestasi tinggi, tetapi berat sebelah terhadap pengguna berbayar.
from web3 import Web3
w3 = Web3(Web3.HTTPProvider('https://eth-mainnet.g.alchemy.com/v2/你的API密钥'))
print(w3.is_connected())

Adalah disyorkan untuk menggunakan Alchemy. Berbanding dengan MetaMask’s Infura, Alchemy menyediakan kuota percuma yang lebih tinggi Selepas pendaftaran, anda boleh mendapatkan alamat RPC, seperti https://eth-mainnet.g.alchemy.com/v2/your API key, dan konfigurasikannya ke Web3.py untuk digunakan.

Alamat kontrak lengkung dan ABI

Mengambil kumpulan Crve sDAI/sUSDe sebagai contoh https://curve.fi/dex/ethereum/pools/factory-stable-ng-102/swap/, anda boleh mencari alamat dua token dan alamat kumpulan dengan mudah. Bagaimana untuk melaksanakan penempatan pesanan dalam pertukaran terdesentralisasi - Mengambil Curve sebagai contoh

ABI mentakrifkan cara untuk berinteraksi dengan kontrak, jadi ia juga perlu untuk mendapatkannya Lihat kontrak di ethscan https://etherscan.io/address/0x167478921b907422f8e88b43c4af2b8bea278d3a#code Anda boleh melihat abi secara langsung pada halaman kontrak dan menyalinnya.

Pautkan kontrak untuk mendapatkan harga

Pertama, pautkan dompet ETH Jika alamat dompet anda dicetak, ini bermakna ia berjaya.

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)

Berikut adalah proses mendapatkan harga Akhirnya, tanpa mengambil kira yuran GAS, pelaburan semasa sebanyak 100,000 SDAI akan menghasilkan keuntungan sebanyak 335U selepas seminggu. Ia mungkin kelihatan agak rumit, tetapi ia sebenarnya tidak sukar untuk difahami.

    # --------------- 合约设置 ---------------
    # 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))

Program Penuh

Akhir sekali, kami menggunakan undian untuk mendapatkan harga secara berterusan, dan membuat pesanan apabila keuntungan yang dijangkakan tercapaiIni hanya contoh kod, jangan guna terusPembaca mungkin menghadapi pelbagai masalah dalam amalan, tetapi AI pada masa ini sangat berkuasa dan pada asasnya boleh menjawab pelbagai soalan Ia juga secara langsung boleh membantu menulis kod FMZ juga menyepadukan ChatGPT, yang boleh digunakan dengan lebih kerap.

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)  # 出错后等待更长时间

Peringatan Risiko

Operasi dalam rantaian agak berisiko untuk orang baru Selain daripada risiko kebocoran kunci persendirian yang disebutkan di atas, terdapat pelbagai risiko lain:

  • Robot MEV mesti menetapkan minimum output min_amount_out apabila melaksanakan transaksi untuk memastikan keuntungan walaupun dalam senario terburuk, jika tidak, mereka akan dieksploitasi oleh MEV. Hari ini, seseorang menggunakan 220,000 USDC untuk menukar hanya 5272 USDT pada Uniswap Sebabnya ialah jumlahOutMinimum ditetapkan kepada 0.
  • Ralat strategi, sama seperti API pertukaran, jika terdapat pepijat dalam transaksi program dalam rantaian, GAS akan kerap digunakan.

Bagi pemula dalam perdagangan dalam rantaian, mereka perlu mempelajari asas-asas: memahami konsep seperti Gas, slippage, MEV, dll. Sentiasa mulakan dengan jumlah yang rendah dan naikkan. Pantau urus niaga menggunakan sesuatu seperti Etherscan. Lebih baik melepaskan peluang daripada mengambil risiko kehilangan modal anda.