Les ressources ont été chargées... Je charge...

Éthereum

Sur la plateforme de trading FMZ Quant, écrivez un code de stratégie pour implémenter l'appel de méthode du contrat intelligent sur la chaîne Ethereum via leexchange.IOLes nœuds d'accès peuvent être des nœuds auto-construits ou utiliser des services tiers, tels queinfura.

Configuration de l'objet Web3 Exchange

configurer le nœud d'accès sur la plate-forme de trading FMZ Quant. Les nœuds d'accès peuvent être des nœuds auto-construits ou utiliser des services tiers, tels queinfura- Je ne sais pas. Sur la page deÉchange FMZ Quant Trading Platform, sélectionnez le protocole:Crypto-monnaie, puis sélectionne l' échangeWeb3- Je ne sais pas. ConfigurationRpc Address(adresse de service du nœud d'accès) etPrivate KeyIl prend en charge le déploiement local de clés privées, voirLa sécurité est essentielle.

Enregistrer l'ABI

Appeler un contrat qui est une normeERC20L'appel des méthodes autres que le contrat standard nécessite l'enregistrement du contenu ABI:exchange.IO("abi", tokenAddress, abiContent)Je suis désolée. Pour obtenir le contenu ABI d'un contrat, vous pouvez utiliser l'URL suivante pour l'obtenir, en prenant leresultseulement sur le terrain.

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

Méthode d'appel d'Ethereum RPC

Utilisez leexchange.IO()fonction pour appeler la méthode Ethereum RPC.

  • Rechercher le solde d'ETH dans le portefeuille
    exchange.IO("api", "eth", "eth_getBalance", owner, "latest")   // owner is the specific wallet address
    
  • Transfert de l'ETH
    exchange.IO("api", "eth", "send", toAddress, toAmount)   // toAddress is the address of the wallet receiving ETH when transferring, toAmount is the quantity
    
  • Renseignez-vous sur le prix du gaz
    exchange.IO("api", "eth", "eth_gasPrice")
    
  • Demande d'éth_estimationGas
    exchange.IO("api", "eth", "eth_estimateGas", data)
    

Code de support

La fonctionexchange.IOencapsule leencodeméthode, qui peut renvoyer le codage d'appel de fonction àhexle format de chaîne. Vous pouvez consulter les plateformes accessibles au public Uniswap V3 Bibliothèque de classes de négociation modèlepour une utilisation spécifique. L'appel du codageunwrapWETH9la méthode est utilisée ici à titre d'exemple:

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

Lorsque vous appelez leexchange.IO("encode",...)fonction, si le deuxième paramètre (type de chaîne) commence par0x, il s'agit de l'appel à la méthode sur le code (encodeLe contrat intelligent. Si elle ne commence pas par0x, il est utilisé pour coder l'ordre de type spécifié.abi.encodedans lesolidity. Consultez l'exemple suivant.

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

Prise en charge de l'encodage séquentiel de tuples ou de types contenant des 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)
}

Cet ordre de type est composé de:tupleetbytes, donc deux paramètres doivent être passés en appelantexchange.IOàencode:

  • Variables correspondant à une tuple de type:
    {
        a: 30,
        b: 20,
        c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
    }
    
    Les paramètres transmis doivent également être conformes à la structure et au type detuple, au sens de la définitiontypesparamètre:tuple(a uint256, b uint8, c address).
  • Variables correspondant à des bytes de type:
    "0011"
    

Prise en charge du codage séquentiel de tableaux ou de types contenant des tableaux:

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

Prise en charge de encodePacked

Par exemple, lorsque l'on appelle la méthode DEX deUniswap V3, vous devez passer dans les paramètres, tels que le chemin d'échange, de sorte que vous devez utiliser leencodePackagedopération:

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

Prise en charge du décodage

Le traitement des données n'est pas seulement compatible avec le codage (encode), mais aussi de décoder (decodeUtilisez leexchange.IO("decode", types, rawData)fonction d'effectuer ledecode 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)
}

L'exemple réalise leencodePackedLa première opérationpathLe traitement des paramètres,exactOutputL'appel de méthode qui doit être codé plus tard nécessite lepathcomme paramètre. Ensuite, leencodeméthode deexactOutputle contrat de routage ne comporte qu'un seul paramètre, et le type de paramètre esttuple- Je ne sais pas. La méthodeexactOutputnom est codé comme0x09b81346, qui est décodé le résultatdecodeRawparexchange.IO ("decode",...)méthode, et il est cohérent avec la variabledataTuple.

Prise en charge de la commutation des clés privées

Il prend en charge la commutation de clés privées pour utiliser plusieurs adresses de portefeuille, par exemple:

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

Méthode d'appel du contrat intelligent

Le contenu suivant est un exemple de certains appels de méthode de contrat intelligent.

  • décimales Ledecimalsla méthode est uneconstantméthode deERC20qui ne génère pasgasIl est également capable de consulter les données de précision d'untoken- Je ne sais pas. LedecimalsLa valeur de retour: les données de précision 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
    }
    
  • allocation Leallowancela méthode est uneconstantméthode deERC20qui ne génère pasgasIl est possible d'obtenir des informations sur la quantité autorisée d'un certaintokenpour une certaine adresse contractuelle. LeallowanceLa méthode doit passer en 2 paramètres, le premier est l'adresse du portefeuille, et le second est l'adresse autorisée.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: L'adresse du portefeuille est remplacée par la chaîne owner dans l'exemple.spender: L'adresse du contrat autorisé est remplacée par la chaîne spender dans l'exemple.Uniswap V3 router v1.

  • approuver LeapproveLa méthode est un non-constantméthode deERC20qui génèregasLa consommation, qui est utilisée pour autoriser untokenLe montant de l'opération correspond à une certaine adresse contractuelle. LeapproveLa méthode doit passer en 2 paramètres, le premier est l'adresse à autoriser et le second est le montant autorisé.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: l'adresse du contrat autorisé, l'exemple est remplacé par la chaîne spender, l'utilisation réelle doit remplir l'adresse spécifique, par exemple, il peut êtreUniswap V3 router v1 address. amount: Le nombre d'autorisations, représenté ici par une chaîne hexadécimale, correspond à une valeur décimale de1e18, divisé par letokenunité de précision dans l'exemple (c'est-à-dire 1e18), donnant 1token authorized.

    Le troisième paramètre de laexchange.IOla fonction est passée le nom de la méthodeapprove, qui peut aussi s' écrire sous la formemethodId, par exemple: 0x571ac8b0. Il est également possible d'écrire le nom complet de la méthode standard, par exemple approuver(adresse,uint256) .

  • appels multiples LemulticallLa méthode est une méthode non constante deUniswap V3, qui généreragasIl peut être utilisé pour échanger des jetons de plusieurs façons. LemulticallLa méthode peut avoir plusieurs méthodes de transmission de paramètres. Vous pouvez interroger l'ABI contenant la méthode pour obtenir des détails. Vous devez enregistrer l'ABI avant d'appeler la méthode. Retourner la valeur:txid.

    Pour des exemples spécifiques demulticallappels de méthode, veuillez vous référer au public Uniswap V3 Bibliothèque de classes de négociation modèlede notre plateforme.

    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: L'ABI du contrat V2 du routeur Uniswap V3 doit être rempli en fonction de la situation réelle.contractV3SwapRouterV2: l'adresse du routeur v2 de Uniswap V3, l'utilisation réelle nécessite une adresse spécifique à remplir...value: le montant de l'ETH transféré, le régler à 0 si letokenInLe jeton pour l'opération d'échange n'est pas ETH, il doit être rempli en fonction de la situation réelle.deadline: Il peut être réglé sur(new Date().getTime() / 1000) + 3600, ce qui signifie qu'il est valable une heure.data: les données relatives à l'opération d'emballage à effectuer; elles doivent être remplies en fonction de la situation réelle.

    Il est également possible de spécifier legasLimit/gasPrice/nonceréglage des appels de méthode:

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

    Vous pouvez définir le paramètre{gasPrice: 5000000000, gasLimit: 21000, nonce: 100}Selon vos besoins spécifiques, le paramètre est réglé sur le dernier paramètre duexchange.IOfonction. Vous pouvez omettrenonceet utiliser les paramètres du système, ou ne pas définirgasLimit/gasPrice/nonceet utiliser toutes les valeurs par défaut du système.

    Il convient de noter que dans l'exemple, l'attribut destateMutabilitydansmulticall(uint256,bytes[])la méthode estpayable, et levalueLe paramètre doit être passé. L'attribut destateMutability":"payable"peut être vue depuis leABILeexchange.IOLa fonction déterminera les paramètres requis en fonction de lastateMutabilityattribut dans leABIqui a été enregistrée. Si lestateMutabilityl'attribut estnonpayable, le paramètrevaluen'a pas besoin d'être transmis.

Autres appels de fonction

  • Obtient l'adresse du portefeuille configuré par l'objet d'échange
    function main() {
        Log(exchange.IO("address"))         // Print the wallet address of the private key configured on the exchange object
    }
    
  • Commutez les nœuds RPC de la chaîne de blocs
    function main() {
        var chainRpc = "https://bsc-dataseed.binance.org"
        
        // Switch to BSC chain
        e.IO("base", chainRpc)
    }
    
Instructions pour écrire une stratégie JavaScript Bibliothèque intégrée