Einfache Einführung in web3-Entwicklung auf Basis von Ethereum mit FMZ

Schriftsteller:Kleine Träume, Erstellt: 2023-03-28 13:32:48, Aktualisiert: 2023-09-18 20:27:13

[TOC]

img

EtherEase mit FMZ

Einfache Einführung in web3-Entwicklung auf Basis von Ethereum mit FMZ

Ethereum ist eine Smart-Contract-Plattform, die auf Blockchain-Technologie basiert und eine dezentrale Möglichkeit bietet, Smart Contracts zu schreiben und zu implementieren. Smart Contracts sind spezielle Computerprogramme, die automatisch auf der Blockchain ausgeführt werden können und verschiedene Geschäftslogiken realisieren können, ohne dass eine dritte Partei vertraut werden muss.

Erfinder der quantitativen HandelsplattformFMZ.COMDie Software bietet eine benutzerfreundliche API, die es Entwicklern erleichtert, mit der Ethereum-Blockchain und ihrem Ökosystem zu interagieren.

Die Beispiele in diesem TutorialJavaScriptSprache schreiben, Testumgebungen verwendenDas Ethereum NetzwerkDas Goerli TestnetzDie API-Dokumentation für die FMZ-Plattform enthält auch die API-Interfaces, die in den Tutorials verwendet wurden, sowie die entsprechenden Beschreibungen und Codebeispiele.


FMZ nutzt den Zugang

Bevor wir lernen, wie wir die FMZ-Quantitätshandelsplattform nutzen können, müssen wir einige Grundkonzepte kennen:

1. FMZ Quantitative Handelsplattform Architektur

Der Name des Kunden wird auf der Website der FMZ Quantitative Trading Plattform veröffentlicht.https://www.fmz.comDie Funktionen der Plattform können bei Registrierung und Login genutzt werden. Die FMZ-Website ist die Verwaltung des gesamten Systems und die vom Benutzer geschriebenen Programme laufen tatsächlich auf dem Host. Der Host kann auf verschiedenen Geräten wie Servern, Computern usw. eingesetzt werden.

img

2. Verwalter

Für die Ausführung einer Instanz muss ein Host eingesetzt werden, der sehr einfach zu installieren ist und über die Plattform verfügbar ist.

  • Ein Host auf einem persönlichen Gerät bereitstellen

    Es ist möglich, Administratorprogramme auf Geräten wie Servern oder PCs zu installieren, sofern sichergestellt ist, dass das Netzwerk funktioniert. Die wichtigsten Schritte für die Deployment sind:

    1. Anmelden oder öffnen Sie die Geräte, auf denen die Administratorprogramme bereitgestellt werden sollen, z. B.Login auf den ServerOderÖffnen Sie den Computer und gehen Sie in das BetriebssystemDas ist nicht wahr. 2. Laden Sie die entsprechende Version des Administratorprogramms (je nach Betriebssystem des Geräts) herunter.https://www.fmz.com/m/add-node img3. Ein Kompressionspaket wird heruntergeladen und muss entschlüsselt werden. 4. Wenn Sie diesen Administrator ausführen, ist der Administrator ein Programm namensrobotDie Funktion ist eine Funktion, mit der die Funktionsberechtigung der Funktionsberechtigung über die Funktionsberechtigung der Funktionsberechtigung übertragen wird.https://www.fmz.com/m/add-nodeDie Seite kann die eigene Adresse sehen (d.h../robot -s node.fmz.com/xxxxxDiese Adressen sind hier.xxxxxDer Inhalt des Standorts, der für jedes FMZ-Konto unterschiedlich angezeigt wird); schließlich muss das Passwort des FMZ-Kontos eingegeben werden, um diese zu konfigurieren und dann den Administrator zu starten.

  • Mit der Funktion "Ein-Taste-Deployment-Hosts" der FMZ-Plattform

    Die Webseite des FMZ-Plattform-Präsidenten wurde auf:https://www.fmz.com/m/add-node

    img

3. Debugging-Tools

Die FMZ Quantitative Trading Plattform bietet ein kostenloses Debugging-Tool, das die Nutzung von Quantifizierungssystemen unterstützt.JavaScriptTypeScriptDie Seite lautet:https://www.fmz.com/m/debugDas Debugger Tool ist kostenpflichtig, da das Erstellen von Instanzen kostenpflichtig ist. Während des ersten Schuljahres kann man mit diesem Debugger Tool testen, lernen und lernen. Das Debugger Tool unterscheidet sich in keiner Weise von dem Erstellen von Instanzen, außer dass es eine maximale Laufzeit von 3 Minuten hat.

NutzungTypeScriptIn einer Sprache muss man in der ersten Zeile des Codes schreiben.// @ts-checkSie können es mitTypeScriptModell, nicht wechseln ist der StandardJavaScriptDie Sprache.

4. Börsen

Auf FMZ ist "Börse" ein allgemeines Konzept, das für die CEX-Börse auf eine bestimmte Kontokonfiguration hinweist. Für die web3 bezieht sich die Kontokonfiguration auf eine Kontoinformation, die die Node-Adresse, die private Schlüsselkonfiguration enthält.

Der Präsident der Fraktion der Europäischen Demokraten (FDP) erklärte, dass er sich nicht für eine politische Entscheidung entschieden habe.https://www.fmz.com/m/add-platformAuf der Seite können Sie die Informationen der Börse konfigurieren, wobei die Börse ein allgemeines Konzept ist.

img

AuswahlWeb3Sie können die RPC-Node-Adresse konfigurieren oder den privaten Schlüssel konfigurieren. Klicken Sie auf "Sensible Informationen mit einem separaten privaten Schlüssel verschlüsseln".

Es gibt viele verschiedene Arten von Node-Servers, zum Beispiel:Infura◦ Nach der Registrierung können Sie die Adresse Ihres Kontos ansehen. ◦ Hauptnetz, Testnetz, sind verfügbar, es ist einfacher, diese Adresse in der Abbildung oben zu konfigurieren.Rpc AddressIn der Anzeige werden die Bezeichnungen in der Anzeigetext-Funktion angezeigt.

img

Die Bilderhttps://mainnet.infura.io/v3/xxxxxxxxxxxxxDas ist die Adresse des RPC-Nodes des privaten ETH-Hauptnetzes von Infura.


Interaktion mit FMZ und Ethereum

在部署好托管者程序、配置好交易所对象的前提下,就可以使用FMZ.COM的「调试工具」进行测试了。调用以太坊RPC方法和以太坊交互,除了本章节列举介绍的几个RPC方法,其它RPC方法可以查询资料了解,例如https://www.quicknode.com/docs

Hier sind ein paar einfache Beispiele, um mit den Grundlagen zu beginnen.

img

In FMZ werden auch Anrufe von RPC-Methoden eingebunden, die in den FMZ-API-Funktionen eingebunden sind.exchange.IODer Anruf ist:exchange.IO("api", "eth", ...)◎ Die erste Parameter wird fest eingetragen"api"Der zweite Parameter ist die feste Übertragung."eth", andere Parameter sind abhängig von der spezifischen RPC-Methode, die aufgerufen wird.

Wir haben die FMZ-Plattform benutzt, um Informationen auszuliefern.LogDie FunktionLogDie Funktion kann mehrere Parameter eingeben und dann in den Log-Bereich der Debugging-Tools-Plattform der FMZ-Plattform oder auf der Live-Disk-Seite ausführen, wo die Debugging-Tools-Seite unser Haupt-Tool sein wird.

eth_getBalance

Das ist Ethereumeth_getBalanceMethode zur Abfrage des ETH-Balances einer Adresse auf Ethereum, die zwei Parameter erfordert.

  • Die Adresse benötigt wird.
  • In der Regel wird "latest" verwendet.

Lassen Sie uns nach dem Gründer von Ethereum fragen.V神Die ETH-Wallets sind unter anderem unter dem Namen:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045

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

Sie haben den Administrator (siehe: linux/amd64...) eingesetzt und die Börsenobjekte (siehe: Web3 test) konfiguriert.

img

Klicken Sie auf die Schaltfläche "Ausführen" und laufen Sie diesen Code aus, der das Ergebnis anzeigt:

EthBalance: 0x117296558f185bbc4c6

LogDie Funktion wird ausgedruckt.ethBalanceDer Variablenwert lautet:0x117296558f185bbc4c6, ist der String-Typ.ETH-Bilanz mit einem 16-stelligen WertDieweiEinheitlich1e18 weiDas ist eins.ETHSo muss es auch umgewandelt werden, um zu einem lesbaren Dezimal-ETH-Bilanz zu werden.

Wir werdenethBalanceDie Daten werden in lesbare Daten umgewandelt:

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

img

Da obenhttps://etherscan.io/Nachfrage:

img

Da sich die Sprache selbst in der Frage nach der Genauigkeit verzerren kann, haben wir zwei Funktionen für die Datenverarbeitung auf der FMZ-Plattform:

  • Big:Int konvertiert eine 16-stellige String in ein BigInt-Objekt.
  • BigDecimal: Konvertiert ein Objekt mit einem Zahlentyp in ein berechenbares BigDecimal-Objekt.

Das ist ein sehr schwieriger Fall.

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

LebensmittelhilfeBilanz: 5149,6244846875215

Eth_chainId

eth_chainIdundnet_versionDie Funktionen sind nahezu identisch, also lassen Sie sie zusammen testen. Beide Funktionen geben die Id der Blockchain zurück, auf die der aktuelle RPC-Node zugegriffen hat.net_versionDie Zahlen werden in der Tabelle angegeben, und die Zahlen werden in der Tabelle angegeben.eth_chainIdDie Rückgabe von Id für das sechzehnstellige System.

Netzwerkname, der der Ketten-Id entspricht

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

img

Mit einem konfigurierten Ethereum-TestnetzgoerliDie Tests werden von den verschiedenen Netzwerken durchgeführt.

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

img

eth_gasPreis

Anrufeeth_gasPriceMethode, um die aktuelle Kette abzufragengas 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))
}

Hier schreiben wir eine Funktion, die eine 16-stellige String in eine lesbare Zahlenwerte umwandelt:toAmountEs ist auch wichtig zu beachten, dass die Einheit GasPriceweiAlso, wir haben die Form der Samen.decimalsDie entsprechende reelle Parameterübertragung kann 0 sein.

Eth_blockNumbe

eth_blockNumbeSie werden verwendet, um nach der Höhe der Blöcke zu fragen.

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

Das Debugger-Tool läuft auf:

img

https://etherscan.io/Nachfrage:

img

eth_getBlockByNumber

Sie können sich die Informationen über die Blöcke anfragen.

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

In der Debugging-Tool können Sie die folgenden Informationen ausführen:

img


Lesen Sie die Vertragsinformation

Es gibt eine Vielzahl von Smart-Contract-Anwendungen, die auf Ethereum laufen.ENSIch bin ein junger Mann und ich bin ein junger Mann.ENSDer Ethereum Name Service ist ein dezentraler Domain-Name-Parsing-Dienst, der auf der Ethereum-Blockchain basiert. Erinnern Sie sich daran, dass wir in unserem Tutorial nach dem Wallet-Balance von Ethereum-Gründer V Gott gefragt haben? Eine Wallet-Adresse von V Gott lautet:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045Wie können wir dann die Adresse wissen?ENSSmart Contracts mit einem intuitiven Namenvitalik.ethIch habe eine Frage an den Autor gestellt: "Was ist das für ein Problem?"

In diesem Kapitel werden die folgenden Inhalte verwendet, um die Ethereum-Umgebung zu nutzen, die in derENSDie Dokumentation ist bekannt, dass eine Abfrage an einem Ethereum-Domain benötigt wird.Hashing NamesDie folgenden Code werden verwendet:vitalik.ethDer Name wird verarbeitet.

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

Wir sehen eine andere unbekannte Funktion in diesem Beispiel.EncodeDie Funktion ist eine API-Funktion für die FMZ-Plattform, die speziell für die Coding-Operationen auf der FMZ-Plattform verwendet wird. Die Funktion unterstützt mehrere Codemethoden und unterstützt mehrere Hash-Algorithmen.

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

Wie in der ENS-Dokumentation beschrieben, verwendetsha3.keccak256Algorithmen verarbeiten Daten.

AnrufenameHashFunktionen wie:Log(nameHash("vitalik.eth"))Das ist ein sehr schwieriges Thema.ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835, muss eine "0x" Präfix hinzugefügt werden.0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835Das ist ein intelligenter Vertrag, der als ENS bekannt ist.resolverDie Parameter der Methode.

let ensNode = "0x" + nameHash("vitalik.eth")    // 准备好调用resolver方法的参数ensNode

Nach der Überprüfung der ENS-Dokumentation kann man feststellen, dass die Vertragsadresse für die ENS-Smart Contract-Anwendung lautet:0x00000000000C2E074eC69A0dFb2997BA6C7d2e1eIch bin der Meinung, dass wir das nicht tun müssen.resolverVor der Methode müssen wir auch einen Vertrag vorbereiten.ABI

Registriert bei ABI

Ich bin hierher gekommen, um zu lernen, was ein intelligenter Vertrag ist.ABIWas ist das?

ABI,即应用程序二进制接口(Application Binary Interface),是智能合约与外部世界进行通信的接口标准。
智能合约的 ABI 定义了合约的函数接口、参数类型、返回值等信息,以及调用合约的方式和参数传递方式等规范。

智能合约的 ABI 通常以 JSON 格式存储,包含以下信息:

合约的函数接口:函数名、参数列表、返回值等信息。
函数参数类型:如 uint256、bool、string 等。
函数的输入参数和输出参数的编码方式:智能合约使用一种称为 Solidity ABI 的编码方式来编码函数的输入参数和输出参数,
以便与以太坊网络进行交互。
在以太坊网络中,使用智能合约的 ABI 来调用合约的函数。当需要调用合约函数时,需要提供函数名和函数参数,以及将函数参数按照 ABI 编码方式编码后的字节码。
以太坊节点会将这些信息打包成一笔交易,并将交易发送到以太坊网络中执行。

智能合约的 ABI 在 Solidity 语言中可以通过 interface 关键字来定义。以太坊开发工具如 Remix IDE、Truffle 等也提供了 ABI 编辑和生成工具,
使得开发者可以方便地创建和使用智能合约的 ABI。

Und das ist der Grund, warum wir das tun.resolverEin Teil der Methode kann auch mit einem vollständigen ABI verwendet werden.https://etherscan.io/Sie können die ABI für den Vertrag anfragen oder die ABI auf andere Weise erhalten (z. B. Projektdokumentation).

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"}]`

Hier lernen wir eine neue Art, wie wir auf der FMZ-Plattform anrufen können.exchange.IO("abi", address, abiContent)Das ist eine sehr schwierige Sache, aber es gibt viele Möglichkeiten, wie man das kann.addressDie Parameter sind die Adresse des Smart Contracts.abiContentDie Parameter sind die entsprechenden Smart Contracts 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智能合约的地址

Wie man Smart Contracts aufruft

Wir können dann das ENS-Smart Contract aufrufen.resolverDie Methode geht zurück.ENS: Public ResolverDie Adresse des Vertrags.

img

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

NutzungENS: Public ResolverVertraglichaddrWie bekomme ich die Adresse der V-Gottes-Wallet?ENS: Public ResolverDer Vertrag muss immer noch vor der Registrierung der ABI erfolgen.https://etherscan.io/Ich habe es nicht geschafft.

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

Letzter AnrufENS: Public ResolverVertraglichaddrDie Methode, die Parameter bleibenensNode

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

Die Log-Funktion liefert:

img

vitalikAddress: 0xd8da6bf26964af9d7eed9e03e53415d37aa96045

Vollständiger Code für den Aufruf von ENS

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

Senden von ETH

Wir haben in den vorherigen Kapiteln gelernt, wie man einen privaten Schlüssel konfiguriert, und wie können wir wissen, welcher private Schlüssel für das konfigurierte Exchange-Objekt die entsprechende Wallet-Adresse ist?exchange.IO("address")Die Funktion erhält die private Schlüssel für die entsprechende Wallet-Adresse.

In Anbetracht der folgenden Bestimmungen dieses Kapitels:GoerliIch bin ein Experte für Web-Umgebungen, also benutze ich folgende Knoten:https://goerli.infura.io/v3/*******Infura hat für jeden registrierten Benutzer eine andere Adresse zugewiesen.*******Ich bin der Ansicht, dass es nicht nur um die Veröffentlichungen geht, sondern auch um das Internet.

function main() {
    let walletAddress = exchange.IO("address")
    Log("测试网 goerli 钱包地址:", walletAddress)
}

img

Wenn man seine eigene Wallet-Adresse kennt, kann man die RPC-Methode von Ethereum verwendeneth_getTransactionCountDie Anzahl der Transaktionen, die nach der Adresse der Geldbörse gefragt werden.nonceParameter: In Ethereum wird der Nonce verwendet, um sicherzustellen, dass jede Transaktion eine einzigartige Zahl ist. Es ist eine inkrementelle Zahl, die sich automatisch bei jedem Versand einer neuen Transaktion erhöht. Daher müssen Sie einen Nonce bereitstellen, um sicherzustellen, dass die Transaktion einzigartig und in der richtigen Reihenfolge ist.

https://goethereumbook.org/en/

img

Hier ist eine Übersicht über den Ethereum-Repository in der Go-Sprache.PendingNonceAtDie Funktion wird tatsächlich aufgerufen.eth_getTransactionCountMethoden. In früheren Lektionen haben wir auch gelernt, wie man die RPC-Methode aufruft, und wir werden sie hier wieder verwenden.exchange.IO("api", "eth", ...)Die Funktion.

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

Bevor wir die Transfers erklären, verstehen wir einfach einige Konzepte, die bei Transfers auf Ethereum eine bestimmte Anzahl von ETH-Token (als Gaskosten) verbrauchen.

  • Gaspreis

    Allerdings schwankt die Gaskosten auf dem Ethereum-Netzwerk stets je nach Marktnachfrage und dem, was die Nutzer bereit sind zu zahlen, so dass es manchmal nicht ideal ist, feststehende Gaskosten in den Code zu schreiben.eth_gasPriceDie Methode, mit der man den durchschnittlichen Gaspreis erhält.

  • Gasgrenze

    Eine Standard-Ethereum-Transfer-Gas-Limit beträgt 21000 Einheiten.

Ich verstehe.noncegasPricegasLimitDiese Konzepte können nun getestet werden. Eine sehr einfache und benutzerfreundliche Überweisungsfunktion ist auf FMZ verpackt.

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

Das ist eine Art Geldtransfer.exchange.IODer dritte Parameter wird als "send" festgelegt.toAddressDie Parameter sind die Adresse, an der die ETH bei der Überweisung empfangen wird.toAmountDie Anzahl der ETH, die überwiesen werden soll.

noncegasPricegasLimitDiese Parameter können in FMZ mit dem System-Standard-Wert verwendet werden, der automatisch erfasst wird.

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

Als nächstes überweisen wir ETH an eine Adresse auf dem Testnetz Goerli:

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
}

Denn die Einheit für die Anzahl der Transaktionen in Ethereum istweiWir brauchen eine benutzerdefinierte FunktiontoInnerAmountVerarbeiten SieweiDie Zahl der Einheiten.

In derhttps://etherscan.io/Überraschenderweise ist es nicht so, dass es nicht funktioniert.0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e

img

Sie können auch Code schreiben, um Abfragen zu übertragen und Hashes zu erstellen.0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e, benutzteth_getTransactionReceiptWie kann man nachfragen?

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

Die Suchergebnisse:

{
	"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": []
}

Jedes Feld wird beschrieben:

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 - 值的类型

Ein Smart Contract namens Ethereum

Wir sind inLesen Sie die VertragsinformationIn diesem Kapitel werden die Methoden, die die ENS-Kontrakte auf Ethereum aufrufen, um die V-Gottes-Wallet-Adresse zu erhalten, in einem vollständigen Beispiel dargestellt.ReadMethoden, die nicht benötigt werden.gasDas ist eine Art "Smart-Contract" (Erinnern Sie sich, was wir zuvor über Gas gesagt haben?).WriteMethoden und ZahlungengasDiese Operationen werden von jedem Knoten im gesamten Netzwerk sowie von Minern verifiziert und ändern den Zustand der Blockchain.

ERC20

Für ERC20-Kontrakte ("ERC20-Token-Kontrakte") listet FMZ-Plattform die ERC20-Kontrakte als übliche ABI direkt in das System integriert, ohne den Schritt der Registrierung von ABI zu überspringen.

Für ein besseres Verständnis der ABI können Sie sich die folgenden ABI für ERC20-Verträge ansehen, bevor Sie sie verwenden:

[{"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"}]

In diesem Kapitel werden folgende Inhalte verwendet:GoerliTestnetz-Umgebung.

Bilanz

Und dann haben wir noch einmal geübt, wie man einen Vertrag aufruft.ReadWie kann man die Informationen von Verträgen lesen und ERC20-Verträge aufrufen?balanceOfWie man den Token-Balance abfragtbalanceOfDie Methode hat nur einen Parameter, ist aber nicht benannt und kann durch den Typ als eine Adresse (d. h. die Adresse des abgefragten Tokens) gesehen werden. Da die zurückgegebenen Daten nicht in einem Token angegeben sind, werden die Präzisionsdaten des Tokens benötigt, um die Präzision des Tokens in einem ERC20-Vertrag zu berechnen.decimalsMethode der Erfassung. Wir verwenden das Ethereum Testnetz.goerliEs ist wichtig zu beachten, dass die Token-Kontraktadressen auf verschiedenen Ketten unterschiedlich sein können.

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", linkAddre

Mehr