Pendahuluan mudah untuk pengembangan web3 berbasis Ethereum dengan FMZ

Penulis:Mimpi kecil, Dibuat: 2023-03-28 13:32:48, Diperbarui: 2023-09-18 20:27:13

[TOC]

img

Tutorial EtherEaseWithFMZ

Pendahuluan mudah untuk pengembangan web3 berbasis Ethereum dengan FMZ

Ethereum adalah platform kontrak pintar berbasis teknologi blockchain yang menyediakan cara terdesentralisasi untuk menulis dan menyebarkan kontrak pintar. Kontrak pintar adalah program komputer khusus yang dapat dijalankan secara otomatis di blockchain dan dapat melaksanakan berbagai logika bisnis tanpa perlu mempercayai pihak ketiga.

Penemu Platform Perdagangan KuantitatifFMZ.COMIni menyediakan API yang mudah digunakan yang memungkinkan pengembang untuk lebih mudah berinteraksi dengan blockchain Ethereum dan ekosistemnya. Fungsi seperti mengakses DEX, mendapatkan data rantai, mengirim transaksi, dll.

Contoh yang digunakan dalam tutorial iniJavaScriptMenulis bahasa, menggunakan lingkungan pengujianEthereumGoerli Testing NetAnda juga dapat melihat API yang digunakan dalam tutorial dan deskripsi dan contoh kode yang terkait di dokumentasi API FMZ.


FMZ digunakan untuk masuk

Sebelum belajar menggunakan FMZ, kita perlu mengetahui beberapa konsep dasar:

1 FMZ Quantified Trading Platform Arsitektur

Di situs resmi FMZhttps://www.fmz.comSetelah mendaftar, Anda dapat menggunakan berbagai fungsi platform. Situs FMZ adalah terminal manajemen seluruh sistem, program yang ditulis pengguna sebenarnya berjalan di host. Program host ini dapat diimplementasikan di berbagai perangkat, seperti server, komputer, dll. Ketika pengguna menulis program yang baik di situs FMZ untuk membuat contoh yang berjalan, platform FMZ akan berkomunikasi dengan host untuk memulai contoh program di host.

img

2. Pengelola

Jika Anda ingin menjalankan contoh program, Anda harus menerapkan host, yang juga sangat sederhana, dan ada tutorial penyebaran di platform. Anda juga dapat menggunakan "One-Knock Deployment Host" yang tersedia di FMZ untuk penyebaran otomatis server sewa FMZ.

  • Mengimplementasikan administrator pada perangkat pribadi

    Program pengelola dapat digunakan pada perangkat seperti server, komputer pribadi, dan lain-lain. Langkah-langkah utama dalam penyebaran adalah:

    1. Masuk atau buka perangkat yang akan Anda gunakan untuk menerapkan program admin, misalnyaMasuk ke serverAtauBuka komputer dan masuk ke sistem operasiAku tidak tahu. 2. Mengunduh versi yang sesuai dari program host (bergantung pada sistem operasi perangkat)https://www.fmz.com/m/add-node img3, download adalah paket kompresi yang perlu dikompresi. 4. Jalankan program admin ini, program admin adalah program bernamarobotFile yang dapat dieksekusi. Mengkonfigurasi alamat komunikasi host, alamat komunikasi yang unik untuk setiap akun FMZ, setelah login FMZhttps://www.fmz.com/m/add-nodeHalaman ini dapat melihat alamat Anda (yaitu:./robot -s node.fmz.com/xxxxxDi sini ada beberapa alamat.xxxxxKonten lokasi, setiap akun FMZ menampilkan berbeda) ; Akhirnya, Anda juga perlu memasukkan kata sandi akun FMZ, mengkonfigurasi ini dan kemudian menjalankan program administrator.

  • Menggunakan fitur "One-click Deploy Host" dari FMZ

    Untuk menambahkan halaman pengelola di platform FMZ, alamat:https://www.fmz.com/m/add-node

    img

3. Alat debugging

FMZ Quantitative Trading Platform menyediakan alat debugging gratis yang mendukung:JavaScriptTypeScriptDi halaman ini:https://www.fmz.com/m/debugKarena pembentukan instance berjalan dengan biaya. Alat debugging ini dapat digunakan untuk pengujian, pembelajaran, dan pembelajaran selama usia sekolah dasar. Alat debugging tidak berbeda dengan pembentukan instance kecuali dengan batas waktu hingga 3 menit.

PenggunaanTypeScriptDalam bahasa, Anda harus menulis di baris pertama kode.// @ts-checkdigunakan untuk beralih keTypeScriptMode, tidak beralih secara default adalahJavaScriptBahasa.

4. Bursa

Di FMZ, "exchange" adalah konsep generik yang untuk bursa CEX berarti konfigurasi akun bursa tertentu. Untuk web3, bursa ini berarti informasi konfigurasi yang berisi alamat node, konfigurasi kunci pribadi.

Setelah login ke platform FMZ, Anda dapat mengaksesnya di:https://www.fmz.com/m/add-platformPada halaman ini, Anda dapat mengkonfigurasi informasi bursa, di mana bursa adalah konsep umum.

img

PilihanWeb3Untuk mengkonfigurasi alamat node RPC, atau mengkonfigurasi kunci pribadi, Anda dapat mengklik bagian bawah kanan "Mengenkripsi informasi sensitif dengan kunci pribadi independen" untuk melihat mekanisme keamanan.

Sebuah node dapat dibuat sendiri atau disediakan oleh penyedia layanan. Ada banyak penyedia layanan, seperti:InfuraSetelah mendaftar, Anda dapat melihat alamat node akun Anda. Situs web utama, situs uji coba tersedia, lebih mudah, konfigurasi alamat node ini di gambar di atas.Rpc AddressDalam kontrol tersebut. Tag dapat diberi nama sendiri, yang digunakan untuk membedakan objek bursa yang dikonfigurasi.

img

Gambarhttps://mainnet.infura.io/v3/xxxxxxxxxxxxxIni adalah alamat RPC pada jaringan utama ETH milik Infura.


Berinteraksi dengan FMZ dan Ethereum

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

Di sini kami akan memberikan beberapa contoh sederhana untuk memulai dengan dasar-dasar.

img

Untuk panggilan metode RPC pada FMZ juga terbungkus, yang berfungsi dalam fungsi API FMZ.exchange.IOCara memanggilnya adalah:exchange.IO("api", "eth", ...)◎ Parameter pertama tetap masuk"api", parameter kedua tetap masuk"eth", parameter lainnya tergantung pada metode RPC yang digunakan.

Kami menggunakan platform FMZ untuk mengekspor informasi.LogFungsi,LogFungsi dapat menginformasikan beberapa parameter dan kemudian mengekspor ke area log di halaman "Debug Tools" atau "Real Disk" di platform FMZ, halaman "Debug Tools" akan menjadi alat utama yang kami uji.

Eth_getBalance

Ethereumeth_getBalanceMetode yang digunakan untuk menanyakan saldo ETH pada alamat Ethereum, yang membutuhkan 2 parameter.

  • Di sini Anda dapat menemukan alamat yang Anda inginkan.
  • Kata "latest" biasanya digunakan dalam tag.

Mari kita tanyakan pada pendiri Ethereum.V神ETH wallet yang diketahui memiliki alamat:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045

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

Sudah mengimplementasikan administrator (gambar: linux/amd64...) dan mengkonfigurasi objek bursa (gambar: Web3 test) dan menguji kode pada alat debugging:

img

Klik tombol "Execute" dan jalankan kode ini, dan hasilnya akan muncul:

EthBalance: 0x117296558f185bbc4c6

LogFungsi yang dicetakethBalanceNilai variabel adalah:0x117296558f185bbc4c6, adalah tipe string.Saldo ETH dengan nilai 16 digitDenganweiSatuan,1e18 weiUntuk 1ETHOleh karena itu, perlu juga dikonversi untuk menjadi saldo ETH desimal yang dapat dibaca.

akanethBalanceMengkonversi data menjadi data yang dapat dibaca:

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

Di atashttps://etherscan.io/Pertanyaan:

img

Namun, alasan untuk melakukan ini adalah karena masalah keakuratan bahasa itu sendiri akan memiliki kecurangan, jadi FMZ memiliki dua fungsi internal untuk memproses data:

  • Big:Int mengubah string 16 digit menjadi objek BigInt.
  • BigDecimal: Mengkonversi objek dengan tipe angka menjadi objek BigDecimal yang dapat dioperasikan.

Ada beberapa hal yang harus diperhatikan.

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

vitalikEthBalanse: 5149.6244846875215

Eth_chainId

eth_chainIddannet_versionKedua fungsi ini mengembalikan Id dari blockchain yang saat ini diakses oleh node RPC, dengan perbedaan:net_versionIni adalah ide yang bagus.eth_chainIdKembali ke Id dari 16 digit.

Nama jaringan yang sesuai dengan chainId

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

Menggunakan jaringan uji Ethereum yang dikonfigurasi dengan baikgoerliPengujian node:

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_gasPrice

Panggilaneth_gasPriceMetode, menanyakan pada rantai saat inigas 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))
}

Di sini kita menuliskan fungsi untuk mengubah string 16 digit menjadi operasi yang dapat dibaca:toAmountSelain itu, unit harga gas adalah:weiJadi, kita bisa menggunakan bentuk sumbu.decimalsNilai transmisi parameter riil yang sesuai adalah 0.

Eth_blockNumbe

eth_blockNumbeUntuk menanyakan ketinggian blok.

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

Perangkat debugging berjalan di:

img

https://etherscan.io/Pertanyaan:

img

eth_getBlockByNumber

Periksa informasi blok.

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

Untuk melakukan debugging di Debug Tools, Anda bisa mendapatkan informasi berikut:

img


Membaca informasi kontrak

Di bawah ini adalah daftar aplikasi kontrak pintar yang tersedia di Ethereum.ENS"Saya tidak tahu apa yang akan terjadi", katanya.ENSEthereum Name Service adalah layanan pemecahan nama domain terdesentralisasi yang didasarkan pada blockchain Ethereum. Apakah Anda ingat di tutorial kami, kita menanyakan contoh saldo dompet pendiri Ethereum, V God?0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045Jika Anda tidak tahu alamatnya, bagaimana Anda bisa tahu alamatnya?ENSSmart contract, menggunakan nama yang intuitifvitalik.eth(vitalik, nama dewa V) untuk melakukan pertanyaan.

Dalam bab ini, kami akan membahas tentang penggunaan lingkungan ethereum.ENSDokumen yang diketahui diperlukan untuk melakukan query pada nama domain EthereumHashing Names, gunakan kode berikut untukvitalik.ethNama yang diproses.

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

Dan di contoh kode di atas, kita melihat fungsi yang aneh lagi.EncodeFungsi ini adalah fungsi API untuk platform FMZ, yang digunakan khusus untuk melakukan operasi pengkodean di platform FMZ. Fungsi ini mendukung berbagai metode pengkodean dan mendukung berbagai algoritma hash.

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

Penggunaan sesuai dengan deskripsi dalam dokumentasi ENSsha3.keccak256Algoritma memproses data.

PanggilannameHashFungsi, misalnya:Log(nameHash("vitalik.eth"))Anda bisa:ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835, perlu ditambah dengan awalan "0x".0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835Ini adalah kontrak pintar ENS.resolverParameter metode.

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

Dengan memeriksa dokumen ENS, Anda dapat mengetahui alamat kontrak aplikasi kontrak cerdas ENS adalah:0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e◦ Menggunakan kontrak pintarresolverSebelum melakukan pendekatan, kita juga harus mempersiapkan kontrak.ABI

Pendaftaran ABI

Saya belajar di sini dan saya bertanya-tanya, apa itu kontrak pintar?ABIApa itu?

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

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

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

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

Mengambil dari ENS dari ABI.resolverBagian dari metode ini juga dapat menggunakan ABI lengkap, yang dapat digunakan dihttps://etherscan.io/Cari ABI kontrak di atas, atau dapatkan ABI dengan cara lain (misalnya: dokumen proyek terkait).

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

Di sini kita akan belajar cara baru untuk menelepon di platform FMZ.exchange.IO("abi", address, abiContent)Dengan menggunakan metode ini, Anda bisa mendaftarkan diri ke ABI.addressParameter adalah alamat kontrak pintar.abiContentParameter adalah kontrak cerdas yang sesuai 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智能合约的地址

Cara Menggunakan Kontrak Pintar

Anda bisa menggunakan kontrak pintar ENS.resolverIni adalah metode, metode kembali.ENS: Public ResolverAlamat kontraknya.

img

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

PenggunaanENS: Public ResolverPerjanjianaddrCara mendapatkan alamat dompet dewa V.ENS: Public ResolverKontrak masih harus didaftarkan terlebih dahulu di ABI. Informasi ABI dari kontrak pintar ini masih dapat diakses darihttps://etherscan.io/Saya tidak tahu apa yang terjadi.

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

Panggilan terakhirENS: Public ResolverPerjanjianaddrMetode, parameter tetap samaensNode

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

Fungsi log output:

img

vitalikAddress: 0xd8da6bf26964af9d7eed9e03e53415d37aa96045

Kode lengkap untuk memanggil 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)
}

Mengirim ETH

Pada bagian sebelumnya, kita telah belajar bagaimana mengkonfigurasi kunci pribadi, bagaimana kita tahu alamat dompet yang sesuai dengan kunci pribadi untuk objek pertukaran yang telah dikonfigurasi?exchange.IO("address")Fungsi ini mendapatkan alamat dompet yang sesuai dengan kunci pribadi yang dikonfigurasi.

Karena isi dari pasal iniGoerliDi sini, saya akan mencoba untuk mengkoneksikan beberapa hal yang saya tidak pernah lakukan.https://goerli.infura.io/v3/*******Di sini, infura memberikan alamat node yang berbeda untuk setiap pengguna terdaftar.*******Di sini, Anda dapat melihat beberapa gambar yang menarik dari video tersebut.

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

img

Setelah mengetahui alamat dompet Anda, Anda dapat menggunakan metode RPC Ethereum.eth_getTransactionCountPerhitungan transaksi untuk menanyakan alamat dompet. Di Ethereum, perhitungan ini sangat umum digunakan, sebenarnya adalah apa yang perlu ditransfer saat operasi transfer.nonceParameter, di Ethereum, nonce digunakan untuk memastikan setiap transaksi adalah angka yang unik. Ini adalah angka yang meningkat dan akan meningkat secara otomatis setiap kali transaksi baru dikirim. Oleh karena itu, ketika Anda mengirim transaksi ke kontrak pintar, perlu memberikan nonce untuk memastikan transaksi itu unik dan urutan yang benar.

https://goethereumbook.org/en/

img

Di sini kita bisa melihat data dari Ethereum di Go.PendingNonceAtFungsi sebenarnya adalah fungsi yang dipanggil.eth_getTransactionCountMetode. Pada pelajaran sebelumnya kita juga belajar bagaimana menggunakan metode RPC, dan kita akan menggunakannya lagi di sini.exchange.IO("api", "eth", ...)Fungsi tersebut.

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

Sebelum menjelaskan operasi transfer, kita hanya perlu memahami beberapa konsep bahwa transfer di Ethereum akan menghabiskan sejumlah token ETH (sebagai biaya gas). Biaya gas ditentukan oleh dua parameter:

  • Gas Harga

    Namun, biaya bahan bakar di jaringan Ethereum selalu berfluktuasi sesuai dengan kebutuhan pasar dan biaya yang bersedia dibayar pengguna, sehingga menulis biaya bahan bakar tetap dalam kode kadang-kadang bukan pilihan yang ideal.eth_gasPriceMetode yang digunakan untuk mendapatkan harga gas rata-rata.

  • gasLimit

    Batas gas untuk transfer Ethereum standar adalah 21000 unit.

Aku mengerti.noncegasPricegasLimitKonsep-konsep ini dapat diuji transfer. Fungsi transfer yang terbungkus di FMZ sangat sederhana dan mudah digunakan.

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

Saat digunakan sebagai transfer uang,exchange.IOPada saat itu, Anda akan melihat bahwa Anda tidak dapat mengirim pesan.toAddressParameter adalah alamat tempat ETH diterima saat transfer, dan alamat tempat ETH diterima saat transfer.toAmountJumlah ETH yang ditransfer.

noncegasPricegasLimitParameter-parameter ini dapat digunakan pada FMZ dengan nilai yang diperoleh secara otomatis oleh sistem secara default.

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

Setelah itu, kita melakukan transfer ETH ke alamat tertentu di 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
}

Karena satuan jumlah transfer Ethereum adalahweiAnda perlu menggunakan fungsi kustom.toInnerAmountMengolahnya sebagaiweiNilai dari satuan tersebut.

dihttps://etherscan.io/Periksa Hash Transaksi di atas:0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e

img

Anda juga dapat menulis kode untuk menanyakan transfer hash.0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734eMenggunakaneth_getTransactionReceiptCara melakukan pertanyaan.

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

Hasil pencarian:

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

Setiap kolom memiliki deskripsi yang sesuai:

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

Menggunakan kontrak pintar Ethereum

Kami berada diMembaca informasi kontrakDalam bab ini, dengan menggunakan contoh lengkap, metode panggilan kontrak ENS yang diimplementasikan di Ethereum memperoleh alamat dompet V; metode-metode ini termasuk:ReadMetode-metode ini tidak perlu disebut.gasJika Anda ingin melihat apa yang akan terjadi di masa depan, maka Anda harus melihat apa yang akan terjadi di masa depan.WriteCara dan PembayarangasOperasi-operasi ini akan divalidasi oleh setiap node di seluruh jaringan dan juga penambang, dan mengubah status blockchain.

ERC20

Untuk kontrak ERC20 (kontrak token ERC20), FMZ menempatkan kontrak ERC20 sebagai ABI yang biasa digunakan secara langsung di sistem, melewati langkah mendaftarkan ABI ini. Untuk ABI, kami juga belajar di tutorial sebelumnya bahwa kami mendaftarkan kontrak ENS sebelum menggunakan metode kontrak ENS.

Untuk memahami ABI dengan lebih jelas, berikut adalah ABI kontrak ERC20 sebelum digunakan:

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

Bagian ini menggunakanGoerliPercobaan lingkungan web.

saldo dari

Dan kemudian kita berlatih lagi bagaimana memanggil kontrak.ReadCara membaca informasi kontrak dan memanggil kontrak ERC20balanceOfCara untuk mencari saldo tokenbalanceOfMetode hanya memiliki satu parameter, tetapi tidak diberi nama, yang dapat dilihat oleh jenisnya sebagai alamat (yaitu alamat token yang ditanyakan). Karena data yang dikembalikan tidak diukur dalam satu token, maka data presisi token juga diperlukan untuk dihitung, dan presisi token dapat diukur dalam kontrak ERC20.decimalsCara mendapatkannya. Kami menggunakan Ethereum Test Net.goerliPeriksa, perhatikan bahwa alamat kontrak token mungkin berbeda di rantai yang berbeda.

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

Lebih banyak