[TOC]

Nutzen Sie FMZ für den einfachen Einstieg in die Ethereum-basierte Web3-Entwicklung
Ethereum ist eine auf der Blockchain-Technologie basierende Smart-Contract-Plattform, die eine dezentrale Möglichkeit zum Schreiben und Bereitstellen von Smart Contracts bietet. Ein Smart Contract ist ein spezielles Computerprogramm, das automatisch auf der Blockchain ausgeführt werden kann und verschiedene Geschäftslogiken implementieren kann, ohne dass dabei das Vertrauen in einen Dritten erforderlich ist.
Die Inventor Quantitative Trading Platform (FMZ.COM) bietet eine benutzerfreundliche API, die Entwicklern die Interaktion mit der Ethereum-Blockchain und ihrem Ökosystem erleichtert. Realisieren Sie Funktionen wie den Zugriff auf dezentrale Börsen (DEX), das Abrufen von On-Chain-Daten und das Senden von Transaktionen.
Die Beispiele in diesem Tutorial verwendenJavaScriptSprachenschreiben, Nutzung der TestumgebungEthereum-Mainnet、Goerli Testnet. Die im Tutorial verwendeten API-Schnittstellen sowie zugehörige Beschreibungen und Codebeispiele können Sie sich auch in der API-Dokumentation der FMZ-Plattform ansehen.
Bevor wir die Nutzung der quantitativen Handelsplattform von FMZ erlernen, müssen wir uns mit mehreren grundlegenden Konzepten vertraut machen:
Nach der Registrierung und Anmeldung auf der offiziellen Website der quantitativen Handelsplattform FMZ (https://www.fmz.com) können Sie die verschiedenen Funktionen der Plattform nutzen. Die FMZ-Website ist die Verwaltungsseite des gesamten Systems, und die von Benutzern geschriebenen Programme werden tatsächlich auf dem Host ausgeführt. Der Host ist ein Softwareprogramm, das auf verschiedenen Geräten wie Servern, Computern usw. bereitgestellt werden kann. Wenn ein Benutzer ein Programm schreibt und eine laufende Instanz auf der FMZ-Website erstellt, kommuniziert die FMZ-Plattform mit dem Host und startet eine Programminstanz auf dem Host.

Wenn Sie eine Programminstanz ausführen möchten, müssen Sie einen Host bereitstellen. Die Hostbereitstellung ist ebenfalls sehr einfach und auf der Plattform gibt es ein Bereitstellungstutorial. Alternativ können Sie den auf der FMZ bereitgestellten „One-Click-Deployment-Host“ nutzen, um die Bereitstellung automatisch über die von der FMZ gemieteten Server durchzuführen.
Das Custodian-Programm kann auf Servern, PCs und anderen Geräten bereitgestellt und ausgeführt werden, solange das Netzwerk normal ist (das entsprechende Ziel muss zugänglich sein, z. B. eine Exchange-Schnittstelle, Knotenadresse usw.). Die wichtigsten Schritte der Bereitstellung sind:

robotausführbare Datei. Konfigurieren Sie die Kommunikationsadresse des Depotverwalters. Diese Kommunikationsadresse ist für jedes FMZ-Konto eindeutig. Nach der Anmeldung bei FMZhttps://www.fmz.com/m/add-nodeDie Seite kann ihre eigene Adresse anzeigen (d. h../robot -s node.fmz.com/xxxxxDiese Adressenfolge hierxxxxxDie Darstellung der Standortinhalte erfolgt je FMZ-Account unterschiedlich. Zum Schluss müssen Sie noch das Passwort des FMZ-Accounts eingeben. Nach der Konfiguration führen Sie das Host-Programm aus.Fügen Sie eine Depotbankseite auf der FMZ-Plattform hinzu, Adresse:https://www.fmz.com/m/add-node

Die quantitative Handelsplattform FMZ bietet ein kostenloses Debugging-Tool, das unterstütztJavaScript,TypeScriptDie Seite lautet: https://www.fmz.com/m/debug, da das Erstellen und Ausführen einer Instanz kostenpflichtig ist. Dieses Debugging-Tool kann während der ersten Lernphase zum Testen und Lernen verwendet werden. Das Debugging-Tool unterscheidet sich nicht vom Erstellen einer Instanz, außer dass die Ausführungsdauer auf 3 Minuten begrenzt ist.
verwendenTypeScriptWenn Sie die Sprache verwenden, müssen Sie sie in die erste Codezeile schreiben// @ts-checkUm zu wechselnTypeScriptModus, wenn nicht umgeschaltet, ist die StandardeinstellungJavaScriptSprache.
Bei FMZ ist „Börse“ ein allgemeiner Begriff. Bei einer CEX-Börse bezieht es sich auf eine bestimmte Börsenkontokonfiguration. Für Web3 bezieht sich dieser Austausch auf Konfigurationsinformationen, einschließlich Knotenadresse und privater Schlüsselkonfiguration.
Wenn Sie auf der FMZ-Plattform angemeldet sind,https://www.fmz.com/m/add-platformAuf dieser Seite können Sie die Austauschinformationen konfigurieren, wobei „Austausch“ ein allgemeines Konzept ist.

wählenWeb3, konfigurieren Sie die RPC-Knotenadresse und den privaten Schlüssel. Sie können unten rechts auf „Vertrauliche Informationen werden mit einem unabhängigen privaten Schlüssel verschlüsselt und gespeichert“ klicken, um den Sicherheitsmechanismus anzuzeigen.
Die Knoten können selbst erstellt oder von Knotendienstanbietern bereitgestellt werden. Es gibt viele Knotendienstanbieter, beispielsweise:Infura. Nach der Registrierung können Sie die Knotenadresse Ihres Kontos anzeigen. Es gibt sowohl ein Mainnet als auch ein Testnet, was praktischer ist. Konfigurieren Sie diese Knotenadresse in der obigen Abbildung.Rpc Addressin den Steuerelementen. Um die konfigurierten Austauschobjekte zu unterscheiden, können Tags eigene Namen erhalten.

In der Abbildunghttps://mainnet.infura.io/v3/xxxxxxxxxxxxxEs handelt sich um die private RPC-Knotenadresse des Infura ETH-Mainnets.
Nach der Bereitstellung des Custodian-Programms und der Konfiguration des Exchange-Objekts können Sie zum Testen das „Debugging-Tool“ von FMZ.COM verwenden. Rufen Sie Ethereum RPC-Methoden auf, um mit Ethereum zu interagieren. Zusätzlich zu den verschiedenen in diesem Kapitel aufgeführten RPC-Methoden können Sie in der Dokumentation nach weiteren RPC-Methoden suchen, wie z. B.https://www.quicknode.com/docs。
Nehmen wir ein paar einfache Beispiele und beginnen mit den Grundlagen. Es gibt verschiedene Möglichkeiten, auf Web3 zuzugreifen, und zwar mit verschiedenen Sprachen und Tools, wie in der Abbildung dargestellt:

RPC-Methodenaufrufe werden auch in FMZ gekapselt. Diese Funktionen sind in der FMZ-API-Funktion gekapseltexchange.IOMitte. Die aufrufende Methode istexchange.IO("api", "eth", ...). Der erste Parameter ist fest."api", der zweite Parameter ist fest"eth", andere Parameter hängen von der jeweils aufgerufenen RPC-Methode ab.
Zur Ausgabe von Informationen nutzen wir die FMZ-PlattformLogFunktion,LogDie Funktion kann mehrere Parameter übergeben und diese dann im Log-Bereich der Seite „Debug-Tool“ oder „Real Trading“ der FMZ-Plattform ausgeben. Die Seite „Debug-Tool“ wird das Haupttool für unsere Tests sein.
Äthereth_getBalanceDie Methode wird verwendet, um den ETH-Kontostand einer Adresse auf Ethereum abzufragen. Für diese Methode müssen zwei Parameter übergeben werden.
Werfen wir einen Blick auf den Gründer von EthereumV神ETH Wallet-Adresse, bekannte Adressen sind:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045。
function main() {
let ethBalance = exchange.IO("api", "eth", "eth_getBalance", "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest")
Log("ethBalance:", ethBalance)
}
Der Custodian wurde bereitgestellt (in der Abbildung: linux/amd64 …) und das Exchange-Objekt wurde konfiguriert (in der Abbildung: Web3-Test). Testen Sie den Code im Debugging-Tool:

Klicken Sie auf die Schaltfläche „Ausführen“, um diesen Code auszuführen und die Ergebnisse anzuzeigen:
ethBalance: 0x117296558f185bbc4c6
LogDie Funktion drucktethBalanceDie Variablenwerte sind:0x117296558f185bbc4c6, ein Zeichenfolgentyp. JaETH-Guthaben im Hexadezimalwert,vonweiAls Einheit1e18 weiist 1ETH. Daher muss es in einen lesbaren ETH-Dezimalsaldo umgewandelt werden.
WilleethBalanceIn lesbare Daten konvertieren:
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)
}

An der Spitzehttps://etherscan.io/Abfrage:

Da es bei dieser Verarbeitung jedoch aufgrund der Genauigkeit der Sprache selbst zu Abweichungen kommt, verfügt die FMZ-Plattform über zwei integrierte Funktionen zur Datenverarbeitung:
Passe den Code noch einmal an:
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()))
}
vitalikEthBalance: 5149.6244846875215
eth_chainIdUndnet_versionDie Einsatzmöglichkeiten sind ähnlich, deshalb haben wir sie zusammen getestet. Beide Funktionen geben die ID der Blockchain zurück, mit der der aktuelle RPC-Knoten verbunden ist. Der Unterschied istnet_versionGibt die Dezimal-ID zurück.eth_chainIdGibt die hexadezimale ID zurück.
Der 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

Verwenden Sie das konfigurierte Ethereum-TestnetzwerkgoerliKnotentest:
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))
}

Anrufeth_gasPriceMethode zum Abfragen der aktuellen Kettegas 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, um einen hexadezimalen String in einen lesbaren Wert umzuwandeln:toAmount. Zu beachten ist auch, dass die Einheit des Gaspreiseswei, also der ParameterdecimalsDer entsprechende Aktualparameter kann als 0 übergeben werden.
eth_blockNumbeWird zum Abfragen der Blockhöhe verwendet.
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))
}
Im Debugger ausführen:

https://etherscan.io/Auf Anfrage:

Informationen zum Abfrageblock.
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])
}
}
Durch die Ausführung im „Debug Tool“ können folgende Informationen abgerufen werden:

Auf Ethereum laufen zahlreiche Smart-Contract-Anwendungen.ENSist einer davon.ENS, nämlich der Ethereum Name Service, ist ein dezentraler Domänennamenauflösungsdienst, der auf der Ethereum-Blockchain basiert.
Erinnern Sie sich an das Beispiel im Tutorial, in dem wir den Wallet-Kontostand des Ethereum-Gründers Vitalik Buterin abgefragt haben? Eine von Vitaliks Wallet-Adressen lautet:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045. Woher kennen wir diese Adresse? Tatsächlich durchENSIntelligenter Vertrag mit einem intuitiven Namenvitalik.eth(vitalik ist der Name von Vitalik), um die Abfrage durchzuführen.
Die folgenden Inhalte in diesem Kapitel verwenden die Hauptnetzwerkumgebung von Ethereum.ENSAus dem Dokument geht hervor, dass der abzufragende Ethereum-DomänennameHashing Names, verwenden Sie den folgenden Code, umvitalik.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))
}
}
Im obigen Codebeispiel sehen wir eine weitere unbekannte FunktionEncodeDiese Funktion ist die API-Funktion der FMZ-Plattform, die speziell zum Ausführen von Codierungsvorgängen auf der FMZ-Plattform verwendet wird. Diese Funktion unterstützt mehrere Codierungsmethoden und mehrere Hash-Algorithmen.
Encode(algo, inputFormat, outputFormat, data, keyFormat, key string)
Gemäß der ENS-Dokumentation verwenden Siesha3.keccak256Algorithmen verarbeiten Daten.
AnrufnameHashFunktionen zum Beispiel:Log(nameHash("vitalik.eth"))erhalten wir:ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835müssen Sie das Präfix „0x“ hinzufügen.0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835Als ENS Smart ContractresolverDie Parameter der Methode.
let ensNode = "0x" + nameHash("vitalik.eth") // 准备好调用resolver方法的参数ensNode
Laut dem ENS-Dokument lautet die Vertragsadresse der ENS-Smart-Contract-Anwendung:0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e. Beim Aufruf des Smart ContractsresolverBevor wir fortfahren, müssen wir den Vertrag vorbereitenABI。
Nachdem ich das erfahren habe, muss ich einfach fragen: Was ist ein Smart Contract?ABIWolltuch?
ABI,即应用程序二进制接口(Application Binary Interface),是智能合约与外部世界进行通信的接口标准。
智能合约的 ABI 定义了合约的函数接口、参数类型、返回值等信息,以及调用合约的方式和参数传递方式等规范。
智能合约的 ABI 通常以 JSON 格式存储,包含以下信息:
合约的函数接口:函数名、参数列表、返回值等信息。
函数参数类型:如 uint256、bool、string 等。
函数的输入参数和输出参数的编码方式:智能合约使用一种称为 Solidity ABI 的编码方式来编码函数的输入参数和输出参数,
以便与以太坊网络进行交互。
在以太坊网络中,使用智能合约的 ABI 来调用合约的函数。当需要调用合约函数时,需要提供函数名和函数参数,以及将函数参数按照 ABI 编码方式编码后的字节码。
以太坊节点会将这些信息打包成一笔交易,并将交易发送到以太坊网络中执行。
智能合约的 ABI 在 Solidity 语言中可以通过 interface 关键字来定义。以太坊开发工具如 Remix IDE、Truffle 等也提供了 ABI 编辑和生成工具,
使得开发者可以方便地创建和使用智能合约的 ABI。
Extrahieren Sie Folgendes aus ENS ABI:resolverDer vollständige ABI kann auch verwendet werden in derhttps://etherscan.io/Sie können die ABI des Vertrags auf GitHub abfragen oder die ABI auf andere Weise erhalten (z. B. über relevante Projektdokumente).

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 müssen wir eine neue Anrufmethode auf der FMZ-Plattform erlernen.exchange.IO("abi", address, abiContent), verwenden Sie diese Methode, um ABI zu registrieren,addressDer Parameter ist die Adresse des Smart Contracts.abiContentDer Parameter ist die entsprechende Smart Contract ABI (Zeichenfolge).
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智能合约的地址
Als nächstes können Sie den ENS Smart Contract aufrufenresolverMethode, die zurückgibtENS: Public ResolverDie Adresse des Vertrags.

let resolverAddress = exchange.IO("api", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", "resolver", ensNode)
verwendenENS: Public ResolverVertraglichaddrMethode zum Abrufen der Wallet-Adresse von Vitalik. AnrufenENS: Public ResolverDer Vertrag muss noch zuerst ABI registrieren. Die ABI-Informationen dieses Smart Contracts finden Sie weiterhin unterhttps://etherscan.io/Erhalten.
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)

Letzter AufrufENS: Public ResolverVertraglichaddrMethode, die Parameter sind nochensNode。
let vitalikAddress = exchange.IO("api", resolverAddress, "addr", ensNode)
Log("vitalikAddress:", vitalikAddress)
Ausgabe der Protokollfunktion:

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)
}
In den vorherigen Kurskapiteln haben wir gelernt, wie man private Schlüssel konfiguriert. Woher wissen wir für das konfigurierte Austauschobjekt, welche Wallet-Adresse diesem privaten Schlüssel entspricht? Verfügbar auf FMZexchange.IO("address")Die Funktion erhält die Wallet-Adresse, die dem konfigurierten privaten Schlüssel entspricht.
Da die folgenden Inhalte dieses KapitelsGoerliTestnetzwerkumgebung. Der von mir verwendete Knoten ist:https://goerli.infura.io/v3/*******, Infura weist jedem registrierten Benutzer eine andere Knotenadresse zu.*******Der konkrete Inhalt ist ausgeblendet.
function main() {
let walletAddress = exchange.IO("address")
Log("测试网 goerli 钱包地址:", walletAddress)
}

Sobald Sie Ihre Wallet-Adresse kennen, können Sie die RPC-Methode von Ethereum verwendeneth_getTransactionCountFragen Sie die Transaktionsanzahl einer Wallet-Adresse ab. Diese Zahl wird in Ethereum sehr häufig verwendet. Tatsächlich muss sie bei Geldüberweisungen eingegeben werden.nonceParameter: In Ethereum ist Nonce eine Nummer, die verwendet wird, um sicherzustellen, dass jede Transaktion eindeutig ist. Es handelt sich um eine ansteigende Zahl, die bei jeder gesendeten Transaktion automatisch erhöht wird. Wenn Sie daher eine Transaktion an einen Smart Contract senden, müssen Sie einen Nonce bereitstellen, um sicherzustellen, dass die Transaktion eindeutig ist und in der richtigen Reihenfolge erfolgt. In einigen Daten und Dokumenten finden wir:

Hier ist die Ethereum-Bibliothek in der Sprache GoPendingNonceAtDie Funktion ruft tatsächlich aufeth_getTransactionCountVerfahren. Im vorherigen Kurs haben wir auch gelernt, wie man RPC-Methoden aufruft. Wir werden es hier erneut verwenden.exchange.IO("api", "eth", ...)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 den Überweisungsvorgang erklären, wollen wir kurz einige Konzepte verstehen. Bei der Überweisung von Geld auf Ethereum wird eine bestimmte Menge an ETH-Token verbraucht (als Gasgebühr). Die Gasgebühr wird durch zwei Parameter bestimmt:
Da die Gasgebühren im Ethereum-Netzwerk jedoch ständig schwanken, richtet sich dies nach der Marktnachfrage und der Zahlungsbereitschaft der Benutzer. Daher ist es manchmal nicht ideal, eine feste Gasgebühr in den Code einzutragen. Wir können das nutzen, was wir zuvor gelernt habeneth_gasPriceMethode, mit der der durchschnittliche Gaspreis ermittelt werden kann.
Das Gaslimit für eine Standard-Ether-Übertragung beträgt 21.000 Einheiten.
Habe esnonce,gasPrice,gasLimitMit diesen Konzepten können Sie die Übertragung testen. Auf FMZ ist eine sehr einfache und leicht zu bedienende Übertragungsfunktion gekapselt.
exchange.IO("api", "eth", "send", toAddress, toAmount)
Bei Verwendung zur Übertragungexchange.IODer dritte Parameter ist immer „senden“.toAddressDer Parameter ist die Adresse, die ETH während der Übertragung empfängt.toAmountDer überwiesene ETH-Betrag.
nonce,gasPrice,gasLimitDiese Parameter können die vom System standardmäßig automatisch erhaltenen Werte auf FMZ verwenden. Sie können außerdem Folgendes angeben:
exchange.IO("api", "eth", "send", toAddress, toAmount, {gasPrice: 5000000000, gasLimit: 21000, nonce: 100})
Als nächstes überweisen wir einen bestimmten Betrag an ETH an eine bestimmte Adresse im Testnetzwerk 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 des Ethereum-Überweisungsbetrags istweimüssen Sie eine benutzerdefinierte Funktion verwendentoInnerAmountVerarbeitet alsweiDer Wert der Einheit.
existierenhttps://etherscan.io/Transaktions-Hash abfragen:0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e。

Sie können auch Code schreiben, um den Transfer-Hash abzufragen0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e,verwendeneth_getTransactionReceiptAbzufragende Methode.
function main() {
let transHash = "0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e"
let info = exchange.IO("api", "eth", "eth_getTransactionReceipt", transHash)
return info
}
Abfrageergebnisse:
{
"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": []
}
Beschreibung der einzelnen Felder:
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 - 值的类型
Wir sindVertragsinformationen lesenIn diesem Abschnitt wird anhand eines vollständigen Beispiels der auf Ethereum bereitgestellte ENS-Vertrag aufgerufen, um Vitaliks Wallet-Adresse zu erhalten. Diese Methoden gehören zuReadMethoden, der Aufruf dieser Methoden ist nicht notwendiggas(Erinnern Sie sich, was wir vorhin über Gas gesprochen haben?). In diesem Abschnitt werden wir einige Smart Contracts auf Ethereum aufrufenWriteMethode und Zahlunggas. Diese Vorgänge werden von jedem Knoten und Miner im gesamten Netzwerk überprüft und ändern den Blockchain-Status.
Bei ERC20-Verträgen (ERC20-Token-Verträgen) listet die FMZ-Plattform die ABI des ERC20-Vertrags als häufig verwendete ABI auf und baut sie direkt in das System ein, wodurch der Schritt der Registrierung der ABI entfällt. Wir haben im vorherigen Tutorial auch etwas über ABI gelernt. Wenn wir die ENS-Vertragsmethode aufrufen, registrieren wir zuerst den ABI des ENS-Vertrags.
Um den ABI besser zu verstehen, können Sie ihn vor der Verwendung überprüfen. Im Folgenden finden Sie den ABI des ERC20-Vertrags:
”`javascript [{“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”:“ad