En la carga de los recursos... Cargando...

Ethereum

En la plataforma de comercio de FMZ Quant, escribir código de estrategia para implementar la llamada de método de contrato inteligente en la cadena Ethereum a través de laexchange.IOEn primer lugar, configure el nodo de acceso en la plataforma de comercio de FMZ Quant. Los nodos de acceso pueden ser nodos auto-construidos o utilizar servicios de terceros, tales comoinfura.

Configuración del objeto de intercambio Web3

Configurar el nodo de acceso en la plataforma de comercio de FMZ Quant. Los nodos de acceso pueden ser nodos construidos por uno mismo o utilizar servicios de terceros, tales comoinfura- ¿ Por qué? En la página deCambio Plataforma de comercio de FMZ Quant, seleccione el protocolo:Criptomonedas, y luego selecciona el intercambioWeb3- ¿ Por qué? ConfiguraciónRpc Address(dirección de servicio del nodo de acceso) yPrivate KeyApoya el despliegue localizado de claves privadas, verSeguridad clave.

Registro de la ABI

Llamando a un contrato que es un estándarERC20El método no requiere registro y puede ser llamado directamente.exchange.IO("abi", tokenAddress, abiContent)¿ Qué pasa? Para obtener el contenido ABI de un contrato, puede utilizar la siguiente URL para obtenerlo, tomando elresultsólo en el campo.

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

Método de llamada de Ethereum RPC

Utilice elexchange.IO()función para llamar al método Ethereum RPC.

  • Consulta el saldo de ETH en la billetera
    exchange.IO("api", "eth", "eth_getBalance", owner, "latest")   // owner is the specific wallet address
    
  • Transferencia de ETH
    exchange.IO("api", "eth", "send", toAddress, toAmount)   // toAddress is the address of the wallet receiving ETH when transferring, toAmount is the quantity
    
  • Precio de la consulta de gas
    exchange.IO("api", "eth", "eth_gasPrice")
    
  • Encuesta et_estimateGas
    exchange.IO("api", "eth", "eth_estimateGas", data)
    

Código de soporte

La funciónexchange.IOEncapsula elencodemétodo, que puede devolver la codificación de llamada de función ahexformato de cadena. Puede consultar las plataformas accesibles al público Uniswap V3 Biblioteca de clases comerciales plantillapara un uso específico. La llamada de la codificaciónunwrapWETH9El método se utiliza aquí como ejemplo:

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)
}

Cuando se llama a laexchange.IO("encode",...)función, si el segundo parámetro (tipo de cadena) comienza con0x, significa la llamada al método en el código (encode) contrato inteligente. Si no comienza con0x, se utiliza para codificar el orden de tipo especificado.abi.encodeEn elsolidityConsulte el siguiente ejemplo.

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
    */
}

Apoya la codificación secuencial de tuples o tipos que contienen tuples:

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)
}

Este tipo de orden está compuesto por:tupleybytes, por lo que hay que pasar dos parámetros al llamarexchange.IOEn elencode:

  • Variables correspondientes al tipo tuple:
    {
        a: 30,
        b: 20,
        c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
    }
    
    Los parámetros transmitidos deben ser también coherentes con la estructura y el tipo detuple, tal como se define en eltypesParámetro:tuple(a uint256, b uint8, c address).
  • Variables correspondientes a bytes de tipo:
    "0011"
    

Soporte para la codificación secuencial de matrices o tipos que contengan matrices:

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

Soporte para encodePacked

Por ejemplo, al llamar el método DEX deUniswap V3, usted necesita pasar en los parámetros, tales como la ruta de intercambio, por lo que necesita utilizar elencodePackagedoperación:

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)
}

Apoyo para decodificar

El procesamiento de datos no sólo admite la codificación (encode), pero también de decodificación (decode) Utilizar elexchange.IO("decode", types, rawData)La función para realizar eldecode 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)
}

El ejemplo realiza laencodePackedla primera operación durante elpathEl procesamiento de parámetros, porque elexactOutputLlamada de método que necesita ser codificado más tarde necesita elpathcomo el parámetro. Entonces, elencodeel método deexactOutputel contrato de enrutamiento tiene un solo parámetro, y el tipo de parámetro estuple- ¿ Por qué? El métodoexactOutputnombre está codificado como0x09b81346, que se decodifica el resultadodecodeRawPor elexchange.IO ("decode",...)método, y es consistente con la variabledataTuple.

Soporte para cambiar claves privadas

Apoya el cambio de claves privadas para operar múltiples direcciones de billetera, por ejemplo:

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

Método para llamar al contrato inteligente

El siguiente contenido es un ejemplo de algunas llamadas de métodos de contratos inteligentes.

  • números decimales Eldecimalsel método es unconstantmétodo deERC20que no generagasEn el caso de los datos de precisión de untoken- ¿ Por qué? EldecimalsEl valor de retorno: los datos de precisión detoken.

    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
    }
    
  • el pago de una indemnización Elallowanceel método es unconstantmétodo deERC20que no generagasEn la actualidad, el consumo de energía está en aumento, y puede consultar la cantidad autorizada de un determinadotokenpara una dirección de contrato determinada. ElallowanceEl valor de retorno: el importe de la autorización de la cartera.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: La dirección de la billetera se reemplaza por la cadena owner en el ejemplo. En el uso real, debe rellenar la dirección.spender: La dirección autorizada del contrato se sustituye por la cadena spender en el ejemplo.Uniswap V3 router v1.

  • Aprobar el proyecto ElapproveEl método es un no-constantmétodo deERC20que generagasConsumo, que se utiliza para autorizar unatokenel importe de la operación a una determinada dirección del contrato. ElapproveEl método debe pasar en 2 parámetros, el primero es la dirección a autorizar y el segundo es la cantidad autorizada.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: La dirección del contrato autorizado, el ejemplo se sustituye por la cadena spender, el uso real necesita rellenar la dirección específica, por ejemplo, puede serUniswap V3 router v1 address. amount: El número de autorizaciones, representado aquí mediante una cadena hexadecimal, corresponde a un valor decimal de1e18, dividido por eltokenUnidad de precisión en el ejemplo (es decir, 1e18), que da 1token authorized.

    El tercer parámetro delexchange.IOLa función se pasa el nombre del métodoapprove, que también se puede escribir en forma demethodId, por ejemplo: 0x571ac8b0. También es posible escribir el nombre completo del método estándar, como approve(address,uint256) .

  • de llamadas múltiples ElmulticallEl método es un método no constante deUniswap V3, que generarágasConsumo y ser utilizado para intercambiar fichas de múltiples maneras. ElmulticallEl método puede tener múltiples métodos de transmisión de parámetros. Puede consultar el ABI que contiene el método para obtener detalles. Debe registrar el ABI antes de llamar al método.txid.

    Para ejemplos concretos demulticallLas llamadas de método, por favor, consulte el público Uniswap V3 Biblioteca de clases comerciales plantillade nuestra plataforma.

    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: El ABI del contrato de router v2 de Uniswap V3, debe completarse de acuerdo con la situación real.contractV3SwapRouterV2: dirección de router v2 de Uniswap V3, el uso real requiere una dirección específica para ser rellenada...value: La cantidad de ETH transferida, fijarla en 0 si eltokenInEl token para la operación de intercambio no es ETH, debe llenarse de acuerdo con la situación real.deadlineSe puede configurar en:(new Date().getTime() / 1000) + 3600, lo que significa que es válido durante una hora.data: Los datos de la operación de embalaje que se realizará, deben rellenarse de acuerdo con la situación real.

    También es posible especificar lagasLimit/gasPrice/nonceConfiguración de las llamadas de métodos:

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

    Puede establecer parámetros{gasPrice: 5000000000, gasLimit: 21000, nonce: 100}De acuerdo con sus necesidades específicas, el parámetro se establece en el último parámetro delexchange.IOla función. Puede omitir elnoncey utilizar los valores predeterminados del sistema, o no establecergasLimit/gasPrice/noncey utilizar todos los valores predeterminados del sistema.

    Debe tenerse en cuenta que en el ejemplo, el atributo destateMutabilityEn elmulticall(uint256,bytes[])el método espayable, y elvalueParámetro tiene que ser pasado en. El atributo destateMutability":"payable"se puede ver desde elABIEl.exchange.IOLa función determinará los parámetros requeridos de acuerdostateMutabilityatributo en elABIque ha sido registrado. Si elstateMutabilityel atributo esnonpayable, el parámetrovalueNo es necesario que se entregue.

Otras llamadas de funciones

  • Obtiene la dirección de la billetera configurada por el objeto de intercambio
    function main() {
        Log(exchange.IO("address"))         // Print the wallet address of the private key configured on the exchange object
    }
    
  • Cambiar los nodos RPC de la cadena de bloques
    function main() {
        var chainRpc = "https://bsc-dataseed.binance.org"
        
        // Switch to BSC chain
        e.IO("base", chainRpc)
    }
    
Instrucciones para escribir estrategias JavaScript Biblioteca integrada