[TOC] Je vous en prie.
Introduction facile au développement web3 basé sur Ethereum avec FMZ
Ethereum est une plateforme de contrats intelligents basée sur la technologie blockchain qui offre une façon décentralisée d'écrire et de déployer des contrats intelligents. Les contrats intelligents sont des programmes informatiques spéciaux qui peuvent être exécutés automatiquement sur la blockchain et peuvent réaliser toutes sortes de logiques commerciales sans avoir besoin de faire confiance à un tiers.
Les inventeurs de la plateforme de négociation quantitativeFMZ.COMLa plate-forme offre une API facile à utiliser qui permet aux développeurs d'interagir plus facilement avec la blockchain Ethereum et son écosystème.
Utiliser les exemples de ce tutorielJavaScript
Écrire des langues, tester des environnementsLe réseau Ethereum、Réseau de test de GoerliVous pouvez également consulter la documentation API de la plateforme FMZ pour voir les interfaces API utilisées dans le tutoriel, ainsi que les descriptions et les exemples de code.
Avant d'apprendre à utiliser la plateforme de trading quantitative FMZ, nous devons nous familiariser avec quelques concepts de base:
Le site officiel de la plateforme de trading quantitative FMZhttps://www.fmz.comUne fois enregistré, vous pouvez utiliser toutes les fonctionnalités de la plate-forme. Le site FMZ est l'administrateur du système entier, les programmes écrits par l'utilisateur sont en fait exécutés sur l'hôte. L'hôte peut déployer ce logiciel sur divers appareils, tels que serveurs, ordinateurs, etc. Lorsque l'utilisateur écrit un bon programme sur le site FMZ pour créer un exemple d'exécution, la plate-forme FMZ communique avec l'hôte et lance un exemple de programme sur l'hôte.
Si vous voulez exécuter une instance de programme, vous devez déployer un hôte, qui est également très simple à déployer, avec des tutoriels de déploiement sur la plate-forme. Vous pouvez également déployer automatiquement un serveur loué au nom de FMZ à l'aide du "hôte de déploiement en un clic" fourni sur FMZ.
Déployer un hôte sur un appareil personnel
Les programmes administrateurs peuvent être déployés sur des appareils tels que des serveurs, des ordinateurs personnels, etc. Les principales étapes du déploiement sont les suivantes:
1° Connectez-vous ou ouvrez le périphérique sur lequel vous souhaitez déployer un programme hôte, par exempleConnectez-vous au serveurOu alorsOuvrez l'ordinateur et accédez au système d'exploitationJe ne sais pas.
2, télécharger la version correspondante du programme d'administration (selon le système d'exploitation de l'appareil), télécharger la page:https://www.fmz.com/m/add-node
3° Le téléchargement est un paquet de compression qui doit être décompressé.
4° exécutez ce programme administrateur, un programme administrateur appelérobot
Le fichier exécutable de l'application. Configure l'adresse de communication de l'administrateur, qui est unique pour chaque compte FMZ.https://www.fmz.com/m/add-node
La page peut voir son adresse (c'est-à-dire./robot -s node.fmz.com/xxxxx
Cette chaîne d'adresses, ici.xxxxx
Le contenu de l'emplacement est différent pour chaque compte FMZ). Enfin, vous devez entrer le mot de passe de votre compte FMZ, le configurer et exécuter le programme d'administration.
Utilisation de la fonctionnalité de déploiement d'hôtes en un clic de la plateforme FMZ
Une page d'administrateur a été ajoutée à la plateforme FMZ, à l'adresse:https://www.fmz.com/m/add-node
La plateforme de trading quantitative FMZ offre un outil de débogage gratuit, qui prend en charge les opérations de débogage.JavaScript
,TypeScript
Le site est le suivant:https://www.fmz.com/m/debugLe débogage peut être utilisé pour tester, apprendre et apprendre pendant l'école primaire. Le débogage n'est pas différent de la création d'exemplaires, sauf qu'il est limité à 3 minutes.
UtilisationTypeScript
Dans les langues, il faut écrire la première ligne du code.// @ts-check
Pour passer àTypeScript
Le mode, ne pas basculer par défautJavaScript
La langue.
Sur FMZ, "échange" est un concept générique qui, pour l'échange CEX, désigne une configuration de compte d'échange spécifique. Pour le web3, l'échange désigne une information de configuration contenant l'adresse des nœuds, la configuration de la clé privée.
Il y a aussi des sites de téléchargement de vidéos sur les réseaux sociaux.https://www.fmz.com/m/add-platform
Le site Web de l'échange est une page qui permet de configurer l'information de l'échange, où l'échange est un concept général.
SélectionWeb3
Vous pouvez configurer l'adresse des nœuds RPC ou la configuration de la clé privée en cliquant sur "Enregistrer des informations sensibles en utilisant une clé privée indépendante" en bas à droite.
Les nœuds peuvent être construits eux-mêmes ou fournis par des serveurs de nœuds.InfureAprès l'enregistrement, vous pouvez voir l'adresse du nœud de votre compte.Rpc Address
Dans le cadre de la configuration de l'échange, les étiquettes peuvent se nommer pour distinguer les objets de l'échange.
Dans le dessinhttps://mainnet.infura.io/v3/xxxxxxxxxxxxx
Il s'agit de l'adresse du nœud RPC de l'ETH du réseau principal privé d'Infura.
在部署好托管者程序、配置好交易所对象的前提下,就可以使用FMZ.COM的「调试工具」进行测试了。调用以太坊RPC方法和以太坊交互,除了本章节列举介绍的几个RPC方法,其它RPC方法可以查询资料了解,例如https://www.quicknode.com/docs。
Voici quelques exemples simples pour commencer par les bases. Il existe différentes manières d'accéder au web3 pour les langages et les outils:
Les appels aux méthodes RPC sur FMZ sont également enveloppés, ces fonctionnalités sont enveloppées dans les fonctions API de FMZ.exchange.IO
Le mode d'appel est:exchange.IO("api", "eth", ...)
Le premier paramètre est le flux fixe."api"
Le deuxième paramètre est le flux fixe."eth"
Les autres paramètres dépendent de la méthode RPC utilisée.
Nous avons utilisé la plateforme FMZ pour exporter des informations.Log
La fonctionLog
Les fonctions peuvent entrer plusieurs paramètres et les exécuter dans la zone des journaux de la page "Outils de débogage" ou "Disque dur" de la plate-forme FMZ, où la page "Outils de débogage" sera le principal outil de test.
Pour Ethereumeth_getBalance
Une méthode utilisée pour rechercher le solde d'ETH d'une adresse sur Ethereum nécessite la transmission de deux paramètres.
Nous allons consulter le fondateur d'Ethereum.V神
L'adresse du portefeuille ETH, connue pour être:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
。
function main() {
let ethBalance = exchange.IO("api", "eth", "eth_getBalance", "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest")
Log("ethBalance:", ethBalance)
}
Vous avez déployé un hôte (figure: linux/amd64...) et configuré un objet d'échange (figure: Web3 test), et vous avez testé le code dans le débogage:
Cliquez sur le bouton "Exécuter" pour exécuter ce code et vous obtiendrez le résultat:
Le bilan est le suivant: 0x117296558f185bbc4c6
Log
La fonction est imprimée.ethBalance
La valeur de la variable est:0x117296558f185bbc4c6
, est le type de chaîne ─ ouiLe solde de l'ETH à 16 chiffresJe vous en prie.wei
Le nombre d'unités1e18 wei
est égal à 1.ETH
Ainsi, il est nécessaire de les convertir pour qu'ils deviennent des équilibres décimaux d'ETH.
Je vaisethBalance
Les données sont converties en données lisibles:
function main() {
let ethBalance = exchange.IO("api", "eth", "eth_getBalance", "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest")
Log("ethBalance:", ethBalance)
// 将ethBalance转换为可读的数据
let vitalikEthBalance = parseInt(ethBalance.substring(2), 16) / 1e18
Log("vitalikEthBalance:", vitalikEthBalance)
}
En hauthttps://etherscan.io/
Il y a une question:
Cependant, la raison en est que les problèmes de précision de la langue elle-même peuvent être déformés, et la plateforme FMZ a donc deux fonctions intégrées pour traiter les données:
Le code a été modifié:
function main() {
let ethBalance = exchange.IO("api", "eth", "eth_getBalance", "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest")
// ETH的精度单位为1e18
let ethDecimal = 18
Log("vitalikEthBalance:", Number((BigDecimal(BigInt(ethBalance)) / BigDecimal(Math.pow(10, ethDecimal))).toString()))
}
Le bilan est de 5149,6244846875215.
eth_chainId
etnet_version
Les deux fonctions renvoient l'id de la chaîne de blocs à laquelle le nœud RPC actuel a accès, la différence étant:net_version
Il est possible de modifier l'id de l'image en utilisant des paramètres.eth_chainId
Il est possible de modifier l'id d'un système à 16 chiffres.
Nom du réseau correspondant à la chaîne Id
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
Utiliser le réseau de test Ethereum bien configurégoerli
Les tests de nœuds:
function main() {
let netVersionId = exchange.IO("api", "eth", "net_version")
let ethChainId = exchange.IO("api", "eth", "eth_chainId")
Log("netVersionId:", netVersionId)
Log("ethChainId:", ethChainId, " ,转换:", parseInt(ethChainId.substring(2), 16))
}
Appeléeeth_gasPrice
Métode qui demande à la chaîne actuellegas price
。
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, " ,转换:", toAmount(gasPrice, 0))
}
Ici, nous écrivons une fonction qui convertit une chaîne de 16 chiffres en une opération qui permet de lire une valeur numérique:toAmount
Il faut aussi noter que l'unité de prix du gaz est:wei
Donc, on peut faire une figure de semence.decimals
La valeur du paramètre réel correspondant est 0.
eth_blockNumbe
Pour demander la hauteur d'un 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))
}
Les outils de débogage fonctionnent:
https://etherscan.io/
Les requêtes:
Vous pouvez consulter les informations sur les blocs.
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)
// 由于Log输出的内容过多,会自动截断,所以遍历返回的区块信息各个字段,逐个打印
for (let key in blockMsg) {
Log("key:", key, ", val:", blockMsg[key])
}
}
Les informations suivantes peuvent être obtenues en les exécutant dans les outils de débogage:
Il existe de nombreuses applications de contrats intelligents sur Ethereum.ENS
Il y a aussi des gens qui se disent que c'est une bonne chose.ENS
L'Ethereum Name Service est un service décentralisé de résolution de noms de domaine basé sur la blockchain Ethereum.
Souvenez-vous que dans le tutoriel, nous avons consulté l'exemple du solde du portefeuille de Dieu V, le fondateur d'Ethereum?0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
Mais comment pouvons-nous connaître cette adresse?ENS
Les contrats intelligents, avec un nom intuitifvitalik.eth
Il y a aussi des gens qui ont besoin d'aide pour se renseigner sur le nom de Dieu.
Les éléments suivants sont utilisés dans l'environnement d'Ethereum selon les termes suivants:ENS
La documentation est connue pour nécessiter des recherches sur les noms de domaine Ethereum.Hashing Names
Pour le faire, utilisez le code suivant:vitalik.eth
Le nom est en cours de traitement.
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 voyons une autre fonction étrange.Encode
Cette fonction est une fonction API de la plateforme FMZ, spécialement conçue pour effectuer des opérations d'encodage sur la plateforme FMZ.
Encode(algo, inputFormat, outputFormat, data, keyFormat, key string)
Utilisation selon la description dans la documentation ENSsha3.keccak256
L'algorithme traite les données.
AppeléenameHash
Les fonctions, par exemple:Log(nameHash("vitalik.eth"))
Vous pouvez:ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835
Il faut ajouter le préfixe "0x".0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835
Il s'agit d'un contrat intelligent créé par l'ENSresolver
Paramètres de la méthode.
let ensNode = "0x" + nameHash("vitalik.eth") // 准备好调用resolver方法的参数ensNode
En consultant les documents d'ENS, vous pouvez voir que l'adresse du contrat de l'application ENS Smart Contract est:0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
Le gouvernement a décidé d'utiliser les contrats intelligents.resolver
Nous avons besoin d'un contrat pour préparer notre approche.ABI
。
Il y a des gens qui apprennent à venir ici et qui demandent ce qu'est un contrat intelligent.ABI
Je ne sais pas.
ABI,即应用程序二进制接口(Application Binary Interface),是智能合约与外部世界进行通信的接口标准。
智能合约的 ABI 定义了合约的函数接口、参数类型、返回值等信息,以及调用合约的方式和参数传递方式等规范。
智能合约的 ABI 通常以 JSON 格式存储,包含以下信息:
合约的函数接口:函数名、参数列表、返回值等信息。
函数参数类型:如 uint256、bool、string 等。
函数的输入参数和输出参数的编码方式:智能合约使用一种称为 Solidity ABI 的编码方式来编码函数的输入参数和输出参数,
以便与以太坊网络进行交互。
在以太坊网络中,使用智能合约的 ABI 来调用合约的函数。当需要调用合约函数时,需要提供函数名和函数参数,以及将函数参数按照 ABI 编码方式编码后的字节码。
以太坊节点会将这些信息打包成一笔交易,并将交易发送到以太坊网络中执行。
智能合约的 ABI 在 Solidity 语言中可以通过 interface 关键字来定义。以太坊开发工具如 Remix IDE、Truffle 等也提供了 ABI 编辑和生成工具,
使得开发者可以方便地创建和使用智能合约的 ABI。
On peut extraire l'ABI de l'ENS.resolver
Une partie de la méthode peut également être utilisée avec une ABI complète.https://etherscan.io/
Vous pouvez consulter l'ABI du contrat ou l'obtenir par d'autres moyens (par exemple: documentation relative au projet).
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"}]`
Nous allons apprendre une nouvelle façon d'appeler sur la plateforme FMZ.exchange.IO("abi", address, abiContent)
Il y a aussi des sites de rencontres en ligne qui permettent de s'inscrire à l'ABI.address
Les paramètres sont l'adresse du contrat intelligent.abiContent
Les paramètres sont les contrats intelligents correspondants ABI (string).
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 是在以太坊主网上部署的ENS智能合约的地址
Vous pouvez ensuite appeler le contrat intelligent ENS.resolver
La méthode est là, la méthode est de retourENS: Public Resolver
L'adresse du contrat est la suivante:
let resolverAddress = exchange.IO("api", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", "resolver", ensNode)
UtilisationENS: Public Resolver
Le contrataddr
Comment obtenir l'adresse du portefeuille de V?ENS: Public Resolver
Les contrats doivent toujours être enregistrés ABI.https://etherscan.io/
Je suis désolée.
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)
Dernier appelENS: Public Resolver
Le contrataddr
La méthode, les paramètres sont toujoursensNode
。
let vitalikAddress = exchange.IO("api", resolverAddress, "addr", ensNode)
Log("vitalikAddress:", vitalikAddress)
La fonction log est produite par:
vitalikAddress: 0xd8da6bf26964af9d7eed9e03e53415d37aa96045
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() {
// 计算名称
let ensNode = "0x" + nameHash("vitalik.eth")
// 注册ENS合约
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)
// 注册ENS Public Resolver合约
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)
}
Dans les chapitres précédents, nous avons appris comment configurer une clé privée, et comment savoir si cette clé privée correspond à une adresse de portefeuille pour un objet d'échange configuré?exchange.IO("address")
La fonction obtient la clé privée de la configuration correspondant à l'adresse du portefeuille.
En raison de l'utilisation des éléments suivants dans ce chapitre:Goerli
Je vais essayer d'utiliser un environnement Web, donc le nœud que j'utilise est le suivant:https://goerli.infura.io/v3/*******
Les adresses des nœuds que l'infura attribue à chaque utilisateur enregistré sont différentes.*******
Le contenu est masqué.
function main() {
let walletAddress = exchange.IO("address")
Log("测试网 goerli 钱包地址:", walletAddress)
}
Une fois que vous connaissez votre adresse de portefeuille, vous pouvez utiliser la méthode RPC d'Ethereum.eth_getTransactionCount
Le nombre de transactions pour l'adresse de votre portefeuille. Dans Ethereum, ce nombre est très courant, car il est nécessaire de le saisir pour effectuer un virement.nonce
Paramètres, dans Ethereum, nonce est utilisé pour s'assurer que chaque transaction est unique. C'est un nombre croissant qui s'ajoute 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.
Il y a une version de Go dans le référentiel Ethereum.PendingNonceAt
La fonction est en fait appelée.eth_getTransactionCount
Les méthodes. Dans les cours précédents, nous avons également appris comment appeler la méthode RPC, et nous l'utilisons à nouveau ici.exchange.IO("api", "eth", ...)
Les fonctions.
function toAmount(s, decimals) {
return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}
function main() {
let walletAddress = exchange.IO("address")
Log("测试网 goerli 钱包地址:", 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 = exchange.IO("api", "eth", "eth_getTransactionCount", walletAddress, "pending")
Log("钱包地址:", walletAddress, "当前的 nonce:", nonce, ",转换为10进制:", toAmount(nonce, 0))
}
Avant d'expliquer les opérations de transfert, nous avons simplement compris quelques concepts qui consomment un certain nombre de jetons d'ETH lors d'un transfert sur Ethereum (en tant que frais de gaz). Ce coût de gaz est déterminé par deux paramètres:
prix du gaz
Cependant, le prix du carburant sur le réseau Ethereum fluctue toujours en fonction de la demande du marché et de ce que les utilisateurs sont prêts à payer, de sorte qu'écrire un prix fixe du carburant dans le code n'est parfois pas une option idéale.eth_gasPrice
La méthode qui permet d'obtenir le prix moyen du gaz.
Limite de gaz
La limite de gaz d'un transfert standard d'Ethereum est de 21000 unités.
Je comprends.nonce
,gasPrice
,gasLimit
Ces concepts peuvent être testés. Une fonction de transfert enveloppée dans FMZ est très simple et facile à utiliser.
exchange.IO("api", "eth", "send", toAddress, toAmount)
Les utilisateurs de Twitter ont été informés de la disparition de leur compte.exchange.IO
Le troisième paramètre est écrit comme "send".toAddress
Le paramètre est l'adresse à laquelle l'ETH est reçu lors du transfert.toAmount
La quantité d'ETH transférée.
nonce
,gasPrice
,gasLimit
Ces paramètres peuvent être utilisés sur FMZ avec les valeurs que le système obtient automatiquement par défaut.
exchange.IO("api", "eth", "send", toAddress, toAmount, {gasPrice: 5000000000, gasLimit: 21000, nonce: 100})
Ensuite, nous transférons une certaine quantité d'ETH vers une adresse sur le goerli du test:
function toInnerAmount(s, decimals) {
return (BigDecimal(s)*BigDecimal(Math.pow(10, decimals))).toFixed(0)
}
function main() {
let walletAddress = exchange.IO("address")
Log("测试网 goerli 钱包地址:", walletAddress)
let ret = exchange.IO("api", "eth", "send", "0x4D75a08E870674E68cAE611f329A27f446A66813", toInnerAmount(0.01, 18))
return ret // 返回Transaction Hash : 0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e
}
C'est parce que l'unité de la quantité de virements sur Ethereum estwei
Vous devez utiliser une fonction personnalisée.toInnerAmount
Traiter commewei
Le nombre d'unités.
Danshttps://etherscan.io/
Pour consulter le transaction hash ci-dessus:0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e
。
Vous pouvez également écrire des requêtes de code pour transférer des hachages.0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e
, utilisationeth_getTransactionReceipt
Comment faire une requête?.
function main() {
let transHash = "0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e"
let info = exchange.IO("api", "eth", "eth_getTransactionReceipt", transHash)
return info
}
Résultats de recherche:
{
"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": []
}
Chaque champ est décrit comme suit:
blockHash - 该交易所在区块的哈希值
blockNumber - 以十六进制编码的该交易所在区块的块号
contractAddress - 如果是合约创建,该合约的地址;否则为null
cumulativeGasUsed - 该交易在区块中执行时使用的总燃气量
effectiveGasPrice - 每单位燃气的总基础费用加小费
from - 发送者的地址
gasUsed - 该特定交易使用的燃气量
logs - 生成该交易的日志对象数组
address - 生成该日志的地址
topics - 0到4个32字节索引日志参数的数据数组。在Solidity中,第一个主题是事件签名的哈希值(例如Deposit(address,bytes32,uint256)),除非你使用匿名说明符声明该事件
data - 日志的32字节非索引参数
blockNumber - 该日志所在区块的块号
transactionHash - 该日志创建时的交易哈希值。如果该日志处于待定状态,则为null
transactionIndex - 该日志创建时的交易索引位置。如果该日志处于待定状态,则为null
blockHash - 该日志所在区块的哈希值
logIndex - 该日志在区块中的索引位置,以十六进制编码的整数。如果该日志处于待定状态,则为null
removed - 如果该日志已被删除,则为true,由于链重组而被删除;如果是有效的日志,则为false
logsBloom - 用于检索相关日志的布隆过滤器
status - 以十六进制编码的值,它要么是1(成功),要么是0(失败)
to - 接收者的地址。如果是合约创建交易,则为null
transactionHash - 该交易的哈希值
transactionIndex - 以十六进制编码的该交易在区块中的索引位置
type - 值的类型
Nous sommes dansLire les informations du contratDans ce chapitre, une méthode appelant les contrats ENS déployés sur Ethereum est utilisée pour obtenir l'adresse du portefeuille de V.Read
Il n'est pas nécessaire d'appeler ces méthodes.gas
Dans ce chapitre, nous allons parler de l'utilisation de certains des contrats intelligents d'Ethereum.Write
Comment et comment payergas
Ces opérations seront validées par chaque nœud de l'ensemble du réseau ainsi que par les mineurs et changeront l'état de la blockchain.
Pour les contrats ERC20, la plate-forme FMZ classe les ABI des contrats ERC20 comme étant des ABI couramment utilisés directement intégrés dans le système, en omettant cette étape de l'enregistrement des ABI.
Pour une meilleure compréhension de l'ABI, avant de l'utiliser, vous pouvez consulter l'ABI suivant pour les contrats ERC20:
[{"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":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"}]
Les articles suivants sont utilisés dans ce chapitre:Goerli
Le site Web de l'équipe de test a été mis à jour.
Nous avons ensuite répété une fois de plus comment appeler les contrats.Read
La méthode pour lire les informations sur les contrats et appeler les contrats ERC20balanceOf
Les méthodes pour vérifier le solde des jetonsbalanceOf
La méthode n'a qu'un paramètre, mais n'est pas nommée, et est vue par le type comme une adresse (c'est-à-dire l'adresse du jeton interrogé). Puisque les données retournées ne sont pas en unité de jeton, des données de précision de jeton sont nécessaires pour les convertir.decimals
Nous utilisons le réseau de test Ethereum.goerli
Le test a été effectué en tenant compte du fait que les adresses des contrats de jetons sur différentes chaînes peuvent également être différentes.
function toAmount(s, decimals) {
return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}
function main() {
let walletAddress = exchange.IO("address")
// goerli WETH address
let wethAddress = "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6"
// goerli LINK address
let linkAddress = "0x326C977E6efc84E512bB9C30f76E30c160eD06FB"
// 由于是ERC20合约,FMZ已经内置ABI注册,所以这里不用注册ERC20 ABI
let wethDecimals = exchange.IO("api", wethAddress, "decimals")
let linkDecimals = exchange.IO("api", linkAddress, "decimals")
let wethBalance = exchange.IO("api", wethAddress, "balanceOf", walletAddress)
let linkBalance = exchange.IO("api", linkAddres