Pengembangan web3 berasaskan Ethereum dengan FMZ

Penulis:Mimpi kecil, Dicipta: 2023-03-28 13:32:48, Dikemas kini: 2023-09-18 20:27:13

[TOC]

img

Tutorial EtherEaseWithFMZ

Pengembangan web3 berasaskan Ethereum dengan FMZ

Ethereum adalah platform kontrak pintar berdasarkan teknologi blockchain yang menyediakan cara terdesentralisasi untuk menulis dan menggunakan kontrak pintar. Kontrak pintar adalah program komputer khas yang boleh dijalankan secara automatik di atas blockchain dan dapat melaksanakan pelbagai logika perniagaan tanpa memerlukan kepercayaan pihak ketiga.

Pencipta Platform Perdagangan KuantitatifFMZ.COMPerisian ini menyediakan API yang mudah digunakan yang membolehkan pemaju berinteraksi dengan blockchain Ethereum dan ekosistemnya dengan lebih mudah.

Contoh penggunaan dalam tutorial iniJavaScriptPenulisan bahasa, penggunaan persekitaran ujianEthereumRangkaian Ujian Goerli◦ Dalam dokumentasi API untuk FMZ platform, anda juga boleh melihat antara muka API yang digunakan dalam tutorial serta penerangan dan contoh kod yang berkaitan.


FMZ digunakan untuk masuk

Sebelum belajar menggunakan platform dagangan kuantitatif FMZ, kita perlu mengetahui beberapa konsep asas:

1, FMZ kuantiti platform perdagangan

Di laman web rasmi FMZ Quantum Tradinghttps://www.fmz.comPerisian ini boleh digunakan pada pelbagai peranti, seperti pelayan, komputer, dan lain-lain. Apabila pengguna menulis program yang baik di laman web FMZ untuk mencipta contoh yang berjalan, platform FMZ akan berkomunikasi dengan pentadbir untuk memulakan contoh program di pentadbir.

img

2. Pengurus

Jika anda ingin menjalankan contoh program, anda perlu menggunakan hoster, dan penyebaran hoster sangat mudah, dengan tutorial penyebaran di platform. Anda juga boleh menggunakan "One-Knock Deployment Host" yang disediakan di FMZ untuk menggunakan pelayan sewa FMZ secara automatik.

  • Menghantar pengurus pada peranti peribadi

    Program pentadbir boleh diedarkan pada peranti seperti pelayan, komputer peribadi, dan lain-lain, dengan memastikan rangkaian berfungsi dengan baik. Langkah-langkah utama yang digunakan ialah:

    1. Masuk atau buka peranti yang akan menggunakan program pentadbir, sepertiLog masuk ke pelayanatauBuka komputer dan masuk ke sistem operasiSaya tidak tahu. 2. Muat turun program pentadbir versi yang sesuai (bergantung pada sistem operasi peranti), muat turun halaman:https://www.fmz.com/m/add-node img3, download adalah pakej mampatan yang perlu dikompres. 4. Jalankan program pengurus ini.robotFile yang boleh dilaksanakan. Mengkonfigurasi alamat komunikasi pentadbir, yang merupakan alamat komunikasi yang unik untuk setiap akaun FMZ, selepas log masuk ke FMZhttps://www.fmz.com/m/add-nodeHalaman ini boleh melihat alamat anda (iaitu./robot -s node.fmz.com/xxxxxDi sini, anda boleh lihat alamat.xxxxxKandungan lokasi, setiap akaun FMZ dipaparkan berbeza) ; akhirnya, anda juga perlu memasukkan kata laluan akaun FMZ, yang kemudian boleh dijalankan oleh pentadbir.

  • Menggunakan FMZ Platform "Penghantaran Pengurus dengan Satu Tombol"

    Tambah halaman pentadbir di platform FMZ, alamat:https://www.fmz.com/m/add-node

    img

3. Alat penyesuaian

FMZ Quantitative Trading Platform menyediakan alat debugging percuma yang menyokongJavaScriptTypeScriptDi laman web ini:https://www.fmz.com/m/debugAlat ini boleh digunakan untuk menguji, belajar, dan belajar semasa sekolah rendah. Alat ini tidak mempunyai perbezaan lain selain daripada had jangka masa yang terhad kepada 3 minit.

PenggunaanTypeScriptDalam bahasa, anda perlu menulis pada baris pertama kod.// @ts-checkdigunakan untuk menukar keTypeScriptModel, tidak beralih adalah lalaiJavaScriptBahasa.

4. Bursa

Pada FMZ, "pertukaran" adalah konsep umum yang merujuk kepada konfigurasi akaun pertukaran tertentu untuk bursa CEX. Untuk web3, pertukaran ini merujuk kepada maklumat konfigurasi yang mengandungi alamat nod, konfigurasi kunci peribadi.

Di sini, anda boleh melihat gambar di bawah.https://www.fmz.com/m/add-platformDi sini, pertukaran adalah konsep umum.

img

PilihanWeb3Untuk mengkonfigurasi alamat nod RPC, atau untuk mengkonfigurasi kunci peribadi, anda boleh mengklik "Mengekodkan maklumat sensitif dengan kunci peribadi bebas" di sebelah kanan bawah untuk melihat mekanisme keselamatan.

Node boleh menggunakan nodes yang dibina sendiri, atau boleh menggunakan nodes yang disediakan oleh pelayan nodes. Terdapat banyak pelayan nodes, contohnya:Infura▽ Setelah mendaftar, anda boleh melihat alamat nod akaun anda. ▽ Laman web utama, laman web ujian ada, lebih mudah, sesuaikan alamat nod ini dalam gambar di atas.Rpc AddressDalam kawalan tersebut. Label boleh memberi nama sendiri untuk membezakan objek bursa yang dikonfigurasikan.

img

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


Berinteraksi dengan FMZ dan Ethereum

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

Kami menyenaraikan beberapa contoh mudah untuk memulakan dengan asas. Terdapat pelbagai cara untuk mengakses web3 untuk pelbagai bahasa dan alat, seperti:

img

Dalam FMZ, panggilan kaedah RPC juga dibungkus, yang berfungsi dalam fungsi API FMZ.exchange.IOCara panggilan ialah:exchange.IO("api", "eth", ...)◎ Parameter pertama adalah input tetap"api"Parameter kedua adalah input tetap."eth", parameter lain bergantung kepada kaedah RPC yang digunakan.

Kami menggunakan platform FMZ untuk mengeluarkan maklumat.LogFungsi,LogFungsi boleh menghantar pelbagai parameter, dan output ke kawasan log di halaman "Debug Tools" atau "Real Disk" di platform FMZ, halaman "Debug Tools" akan menjadi alat utama kami untuk menguji.

eth_getBalance

Ethereumeth_getBalanceKaedah yang digunakan untuk menanyakan baki ETH di alamat Ethereum yang memerlukan dua parameter.

  • Alamat yang diperlukan.
  • Tag, biasanya menggunakan "latest".

Mari kita tanya pencipta Ethereum.V神Alamat dompet ETH yang diketahui ialah:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045

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

Sudah menggunakan hoster (gambar: linux/amd64...) dan mengkonfigurasi objek bursa (gambar: Web3 test) dan menguji kod dalam alat debugging:

img

Klik butang "Execute" untuk menjalankan kod ini dan hasilnya akan muncul:

EthBalanse: 0x117296558f185bbc4c6

LogFungsi yang dicetakethBalanceNilai pembolehubah ialah:0x117296558f185bbc4c6, adalah jenis baris.Saldo ETH dengan nilai 16 digit,weiSatuan,1e18 weiUntuk 1ETHOleh itu, ia juga perlu ditukar untuk menjadi baki ETH desimal yang boleh dibaca.

akanethBalanceMengubah data menjadi data yang boleh 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

Ke atashttps://etherscan.io/Permintaan:

img

Walau bagaimanapun, alasan untuk melakukan ini adalah kerana masalah ketepatan bahasa itu sendiri akan menjadi salah, jadi FMZ platform telah membina dua fungsi untuk memproses data:

  • Big:Int menukar strings berangka 16 digit kepada objek BigInt.
  • BigDecimal: Mengubah objek jenis bilangan kepada objek BigDecimal yang boleh dioperasikan.

Peraturan kod semula:

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_versionFungsi yang digunakan hampir sama, jadi letakkan bersama-sama. Kedua-dua fungsi ini mengembalikan id rpc pada rpc yang sedang digunakan.net_versionKembali ke id perpuluhan,eth_chainIdKembali ke Id pada 16 digit.

Jenama rangkaian yang sepadan 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 Ethereum Test Net yang disusun dengan baikgoerliPercubaan nod:

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_gasPriceKaedah untuk menyiasat pada rantaian semasagas 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 menukar strings 16 digit menjadi operasi yang boleh dibaca:toAmount◦ Perlu juga diperhatikan bahawa unit harga gas adalah:weiJadi, kita boleh ubahnya menjadidecimalsNilai parameter sebenar yang sepadan adalah 0.

Eth_blockNumbe

eth_blockNumbeIa digunakan untuk 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))
}

Perisian penyempurnaan dijalankan di:

img

https://etherscan.io/Permintaan:

img

eth_getBlockByNumber

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

Perisian ini boleh digunakan untuk mengesan maklumat berikut:

img


Membaca maklumat kontrak

Terdapat banyak aplikasi kontrak pintar yang dijalankan di Ethereum.ENSSaya tidak tahu apa yang akan berlaku.ENSPerkhidmatan Nama Domain Ethereum (Ethereum Name Service) adalah perkhidmatan pemecahan nama domain terdesentralisasi berdasarkan blockchain Ethereum. Adakah anda ingat di dalam tutorial kami, kami menanyakan contoh baki dompet V Tuhan, pengasas Ethereum?0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045Jika anda mempunyai alamat di sini, bagaimana anda tahu alamat ini?ENSKontrak pintar, menggunakan nama yang mudah difahamivitalik.eth(Vitalik, nama Tuhan V) untuk membuat pertanyaan.

Dalam bab ini, kita akan menggunakan persekitaran Ethereum untukENSDokumen diketahui memerlukan nama domain Ethereum yang dicariHashing Names, gunakan kod berikut untukvitalik.ethNama 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))
    }
}

Dalam contoh kod di atas, kita nampak lagi fungsi yang tidak biasa.EncodeFungsi ini adalah fungsi API untuk platform FMZ, yang digunakan khusus untuk melakukan pengekodan pada platform FMZ. Fungsi ini menyokong pelbagai kaedah pengekodan dan menyokong pelbagai algoritma hash.

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

Penggunaan seperti yang diterangkan dalam dokumentasi ENSsha3.keccak256Algoritma memproses data.

PanggilannameHashFungsi seperti:Log(nameHash("vitalik.eth"))Boleh:ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835, perlu ditambah dengan awalan "0x".0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835Sebagai kontrak pintar ENSresolverParameter kaedah.

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

Mengesan dokumen ENS, alamat kontrak aplikasi kontrak pintar ENS ialah:0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e◦ Menggunakan kontrak pintarresolverSebelum pendekatan ini, kita perlu menyediakan kontrak yang sesuai.ABI

Pendaftaran ABI

Di sini, anda boleh bertanya, apa itu kontrak pintar?ABIAdakah?

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

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

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

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

Mengambil daripada ENS dalam ABIresolverSebahagian daripada kaedah ini juga boleh digunakan dengan ABI penuh, yang boleh digunakan dihttps://etherscan.io/Untuk mendapatkan maklumat mengenai kontrak, anda boleh menghubungi ABI atau mendapatkan ABI dengan cara lain (contohnya: dokumen projek yang berkaitan).

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 menghubungi di platform FMZ.exchange.IO("abi", address, abiContent)Perisian ini boleh digunakan untuk mendaftarkan ABI.addressParameter adalah alamat kontrak pintar.abiContentParameter adalah kontrak pintar yang sepadan 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 memanggil kontrak pintar

Kemudian anda boleh memanggil kontrak pintar ENS.resolverCara ini, cara ini kembali.ENS: Public ResolverAlamat kontrak.

img

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

PenggunaanENS: Public ResolverKontrakaddrCara mendapatkan alamat dompet dewa V.ENS: Public ResolverKontrak masih memerlukan pendaftaran ABI terlebih dahulu.https://etherscan.io/Diambil.

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 ResolverKontrakaddrkaedah, parameter masihensNode

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

Keluaran log:

img

vitalikAddress: 0xd8da6bf26964af9d7eed9e03e53415d37aa96045

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

Menghantar ETH

Dalam bab kursus sebelumnya, kita telah belajar bagaimana untuk mengkonfigurasi kunci peribadi, bagaimana kita tahu alamat dompet yang sesuai dengan kunci peribadi ini untuk objek pertukaran yang telah dikonfigurasi?exchange.IO("address")Fungsi ini mendapatkan alamat dompet yang sesuai dengan kunci peribadi yang dikonfigurasikan.

Oleh kerana penggunaan:GoerliDi sini, saya akan cuba untuk mengkaji persekitaran web, jadi saya menggunakan:https://goerli.infura.io/v3/*******Di sini, infura telah menetapkan alamat node yang berbeza untuk setiap pengguna berdaftar.*******Di samping itu, ia juga menyembunyikan kandungan tertentu.

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

img

Setelah anda tahu alamat dompet anda, anda boleh menggunakan kaedah RPC Ethereum.eth_getTransactionCountPengiraan transaksi untuk mendapatkan alamat dompet. Pengiraan ini sangat biasa digunakan di Ethereum, yang sebenarnya perlu diteruskan semasa operasi pemindahan.nonceParameter, dalam Ethereum, nonce digunakan untuk memastikan setiap transaksi adalah nombor yang unik. Ia adalah nombor yang meningkat dan akan meningkat secara automatik setiap kali menghantar transaksi baru. Oleh itu, apabila anda menghantar transaksi ke kontrak pintar, anda perlu memberikan nonce untuk memastikan transaksi adalah unik dan urutan yang betul.

https://goethereumbook.org/en/

img

Di sini, anda boleh melihat kumpulan Ethereum dalam bahasa Go.PendingNonceAtFungsi sebenarnya dipanggil.eth_getTransactionCountCara. Dalam kursus sebelumnya, kita juga belajar bagaimana untuk memanggil kaedah 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 menerangkan operasi pemindahan, kita hanya perlu memahami beberapa konsep bahawa pemindahan di Ethereum akan menggunakan sejumlah token ETH (sebagai kos gas) yang ditentukan oleh dua parameter:

  • gasPrice

    Walau bagaimanapun, harga gas pada rangkaian Ethereum sentiasa berubah-ubah mengikut permintaan pasaran dan apa yang pengguna bersedia membayar, jadi menulis harga gas tetap dalam kod kadang-kadang bukan pilihan yang ideal.eth_gasPriceKaedah ini boleh mendapatkan harga gas purata.

  • gasLimit

    Batas gas untuk satu pemindahan ETH standard adalah 21000 unit.

Saya faham.noncegasPricegasLimitKonsep-konsep ini boleh diuji dengan pemindahan. Fungsi pemindahan yang sangat mudah digunakan di FMZ sangat mudah.

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

Apabila digunakan sebagai penghantaran wang,exchange.IOPeruntukan yang diberikan oleh pihak ketiga adalah "send".toAddressParameter adalah alamat yang menerima ETH semasa pemindahan.toAmountJumlah ETH yang akan dipindahkan.

noncegasPricegasLimitParameter-parameter ini boleh digunakan pada FMZ dengan menggunakan nilai yang diambil secara automatik oleh sistem secara lalai.

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

Seterusnya, kami akan memindahkan sejumlah ETH ke alamat di Goerli untuk ujian:

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
}

Kerana unit penghantaran Ethereum adalahweiIa memerlukan fungsi khusus.toInnerAmountDiproses sebagaiweiNilai bagi satuan.

Dalamhttps://etherscan.io/Permintaan atas Hash Transaksi:0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e

img

Anda juga boleh menulis kod untuk menyiasat dan memindahkan hash.0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e, kegunaaneth_getTransactionReceiptCara untuk membuat pertanyaan.

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

Hasil carian:

{
	"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 bidang mempunyai penerangan 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 maklumat kontrakDalam bab ini, melalui satu contoh lengkap, kaedah memanggil kontrak ENS yang digunakan di Ethereum memperoleh alamat dompet dewa V.ReadTidak perlu menggunakan kaedah ini.gasDalam bab ini, kita akan memanggil beberapa kontrak pintar di Ethereum sebagai kontrak pintar.WriteCara dan BayarangasOperasi ini akan disahkan oleh setiap nodus di seluruh rangkaian dan juga pelombong dan mengubah status blockchain.

ERC20

Untuk kontrak ERC20 (kontrak token ERC20), FMZ meletakkan kontrak ERC20 sebagai ABI yang biasa digunakan secara langsung di dalam sistem, tanpa langkah pendaftaran ABI ini.

Untuk mendapatkan pemahaman yang lebih jelas mengenai ABI, lihat ABI kontrak ERC20 sebelum menggunakannya:

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

Penggunaan dalam bab iniGoerliPercubaan persekitaran web.

baki

Kemudian kita akan berlatih lagi bagaimana untuk memanggil kontrak.ReadCara membaca maklumat kontrak, memanggil kontrak ERC20balanceOfCara untuk mendapatkan baki tokenbalanceOfKaedah hanya mempunyai satu parameter, tetapi tidak dinamakan, dan dilihat oleh jenis sebagai alamat (iaitu alamat token yang ditanyakan). Oleh kerana data yang dikembalikan tidak diukur dalam satu token, data ketepatan token juga diperlukan untuk bertukar, dan ketepatan token boleh digunakan untuk kontrak ERC20.decimalsCara mendapatkan. Kami menggunakan Ethereum Test Net.goerliPeriksa, perhatikan bahawa alamat kontrak token mungkin berbeza di rantaian yang berlainan.

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 lanjut