В процессе загрузки ресурсов... загрузка...

Эфириум

На платформе FMZ Quant Trading, напишите код стратегии для реализации метода вызова смарт-контракта на цепочке Ethereum черезexchange.IOВ первую очередь, настроить узел доступа на платформе FMZ Quant Trading.infura.

Конфигурация объекта Web3 Exchange

конфигурировать узел доступа на платформе FMZ Quant Trading.infura- Да. На страницеобменFMZ Quant Trading Platform, выберите протокол:Криптовалюты, а затем выбирает обменWeb3- Да. КонфигурироватьRpc Address(адрес обслуживания узла доступа) иPrivate KeyОн поддерживает локальное развертывание частных ключей, см.Ключевая безопасность.

Регистрировать ABI

Название контракта, который является стандартомERC20Для вызова методов, отличных от стандартного контракта, необходимо зарегистрировать содержание ABI:exchange.IO("abi", tokenAddress, abiContent)- Да. Чтобы получить содержание ABI контракта, вы можете использовать следующий URL, чтобы получить его,resultтолько на поле.

https://api.etherscan.io/api?module=contract&action=getabi&address=0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45

Способ вызова Ethereum RPC

Используйтеexchange.IO()функция для вызова метода Ethereum RPC.

  • Запрос баланса ETH в кошельке
    exchange.IO("api", "eth", "eth_getBalance", owner, "latest")   // owner is the specific wallet address
    
  • Перевод ETH
    exchange.IO("api", "eth", "send", toAddress, toAmount)   // toAddress is the address of the wallet receiving ETH when transferring, toAmount is the quantity
    
  • Запрос газа
    exchange.IO("api", "eth", "eth_gasPrice")
    
  • Запрос eth_estimateГаз
    exchange.IO("api", "eth", "eth_estimateGas", data)
    

Код поддержки

Функцияexchange.IOвключает в себяencodeметод, который может вернуть код вызова функцииhexформат строки. Вы можете ознакомиться с публично доступными платформамиUniswap V3 Trading Class Library шаблондля особого использования. Вызов кодировкиunwrapWETH9Метод используется здесь в качестве примера:

function main() {
    // Main network address of ContractV3SwapRouterV2: 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45
    // To call the unwrapWETH9 method, you need to register the ABI first, omit the registration here.
    // "owner" represents the wallet address, it needs to fill in the specific, 1 represents the number of unwrapping, unwrap a WETH into ETH
    var data = exchange.IO("encode", "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", "unwrapWETH9(uint256,address)", 1, "owner")
    Log(data)
}

Когда вы звонитеexchange.IO("encode",...)функция, если второй параметр (тип строки) начинается с0x, это означает вызов метода на закодированный (encodeУмный контракт. Если он не начинается с0x, он используется для кодирования указанного порядка типа.abi.encodeвsolidity- Обратитесь к следующему примеру.

function main() {
    var x = 10 
    var address = "0x02a5fBb259d20A3Ad2Fdf9CCADeF86F6C1c1Ccc9"
    var str = "Hello World"
    var array = [1, 2, 3]
    var ret = exchange.IO("encode", "uint256,address,string,uint256[]", x, address, str, array)   // uint i.e. uint256 , the type length needs to be specified on FMZ
    Log("ret:", ret)
    /*
    000000000000000000000000000000000000000000000000000000000000000a    // x
    00000000000000000000000002a5fbb259d20a3ad2fdf9ccadef86f6c1c1ccc9    // address
    0000000000000000000000000000000000000000000000000000000000000080    // offset of str
    00000000000000000000000000000000000000000000000000000000000000c0    // offset of array
    000000000000000000000000000000000000000000000000000000000000000b    // the length of str
    48656c6c6f20576f726c64000000000000000000000000000000000000000000    // str data
    0000000000000000000000000000000000000000000000000000000000000003    // the length of the array
    0000000000000000000000000000000000000000000000000000000000000001    // array the first data
    0000000000000000000000000000000000000000000000000000000000000002    // array the second data
    0000000000000000000000000000000000000000000000000000000000000003    // array the third data
    */
}

Поддержка последовательного кодирования тупелей или типов, содержащих тупели:

function main() {
    var types = "tuple(a uint256,b uint8,c address),bytes"
    var ret = exchange.IO("encode", types, {
        a: 30,
        b: 20,
        c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
    }, "0011")
    Log("encode: ", ret)
}

Этот тип порядка состоит из:tupleиbytes, так что два параметра должны быть переданы при вызовеexchange.IOдоencode:

  • Переменные, соответствующие типу тупла:
    {
        a: 30,
        b: 20,
        c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
    }
    
    Переданные параметры также должны соответствовать структуре и типуtuple, как определено вtypesпараметр:tuple(a uint256, b uint8, c address).
  • Переменные, соответствующие типу байтов:
    "0011"
    

Поддержка последовательного кодирования массивов или типов, содержащих массивы:

function main() {
    var path = ["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "0xdac17f958d2ee523a2206206994597c13d831ec7"]   // ETH address, USDT address
    var ret = exchange.IO("encode", "address[]", path)
    Log("encode: ", ret)
}

Поддержка encodePacked

Например, при вызове метода DEXUniswap V3, вы должны передать в параметрах, таких как путь обмена, так что вы должны использоватьencodePackagedОперация:

function main() {
    var fee = exchange.IO("encodePacked", "uint24", 3000)
    var tokenInAddress = "0x111111111117dC0aa78b770fA6A738034120C302"
    var tokenOutAddress = "0x6b175474e89094c44da98b954eedeac495271d0f"
    var path = tokenInAddress.slice(2).toLowerCase()
    path += fee + tokenOutAddress.slice(2).toLowerCase()
    Log("path:", path)
}

Поддержка декодирования

Обработка данных не только поддерживает кодирование (encode), а также декодирования (decode) Используйтеexchange.IO("decode", types, rawData)Функция выполненияdecode operation.

function main() {
    // register SwapRouter02 abi
    var walletAddress = "0x398a93ca23CBdd2642a07445bCD2b8435e0a373f"
    var routerAddress = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"
    var abi = `[{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"internalType":"struct IV3SwapRouter.ExactOutputParams","name":"params","type":"tuple"}],"name":"exactOutput","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"}]`
    exchange.IO("abi", routerAddress, abi)   // abi only uses the contents of the local exactOutput method, the full abi can be searched on the Internet

    // encode path
    var fee = exchange.IO("encodePacked", "uint24", 3000)
    var tokenInAddress = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
    var tokenOutAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7"
    var path = tokenInAddress.slice(2).toLowerCase()
    path += fee + tokenOutAddress.slice(2).toLowerCase()
    Log("path:", path)

    var dataTuple = {
        "path" : path, 
        "recipient" : walletAddress, 
        "amountOut" : 1000, 
        "amountInMaximum" : 1, 
    }
    // encode SwapRouter02 exactOutput 
    var rawData = exchange.IO("encode", routerAddress, "exactOutput", dataTuple)
    Log("method hash:", rawData.slice(0, 8))   // 09b81346
    Log("params hash:", rawData.slice(8))

    // decode exactOutput params
    var decodeRaw = exchange.IO("decode", "tuple(path bytes,recipient address,amountOut uint256,amountInMaximum uint256)", rawData.slice(8))
    Log("decodeRaw:", decodeRaw)
}

Пример выполняетencodePackedпервой операции в течениеpathобработки параметров, посколькуexactOutputПозволение метода, который должен быть закодирован позже, требуетpathкак параметр. Затем,encodeМетодexactOutputдоговор маршрутизации имеет только один параметр, и тип параметра:tuple- Да. МетодexactOutputИмя кодируется как0x09b81346, который расшифровывает результатdecodeRawотexchange.IO ("decode",...)метод, и это соответствует переменнойdataTuple.

Поддержка переключения частных ключей

Он поддерживает переключение частных ключей для работы с несколькими адресами кошельков, например:

function main() {
    exchange.IO("key", "Private Key")   // "Private Key" represents the private key string, which needs to be filled in specifically
}

Способ вызова умного контракта

Следующее содержание является примером некоторых вызовов методов умных контрактов.

  • десятичные числа ВdecimalsМетод являетсяconstantМетодERC20что не генерируетgasС другой стороны, в этом случае можно использоватьtoken- Да. ВdecimalsВ обратном порядке значение: данные точностиtoken.

    function main(){
        var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302"    // The contract address of the token, in the example the token is 1INCH
        Log(exchange.IO("api", tokenAddress, "decimals"))                  // Query, print 1INCH tokens with precision index of 18
    }
    
  • пособие ВallowanceМетод являетсяconstantМетодERC20что не генерируетgasПотребление, и он может запросить разрешенное количество определенногоtokenдля определенного контрактного адреса. ВallowanceМетод должен пройти в 2 параметра, первый - это адрес кошелька, а второй - авторизованный адрес.token.

    function main(){
        // The contract address of the token, in the example the token is 1INCH
        var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302"            
        var owner = ""
        var spender = ""
        
        // For example, the query yields 1000000000000000000, divided by the precision unit of the token 1e18, the current exchange object bound to the wallet to the spender address authorized 1 1INCH.
        Log(exchange.IO("api", tokenAddress, "allowance", owner, spender))
    }
    

    owner: Адрес кошелька заменяется строкой owner в примере.spender: Авторизованный адрес контракта заменяется строкой spender в примере.Uniswap V3 router v1.

  • одобряю ВapproveМетод не является...constantМетодERC20что генерируетgasПотребление, которое используется для разрешенияtokenсумма операции до определенного контрактного адреса. ВapproveМетод должен пройти в 2 параметра, первый - это адрес, который должен быть разрешен, а второй - разрешенная сумма.txid.

    function main(){
        // The contract address of the token, in the example the token is 1INCH
        var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302"
        var spender = ""
        var amount = "0xde0b6b3a7640000"
        
        // The hexadecimal string of the authorization amount: 0xde0b6b3a7640000 , the corresponding decimal string: 1e18 , 1e18 divided by the precision unit of the token, i.e. 1 token amount, so this refers to the authorization of one token.
        Log(exchange.IO("api", tokenAddress, "approve", spender, amount))
    }
    

    spender: адрес уполномоченного контракта, пример заменяется строкой spender, фактическое использование необходимо заполнить конкретный адрес, например, это может бытьUniswap V3 router v1 address. amount: Количество разрешений, представленное здесь с помощью шестой десятичной строки, соответствует десятичному значению1e18, разделенный наtokenточная единица в примере (т.е. 1e18), дающая 1token authorized.

    Третий параметрexchange.IOФункция передается название методаapprove, который также может быть записан в видеmethodId, например: 0x571ac8b0. Также можно написать полное стандартное название метода, например approve(address,uint256) .

  • многократный звонок Вmulticallметод является неконстантным методомUniswap V3, что приведет кgasпотребление и использовать для обмена токенами несколькими способами. ВmulticallУ этого метода может быть несколько способов передачи параметров. Вы можете запросить ABI, содержащий метод, для получения деталей. Вам нужно зарегистрировать ABI перед вызовом метода. Возвращение значения:txid.

    Для конкретных примеровmulticallметоды вызовов, пожалуйста, обратитесь к общественностиUniswap V3 Trading Class Library шаблоннашей платформы.

    function main() {
        var ABI_Route = ""
        var contractV3SwapRouterV2 = ""
        var value = 0
        var deadline = (new Date().getTime() / 1000) + 3600
        var data = ""
        exchange.IO("abi", contractV3SwapRouterV2, ABI_Route)
        exchange.IO("api", contractV3SwapRouterV2, "multicall(uint256,bytes[])", value, deadline, data)
    }
    

    ABI_Route: ABI Uniswap V3s маршрутизатор v2 контракт, он должен быть заполнен в соответствии с фактической ситуацией.contractV3SwapRouterV2: маршрутизатор v2 адрес Uniswap V3, фактическое использование требует конкретный адрес, который должен быть заполнен...value: сумма ETH, перечисленная, установлена на 0, еслиtokenInТокен для обменной операции не ETH, он должен быть заполнен в соответствии с фактической ситуацией.deadline: Он может быть настроен на(new Date().getTime() / 1000) + 3600Это означает, что она действительна в течение часа.data: Данные о предстоящей упаковке должны быть заполнены в соответствии с фактической ситуацией.

    Также можно указатьgasLimit/gasPrice/nonceнастройка вызовов методов:

    exchange.IO("api", contractV3SwapRouterV2, "multicall(uint256,bytes[])", value, deadline, data, {gasPrice: 5000000000, gasLimit: 21000})
    

    Вы можете установить параметр{gasPrice: 5000000000, gasLimit: 21000, nonce: 100}в соответствии с вашими конкретными потребностями, параметр устанавливается на последний параметрexchange.IOФункция. Вы можете пропуститьnonceи использовать системные настройки по умолчанию, или не устанавливатьgasLimit/gasPrice/nonceи использовать все значения системы по умолчанию.

    Следует отметить, что в примере атрибутstateMutabilityвmulticall(uint256,bytes[])метод:payable, иvalueПараметр должен быть передан. АтрибутstateMutability":"payable"может быть просмотрен сABI.exchange.IOфункция будет определять необходимые параметры в соответствии сstateMutabilityатрибут вABIчто было зарегистрировано. ЕслиstateMutabilityатрибут - этоnonpayable, параметрvalueне нужно передавать.

Другие вызовы функций

  • Получает адрес кошелька, настроенного обменным объектом
    function main() {
        Log(exchange.IO("address"))         // Print the wallet address of the private key configured on the exchange object
    }
    
  • Переключайте блокчейн RPC узлов
    function main() {
        var chainRpc = "https://bsc-dataseed.binance.org"
        
        // Switch to BSC chain
        e.IO("base", chainRpc)
    }
    
Инструкции по написанию стратегии JavaScript Встроенная библиотека