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

Commencez avec le développement web3 facilement basé sur Ethereum en utilisant FMZ

Auteur:FMZ~Lydia, Créé: 2023-06-25 09:17:53, Mis à jour: 2024-11-11 22:34:49

[TOC] Je vous en prie.

img

Commencez avec le développement web3 facilement basé sur Ethereum en utilisant FMZ

Le tutoriel EtherEaseWithFMZ

Commencez avec le développement web3 basé sur Ethereum en utilisant FMZ facilement

Ethereum est une plateforme de contrats intelligents basée sur la technologie blockchain, qui fournit un moyen décentralisé d'écrire et de déployer des contrats intelligents.

Plateforme de négociation quantitative FMZ (FMZ.COMIl permet d'accéder aux échanges décentralisés (DEX), d'obtenir des données sur la chaîne, d'envoyer des transactions et d'autres fonctions.

Dans ce tutoriel, les exemples sont écrits enJavaScriptL'environnement de test utilise à la foisRéseau principal EthereumetRéseau de test de Goerli. Et vous pouvez également voir les interfaces API et les descriptions connexes, des exemples de code utilisés dans le tutoriel dans la documentation API de la plateforme FMZ.


Le FMZ est lancé

Avant d'apprendre à utiliser la plateforme de trading FMZ Quant, nous devons nous familiariser avec quelques concepts de base:

1. L'architecture de la plateforme de négociation quantique FMZ

Après s'être inscrit et connecté sur le site officiel de la plateforme de négociation quantitative FMZ (https://www.fmz.comLe programme de logiciel de docker peut être déployé sur divers appareils, tels que des serveurs, des ordinateurs, etc. Lorsqu'un utilisateur écrit un programme et crée une instance en cours d'exécution sur le site Web de FMZ, la plate-forme FMZ communique avec le docker et démarre une instance de programme sur celui-ci.

2. Docker

Si vous souhaitez exécuter une instance de programme, vous devez déployer un docker. Le déploiement du docker est également très simple, et il existe des tutoriels de déploiement sur la plateforme. Vous pouvez également utiliser le One-click Deployment fourni par FMZ pour le déployer automatiquement sur des serveurs loués pour le compte de FMZ.

  • Déployer le docker sur les appareils personnels

Vous pouvez déployer et exécuter le programme docker sur des serveurs, des ordinateurs personnels et d'autres appareils, tant que le réseau est normal (besoin d'avoir accès à la cible correspondante, telle qu'une certaine interface d'échange, une adresse de nœud, etc.).

  1. Connectez-vous ou ouvrez l'appareil où le programme docker doit être déployé, par exempleconnexion à un serveurouallumer un ordinateur pour entrer dans le système d'exploitation.
  2. Télécharger la version correspondante du programme docker (selon le système d'exploitation du périphérique), page de téléchargement:https://www.fmz.com/m/add-node

img

  1. Ce que vous avez téléchargé est un paquet comprimé, il faut le décompresser.
  2. Exécutez le programme docker, le programme docker est un fichier exécutable appelérobot. Configurez l'adresse de communication docker, qui est unique pour chaque compte FMZ, après vous être connecté à FMZ, vous pouvez voir votre propre adresse àhttps://www.fmz.com/m/add-nodepage (c'est-à-dire./robot -s node.fmz.com/xxxxxcette chaîne d'adresses, où le contenu àxxxxxLa position est différente pour chaque compte FMZ). Enfin, vous devez entrer le mot de passe de votre compte FMZ. Après avoir configuré ces paramètres, exécutez le programme docker.
  • Utilisez la fonction de déploiement en un clic de la plateforme FMZ

    Ajoutez une page d'accueil sur la plateforme FMZ, adresse:https://www.fmz.com/m/add-node

    img

3. Outil de débogage

FMZ Quant Trading Platform fournit un outil de débogage gratuit qui prend en chargeJavaScript, TypeScript, et la page est:https://www.fmz.com/m/debug. Parce que la création d'instances à exécuter est facturée. Pendant la période d'apprentissage initiale, vous pouvez utiliser cet outil de débogage pour les tests et l'apprentissage. À l'exception de la limite maximale de temps d'exécution de 3 minutes, il n'y a aucune différence entre l'utilisation de l'outil de débogage et la création d'une instance à exécuter.

Lorsque vous utilisezTypeScriptLe langage, vous devez écrire// @ts-checksur la première ligne de code à passer àTypeScriptmode; s'il n'est pas commuté, le mode par défaut estJavaScript language.

4. Plateformes

Sur FMZ, Platform est un concept général. Pour les échanges CEX, il fait référence à une configuration de compte d'échange spécifique. Pour web3, cet échange fait référence à une information de configuration qui comprend l'adresse du nœud et la configuration de la clé privée.

Dans l'état de connexion de la plateforme FMZ, àhttps://www.fmz.com/m/add-platformpage, vous pouvez configurer des informations d'échange, où l'échange est un concept général.

img

SélectionnezWeb3, configurer l'adresse du nœud RPC, configurer la clé privée, vous pouvez cliquer sur le coin inférieur droit Les informations sensibles seront stockées cryptées pour afficher le mécanisme de sécurité.

Les nœuds peuvent être des nœuds auto-construits ou des nœuds fournis par des fournisseurs de services de nœuds.Infure. Après l'enregistrement, vous pouvez voir l'adresse du nœud de votre propre compte. Le mainnet et le testnet sont tous deux disponibles, ce qui est très pratique.Rpc AddressL'étiquette peut être nommée par vous-même pour distinguer les objets d'échange configurés.

img

Dans la photo,https://mainnet.infura.io/v3/xxxxxxxxxxxxxest l'adresse privée du nœud RPC du réseau principal Infura ETH.


Interagir avec Ethereum en utilisant FMZ

Après avoir déployé le programme docker et configuré l'objet d'échange, vous pouvez utiliserFMZ.COMs Debugging Tool pour les tests. Appeler les méthodes Ethereum RPC et interagir avec Ethereum, en plus des plusieurs méthodes RPC énumérées et introduites dans ce chapitre, d'autres méthodes RPC peuvent être trouvées en consultant des matériaux, tels quehttps://www.quicknode.com/docs.

Pour différents langages et outils, il existe des moyens d'accéder au web3, comme indiqué sur l'image:

img

Sur FMZ, les appels à la méthode RPC sont également encapsulés, et ces fonctions sont encapsulées dans la fonction FMZ APIexchange.IOLa méthode d'appel estexchange.IO("api", "eth", ...). Le premier paramètre est fixé à"api", le deuxième paramètre est fixé à"eth", et d'autres paramètres dépendent de la méthode RPC spécifique appelée.

Pour les informations de sortie, nous utiliserons leLogLa fonction de la plateforme FMZLogfonction peut accepter plusieurs paramètres et ensuite les produire dans la zone de journal de la page Debug Tool ou Bot sur la plateforme FMZ.

eth_getBalance

Leeth_getBalancela méthode d'Ethereum est utilisée pour interroger le solde ETH d'une adresse sur Ethereum, et cette méthode nécessite deux paramètres.

  • L'adresse à vérifier.
  • Sur l'étiquette, on utilise habituellement le dernier . Voyons le fondateur d'Ethereum.Vitalik Buterinl'adresse du portefeuille ETH, l'adresse connue est:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045.
function main() {
    let ethBalance = exchange.IO("api", "eth", "eth_getBalance", "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest")
    Log("ethBalance:", ethBalance)
}

Déjà déployé le docker (sur l'image: linux/amd64...) et configuré l'objet d'échange (sur l'image: test Web3), code de test dans le débogage outil:

img

Cliquez sur le bouton Execute pour exécuter le code et afficher les résultats:

Le bilan est le suivant: 0x117296558f185bbc4c6

Lelogfonction imprime leethBalancela valeur de la variable est:0x117296558f185bbc4c6, qui est un type de chaîne.la valeur hexadécimale du solde ETHdansweiunités, avec1e18 weiétant égal à 1ETHPar conséquent, il doit être converti pour devenir un solde décimal ETH lisible.

ConversionethBalancedans des données lisibles:

function main() {
    let ethBalance = exchange.IO("api", "eth", "eth_getBalance", "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest")
    Log("ethBalance:", ethBalance)
    
    // Converting ethBalance into readable data
    let vitalikEthBalance = parseInt(ethBalance.substring(2), 16) / 1e18
    Log("vitalikEthBalance:", vitalikEthBalance)
}

Recherche en courshttps://etherscan.io/:

img

Cependant, en raison du problème de précision du langage lui-même, il y aura des écarts dans cette façon de traitement.

  • BigInt: Convertir une chaîne hexadécimale en un objet BigInt.
  • BigDecimal: Convertir les objets de type numérique en objets BigDecimal computables.

Ajustez le code à nouveau:

function main() {
    let ethBalance = exchange.IO("api", "eth", "eth_getBalance", "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest")

    // The precision unit of ETH is 1e18
    let ethDecimal = 18
    Log("vitalikEthBalance:", Number((BigDecimal(BigInt(ethBalance)) / BigDecimal(Math.pow(10, ethDecimal))).toString()))
}

Le bilan est de 5149,6244846875215.

eth_chainId

eth_chainIdetnet_versionCes deux fonctions renvoient l'id de la blockchain à laquelle le nœud RPC actuel est connecté, la différence étant quenet_versionrenvoie un Id décimal eteth_chainIdrenvoie un ID hexadécimal.

Nom du réseau correspondant à chaîneId

1 - ethereum mainnet
2 - morden testnet (deprecated)
3 - ropsten testnet
4 - rinkeby testnet
5 - goerli testnet
11155111 - sepolia testnet
10 - optimism mainnet
69 - optimism kovan testnet
42 - kovan testnet
137 - matic/polygon mainnet
80001 - matic/polygon mumbai testnet
250 - fantom mainnet
100 - xdai mainnet
56 - bsc mainnet

Testez avec le réseau de test Ethereum configurégoerlinœud:

function main() {
    let netVersionId = exchange.IO("api", "eth", "net_version")
    let ethChainId = exchange.IO("api", "eth", "eth_chainId")

    Log("netVersionId:", netVersionId)
    Log("ethChainId:", ethChainId, " , conversion:", parseInt(ethChainId.substring(2), 16))
}

prix du gaz eth_gas

Appelez leeth_gasPriceméthode pour interroger le courantgas pricesur la chaîne.

function toAmount(s, decimals) {
    return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}

function main() {
    let gasPrice = exchange.IO("api", "eth", "eth_gasPrice")
    Log("gasPrice:", gasPrice, " , conversion:", toAmount(gasPrice, 0))
}

Ici, nous écrivons une fonction pour convertir la chaîne hexadécimale en une valeur numérique lisible:toAmountEn outre, il convient de noter que l'unité degasPriceestwei, donc passer la valeur 0 au paramètre réel correspondant au paramètre formeldecimals.

eth_blockNombre

"eth_blockNumberest utilisé pour interroger la hauteur du bloc.

function toAmount(s, decimals) {
    return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}

function main() {
    let blockNumber = exchange.IO("api", "eth", "eth_blockNumber")
    Log(toAmount(blockNumber, 0))
}

Exécutez l' outil de débogage:

img

Recherche en courshttps://etherscan.io/:

img

eth_getBlockByNumber

Informations sur le bloc de requête.

function main() {
    let blockNumber = exchange.IO("api", "eth", "eth_blockNumber")    
    Log(blockNumber)
    let blockMsg = exchange.IO("api", "eth", "eth_getBlockByNumber", blockNumber, true)
    Log(typeof(blockMsg), blockMsg)
    
    // Due to the excessive content of Log output, it will be truncated automatically, so traverse each field of the returned block information and print them one by one
    for (let key in blockMsg) {
        Log("key:", key, ", val:", blockMsg[key])
    }
}

L'exécution dans l'outil de débogage peut obtenir les informations suivantes:

img

Lire les informations relatives au contrat

Beaucoup d'applications de contrats intelligents fonctionnent sur Ethereum etENSest l'un d'entre eux.ENS, ou Ethereum Name Service, est un service décentralisé de résolution de noms de domaine basé sur la blockchain Ethereum. Vous souvenez-vous de l'exemple du tutoriel où nous avons vérifié le solde du portefeuille du fondateur d'Ethereum Vitalik Buterin?0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045- Alors comment savons-nous l'adresse?ENSun contrat intelligent avec un nom intuitifvitalik.eth.

Le contenu suivant dans ce chapitre utilise l'environnement Ethereum mainnet, selon leENSla documentation,Hashing Namessont nécessaires pour interroger les noms de domaine Ethereum. Utilisez le code suivant pour traitervitalik.eth.

function nameHash(name) {
    if (name == "") {
        return "0000000000000000000000000000000000000000000000000000000000000000"
    } else {
        let arr = name.split(".")
        let label = arr[0]
        
        arr.shift()
        let remainder = arr.join(".")
        return Encode("sha3.keccak256", "hex", "hex", nameHash(remainder) + Encode("sha3.keccak256", "raw", "hex", label))
    }
}

Dans l'exemple de code ci-dessus, nous avons vu une autre fonction inconnueEncodeCette fonction est une fonction API de la plateforme FMZ et est spécifiquement utilisée pour encoder des opérations sur la plateforme FMZ.

Encode(algo, inputFormat, outputFormat, data, keyFormat, key string)

Conformément à la description contenue dans le document ENS, utilisezsha3.keccak256algorithme pour traiter les données.

Appelez lenameHashfonction, par exemple:Log(nameHash("vitalik.eth")), vous pouvez obtenir:ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835, et vous devez ajouter le préfixe 0x.0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835est utilisé comme paramètre duresolverméthode dans le contrat intelligent ENS.

let ensNode = "0x" + nameHash("vitalik.eth")    // Prepare the parameters ensNode for calling the resolver method

Selon la documentation ENS, l'adresse du contrat pour les applications de contrats intelligents ENS est la suivante:0x00000000000C2E074eC69A0dFb2997BA6C7d2e1eAvant d' appeler leresolverLa méthode de l'accord intelligent, nous devons également préparer laABIdu contrat.

Enregistrer l'ABI

En apprenant cela, vous vous demandez peutêtre:ABId'un contrat intelligent?

ABI, or Application Binary Interface, is the interface standard for smart contracts to communicate with the external world.
The ABI of a smart contract defines the contract's function interfaces, parameter types, return values, and other information, as well as specifications for calling the contract and passing parameters.

The ABI of a smart contract is usually stored in JSON format and contains the following information:

Contract function interfaces: function names, parameter lists, return values, etc.
Function parameter types: such as uint256, bool, string etc.
Encoding methods for input and output parameters of functions: Smart contracts use an encoding method called Solidity ABI to encode input and output parameters of functions so that they can interact with Ethereum network.
In Ethereum network ,the ABI of a smart contract is used to call its functions. When you need to call a contract function, you need to provide the name of the function, its parameters, and bytecode encoded according to ABI encoding method.
Ethereum nodes will package this information into transactions and send them out on Ethereum network for execution.

In Solidity language,the keyword 'interface' can be used define ABIs for smart contracts. Ethereum development tools like Remix IDE ,Truffle also provide editing & generation tools making it easier developers create & use ABIs.

Extraire leresolverVous pouvez consulter l'ABI du contrat surhttps://etherscan.io/ou obtenir l'ABI par d'autres voies (par exemple, la documentation pertinente du projet).

img

let abiENS_resolver = `[{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"resolver","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]`

Ici, nous allons apprendre une nouvelle méthode d'invocation sur la plateforme FMZ,exchange.IO("abi", address, abiContent), qui est utilisé pour enregistrer l'ABI.addressParamètre est l'adresse du contrat intelligent et leabiContentle paramètre est le contrat intelligent correspondant ABI (chaîne).

let abiENS_resolver = `[{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"resolver","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]`
exchange.IO("abi", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", abiENS_resolver)  // 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e is the address of the ENS smart contract deployed on the Ethereum mainnet

Méthodes d'appel des contrats intelligents

Ensuite, vous pouvez appelerresolverLa méthode du contrat intelligent ENS, qui renvoie l'adresse duENS: Public Resolver contract.

img

let resolverAddress = exchange.IO("api", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", "resolver", ensNode)

Utilisez leENS: Public ResolverLes contratsaddrPour obtenir l'adresse du portefeuille de Vitalik Buterin.ENS: Public ResolverLes informations ABI pour ce contrat intelligent peuvent toujours être obtenues à partir dehttps://etherscan.io/.

let abiENSPublicResolver = `[{"inputs":[{"internalType":"contract ENS","name":"_ens","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"contentType","type":"uint256"}],"name":"ABIChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"a","type":"address"}],"name":"AddrChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"coinType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newAddress","type":"bytes"}],"name":"AddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bool","name":"isAuthorised","type":"bool"}],"name":"AuthorisationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"hash","type":"bytes"}],"name":"ContenthashChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"resource","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"record","type":"bytes"}],"name":"DNSRecordChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"resource","type":"uint16"}],"name":"DNSRecordDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"DNSZoneCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"bytes4","name":"interfaceID","type":"bytes4"},{"indexed":false,"internalType":"address","name":"implementer","type":"address"}],"name":"InterfaceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"NameChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"x","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"y","type":"bytes32"}],"name":"PubkeyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"string","name":"indexedKey","type":"string"},{"indexed":false,"internalType":"string","name":"key","type":"string"}],"name":"TextChanged","type":"event"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"contentTypes","type":"uint256"}],"name":"ABI","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"addr","outputs":[{"internalType":"address payable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"coinType","type":"uint256"}],"name":"addr","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"authorisations","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"clearDNSZone","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"contenthash","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"name","type":"bytes32"},{"internalType":"uint16","name":"resource","type":"uint16"}],"name":"dnsRecord","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"name","type":"bytes32"}],"name":"hasDNSRecords","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"interfaceImplementer","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"pubkey","outputs":[{"internalType":"bytes32","name":"x","type":"bytes32"},{"internalType":"bytes32","name":"y","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"contentType","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setABI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"coinType","type":"uint256"},{"internalType":"bytes","name":"a","type":"bytes"}],"name":"setAddr","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"a","type":"address"}],"name":"setAddr","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"isAuthorised","type":"bool"}],"name":"setAuthorisation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"hash","type":"bytes"}],"name":"setContenthash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setDNSRecords","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes4","name":"interfaceID","type":"bytes4"},{"internalType":"address","name":"implementer","type":"address"}],"name":"setInterface","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"name","type":"string"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"x","type":"bytes32"},{"internalType":"bytes32","name":"y","type":"bytes32"}],"name":"setPubkey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"key","type":"string"},{"internalType":"string","name":"value","type":"string"}],"name":"setText","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"key","type":"string"}],"name":"text","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}]`
exchange.IO("abi", resolverAddress, abiENSPublicResolver)

img

Enfin, appelez leENS: Public ResolverLes contratsaddrméthode, le paramètre étant toujoursensNode.

let vitalikAddress = exchange.IO("api", resolverAddress, "addr", ensNode)
Log("vitalikAddress:", vitalikAddress)

Sortie de la fonction log:

vitalikAddress: 0xd8da6bf26964af9d7eed9e03e53415d37aa96045

Appelez le code complet du SNE

function nameHash(name) {
    if (name == "") {
        return "0000000000000000000000000000000000000000000000000000000000000000"
    } else {
        let arr = name.split(".")
        let label = arr[0]
        
        arr.shift()
        let remainder = arr.join(".")
        return Encode("sha3.keccak256", "hex", "hex", nameHash(remainder) + Encode("sha3.keccak256", "raw", "hex", label))
    }
}

function main() {
    // Calculate the name
    let ensNode = "0x" + nameHash("vitalik.eth")    

    // Register ENS contract
    let abiENS_resolver = `[{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"resolver","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]`
    exchange.IO("abi", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", abiENS_resolver)
    let resolverAddress = exchange.IO("api", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", "resolver", ensNode)
    
    // Register ENS Public Resolver contract
    let abiENSPublicResolver = `[{"inputs":[{"internalType":"contract ENS","name":"_ens","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"contentType","type":"uint256"}],"name":"ABIChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"a","type":"address"}],"name":"AddrChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"coinType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newAddress","type":"bytes"}],"name":"AddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bool","name":"isAuthorised","type":"bool"}],"name":"AuthorisationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"hash","type":"bytes"}],"name":"ContenthashChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"resource","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"record","type":"bytes"}],"name":"DNSRecordChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"resource","type":"uint16"}],"name":"DNSRecordDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"DNSZoneCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"bytes4","name":"interfaceID","type":"bytes4"},{"indexed":false,"internalType":"address","name":"implementer","type":"address"}],"name":"InterfaceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"NameChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"x","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"y","type":"bytes32"}],"name":"PubkeyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"string","name":"indexedKey","type":"string"},{"indexed":false,"internalType":"string","name":"key","type":"string"}],"name":"TextChanged","type":"event"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"contentTypes","type":"uint256"}],"name":"ABI","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"addr","outputs":[{"internalType":"address payable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"coinType","type":"uint256"}],"name":"addr","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"authorisations","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"clearDNSZone","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"contenthash","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"name","type":"bytes32"},{"internalType":"uint16","name":"resource","type":"uint16"}],"name":"dnsRecord","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"name","type":"bytes32"}],"name":"hasDNSRecords","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"interfaceImplementer","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"pubkey","outputs":[{"internalType":"bytes32","name":"x","type":"bytes32"},{"internalType":"bytes32","name":"y","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"contentType","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setABI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"coinType","type":"uint256"},{"internalType":"bytes","name":"a","type":"bytes"}],"name":"setAddr","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"a","type":"address"}],"name":"setAddr","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"isAuthorised","type":"bool"}],"name":"setAuthorisation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"hash","type":"bytes"}],"name":"setContenthash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setDNSRecords","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes4","name":"interfaceID","type":"bytes4"},{"internalType":"address","name":"implementer","type":"address"}],"name":"setInterface","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"name","type":"string"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"x","type":"bytes32"},{"internalType":"bytes32","name":"y","type":"bytes32"}],"name":"setPubkey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"key","type":"string"},{"internalType":"string","name":"value","type":"string"}],"name":"setText","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"key","type":"string"}],"name":"text","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}]`
    exchange.IO("abi", resolverAddress, abiENSPublicResolver)
    let vitalikAddress = exchange.IO("api", resolverAddress, "addr", ensNode)
    Log("vitalikAddress:", vitalikAddress)
}

Envoyer de l'ETH

Dans les chapitres précédents du cours, nous avons appris comment configurer les clés privées. Comment connaissons-nous l'adresse de portefeuille correspondant à cette clé privée pour l'objet d'échange configuré?exchange.IO("address")fonction pour obtenir l'adresse de portefeuille correspondant à la clé privée configurée.

Le contenu suivant dans ce chapitre utilise l'environnement Goerli testnet, donc le nœud que j'utilise est:https://goerli.infura.io/v3/*******, et Infura attribue différentes adresses de nœuds pour chaque utilisateur enregistré.*******cache un contenu spécifique.

function main() {
    let walletAddress = exchange.IO("address")
    Log("Testnet goerli wallet address:", walletAddress)
}

Après avoir connu votre adresse de portefeuille, vous pouvez utiliser la méthode RPC d'Ethereumeth_getTransactionCountDans Ethereum, ce nombre est très commun, et c'est en fait le nombre de transactions de l'adresse du portefeuille.nonceNonce est un nombre unique utilisé pour s'assurer que chaque transaction est unique. C'est un nombre croissant, et il augmentera automatiquement à chaque fois qu'une nouvelle transaction est envoyée. Par conséquent, lorsque vous envoyez une transaction à un contrat intelligent, vous devez fournir un nonce pour vous assurer que la transaction est unique et dans le bon ordre.

https://goethereumbook.org/en/

img

Voici lePendingNonceAtfonction dans la bibliothèque Ethereum du langage Go appelle en fait leeth_getTransactionCountDans les cours précédents, nous avons également appris comment appeler les méthodes RPC.exchange.IO("api", "eth", ...)fonctionne à nouveau.

function toAmount(s, decimals) {
    return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}

function main() {
    let walletAddress = exchange.IO("address")
    Log("Testnet goerli wallet address:", walletAddress)

    /**
    * eth_getTransactionCount
    * @param address - string - The address from which the transaction count to be checked.
    * @param blockNumber - string - The block number as a string in hexadecimal format or tags.
    * @returns The integer of the number of transactions sent from an address encoded as hexadecimal.
    */
    let nonce: string = exchange.IO("api", "eth", "eth_getTransactionCount", walletAddress, "pending")
    Log("wallet address:", walletAddress, "current nonce:", nonce, ", convert to decimal:", toAmount(nonce, 0))
}

Avant d'expliquer l'opération de transfert, comprenons brièvement certains concepts. Lors du transfert sur Ethereum, une certaine quantité de jetons ETH sera consommée (en tant que frais de gaz).

  • prix du gaz

    Cependant, les frais de gaz sur le réseau Ethereum fluctuent toujours en fonction de la demande du marché et des frais que les utilisateurs sont prêts à payer, donc écrire un tarif fixe de gaz dans le code n'est parfois pas un choix idéal.eth_gasPriceLa méthode que nous avons apprise précédemment, qui peut obtenir le prix moyen de l'essence.

  • Limite de gaz

    Un transfert standard d'éther a une limite de gaz de 21 000 unités.

Après avoir compris les concepts denonce, gasPrice, etgasLimit, vous pouvez tester le transfert. FMZ fournit une fonction de transfert très simple et facile à utiliser.

exchange.IO("api", "eth", "send", toAddress, toAmount)

Lorsqu'il est utilisé pour les transferts, le troisième paramètre deexchange.IOest fixé comme envoyer, letoAddressle paramètre est l'adresse qui reçoit l'ETH pendant le transfert, ettoAmountest le montant de l'ETH transféré.

Les paramètresnonce, gasPrice, etgasLimitpeuvent toutes utiliser les valeurs par défaut du système obtenues automatiquement sur FMZ.

exchange.IO("api", "eth", "send", toAddress, toAmount, {gasPrice: 5000000000, gasLimit: 21000, nonce: 100})

Ensuite, nous allons transférer une certaine quantité d'ETH à une adresse spécifique sur le réseau de test de Goerli:

function toInnerAmount(s, decimals) {
    return (BigDecimal(s)*BigDecimal(Math.pow(10, decimals))).toFixed(0)
}

function main() {
    let walletAddress = exchange.IO("address")
    Log("Testnet goerli wallet address:", walletAddress)

    let ret = exchange.IO("api", "eth", "send", "0x4D75a08E870674E68cAE611f329A27f446A66813", toInnerAmount(0.01, 18))
    return ret // return Transaction Hash : 0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e
}

Parce que l'unité du montant du transfert Ethereum estwei, une fonction personnaliséetoInnerAmountdoit être utilisé pour traiter la valeur danswei units.

Hash de transaction de requête:0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734esurhttps://etherscan.io/.

img

Vous pouvez également écrire du code pour demander le transfert de hachage0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e, en utilisant leeth_getTransactionReceiptméthode pour les requêtes.

function main() {
    let transHash = "0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e"
    let info = exchange.IO("api", "eth", "eth_getTransactionReceipt", transHash)
    return info
}

Résultat de requête:

{
	"cumulativeGasUsed": "0x200850",
	"effectiveGasPrice": "0x1748774421",
	"transactionHash": "0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e",
	"type": "0x0",
	"blockHash": "0x6bdde8b0f0453ecd24eecf7c634d65306f05511e0e8f09f9ed3f59eee2d06ac7",
	"contractAddress": null,
	"blockNumber": "0x868a50",
	"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
	"gasUsed": "0x5208",
	"to": "0x4d75a08e870674e68cae611f329a27f446a66813",
	"status": "0x1",
	"transactionIndex": "0x23",
	"from": "0x6b3f11d807809b0b1e5e3243df04a280d9f94bf4",
	"logs": []
}

Description correspondant à chaque champ:

blockHash - The hash value of the block where the transaction is located.
blockNumber - The block number of the block where the transaction is located, encoded in hexadecimal.
contractAddress - If it's a contract creation, the address of the contract; otherwise null.
cumulativeGasUsed - The total gas used when executing this transaction in the block.
effectiveGasPrice - Total base fee plus tip per unit of gas.
from - Sender's address.
gasUsed - Gas used by this specific transaction.
logs - Array of log objects generated by this transaction.
  address - Address that generated this log.
  topics - Data array with 0 to 4 indexed log parameters, each with 32 bytes. In Solidity, first topic is event signature hash (e.g., Deposit(address,bytes32,uint256)), unless you declare an event using anonymous specifier.
  data - Non-indexed parameters for logs with length of 32 bytes.
  blockNumber - The block number of the block where this log is located.
  transactionHash - Transaction hash at time when log was created. Null if pending state.
  transactionIndex - Index position during creation. Null if pending state.
  blockHash - The hash value for containing block.
  logIndex - Hexadecimal-encoded integer index position within containing block. Null if pending state.
  removed - True if deleted due to chain reorganization; false for valid logs.
logsBloom - Bloom filter for retrieving related logs.
status - Hexadecimal-encoded value either being '1' (success) or '0' (failure).
to - Receiving party's address; null for contract creation transactions.
transactionHash - The hash value associated with given transaction.
transactionIndex - Hexadecimal-encoded index position within its respective containing-block.
type - Type value.

Appelez le contrat intelligent Ethereum

Dans le chapitre sur Reading Contract Information, nous avons utilisé un exemple complet pour appeler la méthode de contrat ENS déployée sur Ethereum pour obtenir l'adresse de portefeuille de Vitalik Buterin.Readméthodes, et appeler ces méthodes ne nécessite pasgasDans ce chapitre, nous allons appeler certainsWriteméthodes de contrats intelligents sur Ethereum et de payer pourgasCes opérations seront vérifiées par chaque nœud et mineur de l'ensemble du réseau et changeront l'état de la blockchain.

Résultats de l'enquête

Pour le contrat ERC20 (contrat ERC20 token), la plateforme FMZ répertorie l'ABI du contrat ERC20 ABI comme un ABI commun intégré directement dans le système, éliminant l'étape d'enregistrement de l'ABI.

Pour mieux comprendre ABI, vous pouvez le vérifier avant de l'utiliser.

[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"tran

Relationnée

Plus de