O recurso está a ser carregado... Carregamento...

Ethereum

Na plataforma de negociação FMZ Quant, escrever código de estratégia para implementar a chamada de método de contrato inteligente na cadeia Ethereum através doexchange.IOPrimeiro, configure o nó de acesso na plataforma de negociação FMZ Quant. Os nós de acesso podem ser nós auto-construídos ou usar serviços de terceiros, comoinfura.

Configuração do objeto Web3 Exchange

Configurar o nó de acesso na plataforma de negociação FMZ Quant. Os nós de acesso podem ser nós auto-construídos ou usar serviços de terceiros, comoinfura- Não. Na página de Troca FMZ Quant Trading Platform, selecione o protocolo:Criptomoedas, e depois seleciona a trocaWeb3- Não. ConfiguraçãoRpc Address(endereço de serviço do nó de acesso) ePrivate Key(chave privada). Ele suporta a implantação localizada de chaves privadas, verSegurança fundamental.

Registro ABI

O que é um contrato padrão?ERC20O método não requer registro e pode ser chamado diretamente.exchange.IO("abi", tokenAddress, abiContent)- Não. Para obter o conteúdo ABI de um contrato, você pode usar o seguinte URL para obtê-lo, tomando oresultapenas em campo.

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

Método de chamada do Ethereum RPC

Utilize oexchange.IO()função para chamar o método Ethereum RPC.

  • Consultar o saldo de ETH na carteira
    exchange.IO("api", "eth", "eth_getBalance", owner, "latest")   // owner is the specific wallet address
    
  • Transferência de ETH
    exchange.IO("api", "eth", "send", toAddress, toAmount)   // toAddress is the address of the wallet receiving ETH when transferring, toAmount is the quantity
    
  • Query gasPrice
    exchange.IO("api", "eth", "eth_gasPrice")
    
  • Query eth_estimateGás
    exchange.IO("api", "eth", "eth_estimateGas", data)
    

Código de suporte

A funçãoexchange.IOEncapsula oencodemétodo, que pode retornar a codificação de chamada de função parahexformato de cadeia. Pode consultar as plataformas acessíveis ao público Uniswap V3 Trading Class Library modelopara utilização específica. A chamada da codificaçãounwrapWETH9método é usado aqui como exemplo:

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

Ao ligar para oexchange.IO("encode",...)função, se o segundo parâmetro (tipo de string) começar com0x, significa a chamada do método no código (encode) contrato inteligente. Se não começar com0x, é utilizado para codificar a ordem de tipo especificada.abi.encodeemsolidity. Consulte o seguinte exemplo.

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

Suporte à codificação sequencial de tuplas ou tipos contendo tuplas:

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

Esta ordem de tipo é composta por:tupleebytes, então dois parâmetros precisam ser passados quando chamadosexchange.IOparaencode:

  • Variaveis correspondentes a tupla de tipo:
    {
        a: 30,
        b: 20,
        c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
    }
    
    Os parâmetros transmitidos devem igualmente ser coerentes com a estrutura e o tipo detuple, tal como definido notypesParâmetro:tuple(a uint256, b uint8, c address).
  • Variaveis correspondentes a bytes de tipo:
    "0011"
    

Suporte para codificação sequencial de matrizes ou tipos que contenham matrizes:

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

Suporte para encodePacked

Por exemplo, ao chamar o método DEX deUniswap V3, você precisa passar em parâmetros, tais como o caminho de troca, então você precisa usar oencodePackagedOperação:

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

Suporte para decodificação

O processamento de dados não só suporta a codificação (encode), mas também a decodificação (decode) Utilize oexchange.IO("decode", types, rawData)função para executar odecode 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)
}

O exemplo executa oencodePackedA primeira operação durante opathProcessamento de parâmetros, porque oexactOutputchamada de método que precisa ser codificada mais tarde precisa dopathcomo o parâmetro. Em seguida, oencodeMétodo deexactOutputcontrato de roteamento tem apenas um parâmetro, e o tipo de parâmetro étuple- Não. MétodoexactOutputnome é codificado como0x09b81346, que é decodificado o resultadodecodeRawporexchange.IO ("decode",...)método, e é consistente com a variáveldataTuple.

Suporte para troca de chaves privadas

Ele suporta a troca de chaves privadas para operar vários endereços de carteira, por exemplo:

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

Método de chamada do contrato inteligente

O seguinte conteúdo é um exemplo de algumas chamadas de métodos de contrato inteligente.

  • números decimais OdecimalsO método éconstantmétodo deERC20que não geramgasA utilização de dados de precisão de um computadortoken- Não. OdecimalsValor de retorno: os dados de precisão 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
    }
    
  • subsídio OallowanceO método éconstantmétodo deERC20que não geramgasA Comissão considera que a Comissão não pode, por conseguinte,tokenpara um determinado endereço contratual. OallowanceRetorno de valor: o valor de autorização de uma carteira é o valor de uma carteira.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: O endereço da carteira é substituído pela cadeia owner no exemplo.spenderNo exemplo, o endereço do contrato autorizado é substituído pela cadeia spender.Uniswap V3 router v1.

  • Aprovar OapproveO método é um não-constantmétodo deERC20que geragasConsumo, que é utilizado para autorizar umatokenO montante da operação para um determinado endereço contratual. OapproveO método precisa passar em 2 parâmetros, o primeiro é o endereço a ser autorizado e o segundo é o montante autorizado.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: O endereço do contrato autorizado, o exemplo é substituído pela cadeia spender, o uso real precisa preencher o endereço específico, por exemplo, pode serUniswap V3 router v1 address. amount: O número de autorizações, representado aqui por uma cadeia hexadecimal, corresponde a um valor decimal de1e18, dividido pelotokenunidade de precisão no exemplo (ou seja, 1e18), dando 1token authorized.

    O terceiro parâmetro doexchange.IOfunção é passada o nome do métodoapprove, que também pode ser escrito na forma demethodId, por exemplo: 0x571ac8b0. Também é possível escrever o nome completo do método padrão, como approve(address,uint256) .

  • Multicall Omulticallmétodo é um método não constante deUniswap V3, que irá gerargasConsumo e ser usado para trocar tokens de várias maneiras. OmulticallO método pode ter vários métodos de passagem de parâmetros. Você pode consultar o ABI contendo o método para obter detalhes. Você precisa registrar o ABI antes de chamar o método. Retorno de valor:txid.

    Para exemplos específicos demulticallAplicação do método de chamadas. Uniswap V3 Trading Class Library modeloda nossa 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: O ABI do contrato V2 do roteador Uniswap V3, precisa ser preenchido de acordo com a situação real.contractV3SwapRouterV2: endereço do roteador v2 do Uniswap V3, o uso real requer um endereço específico para ser preenchido...value: O montante de ETH transferido, definido em 0 se otokenIntoken para a operação de troca não é ETH, ele precisa ser preenchido de acordo com a situação real.deadline: Pode ser definido como(new Date().getTime() / 1000) + 3600, o que significa que é válido por uma hora.data: Os dados da operação de embalagem a realizar, devem ser preenchidos de acordo com a situação real.

    É também possível especificar ogasLimit/gasPrice/nonceConfiguração das chamadas de métodos:

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

    Você pode definir parâmetro{gasPrice: 5000000000, gasLimit: 21000, nonce: 100}De acordo com as suas necessidades específicas, o parâmetro é definido para o último parâmetro doexchange.IOfunção. Pode omitir ononcee usar os padrões do sistema, ou não definirgasLimit/gasPrice/noncee usar todos os valores padrão do sistema.

    Deve notar-se que no exemplo, o atributo destateMutabilityemmulticall(uint256,bytes[])método épayable, e ovalueParâmetro precisa ser passado. O atributo destateMutability":"payable"A partir daí, oABI. Oexchange.IOA função irá determinar os parâmetros necessários de acordo com ostateMutabilityatributo noABIque foi registado. Se ostateMutabilityatributo énonpayable, o parâmetrovaluenão precisa de ser transmitido.

Outras chamadas de função

  • Obtém o endereço da carteira configurada pelo objeto de troca
    function main() {
        Log(exchange.IO("address"))         // Print the wallet address of the private key configured on the exchange object
    }
    
  • Mudar os nós RPC da blockchain
    function main() {
        var chainRpc = "https://bsc-dataseed.binance.org"
        
        // Switch to BSC chain
        e.IO("base", chainRpc)
    }
    
Instruções de Escrita de Estratégia JavaScript Biblioteca integrada