[TOC]
Mở rộng web3 dựa trên Ethereum với FMZ
Ethereum là một nền tảng hợp đồng thông minh dựa trên công nghệ blockchain, nó cung cấp một cách phân quyền để viết và triển khai hợp đồng thông minh. Hợp đồng thông minh là một chương trình máy tính đặc biệt có thể tự động thực hiện trên blockchain và thực hiện tất cả các logic kinh doanh mà không cần phải tin tưởng bên thứ ba.
Những người phát minh ra nền tảng giao dịch định lượngFMZ.COMCác API dễ sử dụng cho phép các nhà phát triển tương tác dễ dàng hơn với blockchain Ethereum và hệ sinh thái của nó. Khả năng truy cập sàn giao dịch tập trung (DEX), thu thập dữ liệu trên chuỗi, gửi giao dịch, v.v.
Sử dụng ví dụ trong bài họcJavaScript
Viết ngôn ngữ, sử dụng môi trường thử nghiệmEthereum、Goerli thử mạngBạn cũng có thể xem tài liệu API của nền tảng FMZ để xem các giao diện API được sử dụng trong hướng dẫn và các mô tả, ví dụ về mã liên quan.
Trước khi học cách sử dụng nền tảng giao dịch định lượng FMZ, chúng ta cần làm quen với một vài khái niệm cơ bản:
Trong trang web chính thức của FMZhttps://www.fmz.comCác ứng dụng được viết bởi người dùng thực sự chạy trên máy chủ. Các ứng dụng này có thể được triển khai trên nhiều thiết bị khác nhau, chẳng hạn như máy chủ, máy tính, v.v. Khi người dùng viết một chương trình tốt trên trang web FMZ để tạo một trường hợp chạy, nền tảng FMZ sẽ liên lạc với người quản lý và khởi động một trường hợp chương trình trên người quản lý.
Nếu bạn muốn thực hiện một ứng dụng, bạn phải triển khai một trình quản lý, và việc triển khai trình quản lý rất đơn giản, có hướng dẫn triển khai trên nền tảng. Bạn cũng có thể tự động triển khai một máy chủ thuê máy chủ bằng "một trình quản lý triển khai một nút" được cung cấp trên FMZ.
triển khai người quản lý trên thiết bị cá nhân
Các chương trình quản trị có thể được triển khai trên các thiết bị như máy chủ, máy tính cá nhân, miễn là đảm bảo mạng hoạt động tốt, các bước chính của việc triển khai là:
1, đăng nhập hoặc mở thiết bị để triển khai chương trình quản trị, ví dụ:Đăng nhập vào máy chủHoặcMở máy tính vào hệ điều hành❖
2, tải xuống phiên bản ứng dụng quản trị tương ứng (tùy theo hệ điều hành thiết bị), tải xuống trang:https://www.fmz.com/m/add-node
3, tải xuống là một gói nén, cần giải nén.
4, để chạy chương trình quản trị viên này, một chương trình quản trị viên tên làrobot
Các tài liệu thực thi của FMZ. Thiết lập địa chỉ giao tiếp của người quản lý, địa chỉ này là duy nhất cho mỗi tài khoản FMZ.https://www.fmz.com/m/add-node
Các trang có thể xem địa chỉ của mình (tức là./robot -s node.fmz.com/xxxxx
Dòng địa chỉ này, ở đây.xxxxx
Nội dung của vị trí, mỗi tài khoản FMZ hiển thị khác nhau). Cuối cùng, bạn cũng cần nhập mật khẩu của tài khoản FMZ, cấu hình chúng và sau đó chạy chương trình quản trị viên.
Sử dụng các tính năng của nền tảng FMZ "Một nút triển khai quản trị viên"
Một số người đã đăng ký đăng ký đăng ký trên trang web của FMZ.https://www.fmz.com/m/add-node
FMZ Quantitative Trading Platform cung cấp một công cụ chỉnh sửa miễn phí, hỗ trợ các ứng dụng và dịch vụ khác nhau.JavaScript
,TypeScript
Trang này là:https://www.fmz.com/m/debug, bởi vì việc tạo trường hợp chạy là tính phí. Bạn có thể sử dụng công cụ này để thử nghiệm, học tập trong thời gian học tiểu học. Ngoài việc giới hạn thời gian chạy tối đa 3 phút, các khía cạnh khác không khác gì với việc tạo trường hợp chạy.
Sử dụngTypeScript
Trong ngôn ngữ, bạn cần phải viết ở dòng đầu tiên của mã.// @ts-check
để chuyển sangTypeScript
Mô hình, không chuyển đổi mặc định làJavaScript
Ngôn ngữ.
Trong FMZ, "thị trường" là một khái niệm chung, với sàn giao dịch CEX chỉ là một cấu hình tài khoản giao dịch cụ thể. Đối với web3, sàn giao dịch này chỉ là một thông tin cấu hình, bao gồm địa chỉ nút, cấu hình khóa riêng.
Trong khi đó, một số người khác đã đăng ký đăng ký trên nền tảng FMZ.https://www.fmz.com/m/add-platform
Các trang có thể cấu hình thông tin về sàn giao dịch, nơi sàn giao dịch là khái niệm chung.
Lựa chọnWeb3
Bạn có thể cài đặt địa chỉ RPC, cài đặt khóa cá nhân, bạn có thể nhấp vào bên dưới bên phải "Làm mã hóa thông tin nhạy cảm bằng khóa riêng độc lập" để xem các cơ chế bảo mật.
Các nút có thể được xây dựng bằng các nút tự xây dựng hoặc các nút được cung cấp bởi các máy chủ nút. Có rất nhiều các máy chủ nút, ví dụ:Infura; Sau khi đăng ký, bạn có thể xem địa chỉ của tài khoản của mình.; HomeNet, TestNet cũng có, dễ dàng hơn, cấu hình địa chỉ này trong biểu đồ trên.Rpc Address
Trong điều khiển này, thẻ có thể đặt tên cho chính nó để phân biệt các đối tượng giao dịch được cấu hình.
Hình ảnhhttps://mainnet.infura.io/v3/xxxxxxxxxxxxx
Đây là địa chỉ của các nút RPC trên mạng chủ sở hữu riêng của Infura.
在部署好托管者程序、配置好交易所对象的前提下,就可以使用FMZ.COM的「调试工具」进行测试了。调用以太坊RPC方法和以太坊交互,除了本章节列举介绍的几个RPC方法,其它RPC方法可以查询资料了解,例如https://www.quicknode.com/docs。
Chúng tôi liệt kê một vài ví dụ đơn giản, bắt đầu từ những điều cơ bản.
Trong FMZ, các cuộc gọi phương thức RPC cũng được gói gọn, những chức năng này được gói gọn trong các hàm API của FMZ.exchange.IO
Trong đó.exchange.IO("api", "eth", ...)
◎ Các tham số đầu tiên là truyền cố định"api"
Các tham số thứ hai là truyền cố định."eth"
Các tham số khác tùy thuộc vào phương pháp RPC được gọi cụ thể.
Chúng tôi sử dụng nền tảng FMZ để xuất thông tin.Log
Các hàm,Log
Chức năng có thể nhập nhiều tham số và xuất ra khu vực nhật ký trong trang "Debug Tools" hoặc "RealDisk" của nền tảng FMZ, trang "Debug Tools" sẽ là công cụ chính của chúng tôi để thử nghiệm.
Ethereumeth_getBalance
Phương pháp để truy vấn số dư ETH của một địa chỉ trên Ethereum, phương pháp này đòi hỏi phải truyền 2 tham số.
Chúng ta hãy tìm hiểu về người sáng lập Ethereum.V神
Địa chỉ của ví ETH được biết đến là:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
。
function main() {
let ethBalance = exchange.IO("api", "eth", "eth_getBalance", "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest")
Log("ethBalance:", ethBalance)
}
Đã triển khai trình quản lý (hình: linux/amd64...) và cấu hình các đối tượng sàn giao dịch (hình: Web3 test), kiểm tra mã trong công cụ gỡ lỗi:
Nhấp vào nút "Execute" và chạy đoạn mã này, kết quả sẽ xuất hiện:
EthBalance: 0x117296558f185bbc4c6
Log
Các hàm được in raethBalance
Giá trị của biến là:0x117296558f185bbc4c6
, là kiểu chuỗi.Số dư ETH với giá trị 16 chữ số,wei
Đơn vị1e18 wei
là 1ETH
Vì vậy, nó cũng cần phải được chuyển đổi để trở thành một số dư ETH thập phân có thể đọc được.
sẽethBalance
Chuyển đổi thành dữ liệu có thể đọc:
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)
}
Ở trênhttps://etherscan.io/
Tìm kiếm:
Tuy nhiên, điều này được lý giải bởi vấn đề chính xác của ngôn ngữ sẽ có sự sai lệch, vì vậy nền tảng FMZ đã tích hợp hai chức năng để xử lý dữ liệu:
Một số người khác đã bị ảnh hưởng.
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()))
}
Đơn vị: 5149.6244846875215
eth_chainId
vànet_version
Các hàm này đều trả về ID của blockchain mà các node RPC hiện tại đã truy cập, sự khác biệt là:net_version
Trả về ID số thập phân,eth_chainId
Trả về Id của hệ số 16.
Tên mạng tương ứng với chuỗi ID
1 - ethereum mainnet
2 - morden testnet (deprecated)
3 - ropsten testnet
4 - rinkeby testnet
5 - goerli testnet
11155111 - sepolia testnet
10 - optimism mainnet
69 - optimism kovan testnet
42 - kovan testnet
137 - matic/polygon mainnet
80001 - matic/polygon mumbai testnet
250 - fantom mainnet
100 - xdai mainnet
56 - bsc mainnet
Sử dụng mạng thử nghiệm Ethereum được cấu hình tốtgoerli
Kiểm tra nút:
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))
}
Gọi điệneth_gasPrice
Phương pháp, truy vấn chuỗi hiện tạigas 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))
}
Ở đây chúng ta viết một hàm để chuyển đổi một chuỗi 16 chữ số thành một số lượng có thể đọc được:toAmount
Một điều cần lưu ý là đơn vị của giá gas là:wei
Vì vậy, chúng ta có thể tạo ra các hình dángdecimals
Giá trị thông biến thực tương ứng là 0.
eth_blockNumbe
Để hỏi độ cao của khối.
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))
}
Các công cụ này được sử dụng trong:
https://etherscan.io/
Tìm kiếm:
Tìm kiếm thông tin về khối.
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])
}
}
Các thông tin sau đây có thể được thực hiện trong công cụ gỡ lỗi:
Có rất nhiều ứng dụng hợp đồng thông minh đang chạy trên Ethereum.ENS
Một trong số đó là.ENS
Dịch vụ tên miền Ethereum (Ethereum Name Service) là một dịch vụ phân tích tên miền phi tập trung dựa trên blockchain Ethereum.
Bạn có nhớ trong bài hướng dẫn, chúng tôi đã hỏi về ví dụ về số dư ví của người sáng lập Ethereum, V God?0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
│ Vậy làm sao chúng ta biết địa chỉ này?ENS
Hợp đồng thông minh, sử dụng một tên trực quanvitalik.eth
(Vitalik là tên của vị thần V) để hỏi.
Các nội dung sau đây được sử dụng trong môi trường Ethereum theo quy định củaENS
Tài liệu được biết là cần thiết để truy vấn tên miền EthereumHashing Names
Sử dụng mã sau đây.vitalik.eth
Tên đã được xử lý.
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))
}
}
Trong ví dụ mã trên, chúng ta thấy một hàm khác lạ.Encode
, là một hàm API của nền tảng FMZ, được sử dụng đặc biệt để mã hóa các hoạt động trên nền tảng FMZ, hỗ trợ nhiều cách mã hóa và hỗ trợ nhiều thuật toán hash.
Encode(algo, inputFormat, outputFormat, data, keyFormat, key string)
Sử dụng theo mô tả trong tài liệu ENSsha3.keccak256
Các thuật toán xử lý dữ liệu.
Gọi điệnnameHash
Các hàm, ví dụ:Log(nameHash("vitalik.eth"))
Bạn có thể:ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835
, cần thêm tiền tố "0x".0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835
Một hợp đồng thông minh của ENSresolver
Các tham số của phương pháp.
let ensNode = "0x" + nameHash("vitalik.eth") // 准备好调用resolver方法的参数ensNode
Tìm tài liệu của ENS để biết địa chỉ hợp đồng của ứng dụng hợp đồng thông minh ENS là:0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
❖ Những người đang gọi hợp đồng thông minhresolver
Trước khi tiếp cận, chúng ta cần chuẩn bị hợp đồng.ABI
。
Học đến đây không thể không hỏi, hợp đồng thông minh là gì?ABI
Có gì không?
ABI,即应用程序二进制接口(Application Binary Interface),是智能合约与外部世界进行通信的接口标准。
智能合约的 ABI 定义了合约的函数接口、参数类型、返回值等信息,以及调用合约的方式和参数传递方式等规范。
智能合约的 ABI 通常以 JSON 格式存储,包含以下信息:
合约的函数接口:函数名、参数列表、返回值等信息。
函数参数类型:如 uint256、bool、string 等。
函数的输入参数和输出参数的编码方式:智能合约使用一种称为 Solidity ABI 的编码方式来编码函数的输入参数和输出参数,
以便与以太坊网络进行交互。
在以太坊网络中,使用智能合约的 ABI 来调用合约的函数。当需要调用合约函数时,需要提供函数名和函数参数,以及将函数参数按照 ABI 编码方式编码后的字节码。
以太坊节点会将这些信息打包成一笔交易,并将交易发送到以太坊网络中执行。
智能合约的 ABI 在 Solidity 语言中可以通过 interface 关键字来定义。以太坊开发工具如 Remix IDE、Truffle 等也提供了 ABI 编辑和生成工具,
使得开发者可以方便地创建和使用智能合约的 ABI。
Và chúng ta có thể lấy nó ra khỏi ENS.resolver
Một phần của phương pháp, cũng có thể sử dụng ABI đầy đủ, có thể được sử dụng trênhttps://etherscan.io/
Bạn có thể truy cập vào ABI của hợp đồng, hoặc có được ABI bằng các cách khác (ví dụ: tài liệu dự án liên quan).
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"}]`
Một lần nữa, chúng ta sẽ học một cách gọi mới trên nền tảng FMZ.exchange.IO("abi", address, abiContent)
Một số người đã sử dụng phương pháp này để đăng ký ABI.address
Các tham số là địa chỉ của hợp đồng thông minh.abiContent
Các tham số là các hợp đồng thông minh tương ứng 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智能合约的地址
Sau đó, bạn có thể gọi ENS Smart Contract.resolver
Phương pháp này, phương pháp này quay lạiENS: Public Resolver
Địa chỉ của hợp đồng.
let resolverAddress = exchange.IO("api", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", "resolver", ensNode)
Sử dụngENS: Public Resolver
Thỏa thuậnaddr
Cách lấy địa chỉ ví của V.ENS: Public Resolver
Các hợp đồng vẫn cần phải đăng ký ABI trước. Thông tin ABI của hợp đồng thông minh vẫn có thể được truy cập từ các trang web khác nhau.https://etherscan.io/
Nhận được.
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)
Gọi cuối cùngENS: Public Resolver
Thỏa thuậnaddr
Phương pháp, các tham số vẫn làensNode
。
let vitalikAddress = exchange.IO("api", resolverAddress, "addr", ensNode)
Log("vitalikAddress:", vitalikAddress)
Lưu ý:
vitalikAddress: 0xd8da6bf26964af9d7eed9e03e53415d37aa96045
function nameHash(name) {
if (name == "") {
return "0000000000000000000000000000000000000000000000000000000000000000"
} else {
let arr = name.split(".")
let label = arr[0]
arr.shift()
let remainder = arr.join(".")
return Encode("sha3.keccak256", "hex", "hex", nameHash(remainder) + Encode("sha3.keccak256", "raw", "hex", label))
}
}
function main() {
// 计算名称
let ensNode = "0x" + nameHash("vitalik.eth")
// 注册ENS合约
let abiENS_resolver = `[{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"resolver","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]`
exchange.IO("abi", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", abiENS_resolver)
let resolverAddress = exchange.IO("api", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", "resolver", ensNode)
// 注册ENS Public Resolver合约
let abiENSPublicResolver = `[{"inputs":[{"internalType":"contract ENS","name":"_ens","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"contentType","type":"uint256"}],"name":"ABIChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"a","type":"address"}],"name":"AddrChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"coinType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newAddress","type":"bytes"}],"name":"AddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bool","name":"isAuthorised","type":"bool"}],"name":"AuthorisationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"hash","type":"bytes"}],"name":"ContenthashChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"resource","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"record","type":"bytes"}],"name":"DNSRecordChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"resource","type":"uint16"}],"name":"DNSRecordDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"DNSZoneCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"bytes4","name":"interfaceID","type":"bytes4"},{"indexed":false,"internalType":"address","name":"implementer","type":"address"}],"name":"InterfaceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"NameChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"x","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"y","type":"bytes32"}],"name":"PubkeyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"string","name":"indexedKey","type":"string"},{"indexed":false,"internalType":"string","name":"key","type":"string"}],"name":"TextChanged","type":"event"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"contentTypes","type":"uint256"}],"name":"ABI","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"addr","outputs":[{"internalType":"address payable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"coinType","type":"uint256"}],"name":"addr","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"authorisations","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"clearDNSZone","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"contenthash","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"name","type":"bytes32"},{"internalType":"uint16","name":"resource","type":"uint16"}],"name":"dnsRecord","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"name","type":"bytes32"}],"name":"hasDNSRecords","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"interfaceImplementer","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"pubkey","outputs":[{"internalType":"bytes32","name":"x","type":"bytes32"},{"internalType":"bytes32","name":"y","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"contentType","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setABI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"coinType","type":"uint256"},{"internalType":"bytes","name":"a","type":"bytes"}],"name":"setAddr","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"a","type":"address"}],"name":"setAddr","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"isAuthorised","type":"bool"}],"name":"setAuthorisation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"hash","type":"bytes"}],"name":"setContenthash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setDNSRecords","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes4","name":"interfaceID","type":"bytes4"},{"internalType":"address","name":"implementer","type":"address"}],"name":"setInterface","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"name","type":"string"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"x","type":"bytes32"},{"internalType":"bytes32","name":"y","type":"bytes32"}],"name":"setPubkey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"key","type":"string"},{"internalType":"string","name":"value","type":"string"}],"name":"setText","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"key","type":"string"}],"name":"text","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}]`
exchange.IO("abi", resolverAddress, abiENSPublicResolver)
let vitalikAddress = exchange.IO("api", resolverAddress, "addr", ensNode)
Log("vitalikAddress:", vitalikAddress)
}
Trong các bài học trước đây, chúng ta đã học cách cấu hình khóa riêng, và làm thế nào để chúng ta biết khóa riêng này tương ứng với địa chỉ ví đối với các đối tượng giao dịch đã được cấu hình?exchange.IO("address")
Chức năng lấy khóa cá nhân được cấu hình cho địa chỉ ví tương ứng.
Do các nội dung sau đây được sử dụng trong chương này:Goerli
Tôi đã thử nghiệm môi trường web, vì vậy các nút mà tôi sử dụng là:https://goerli.infura.io/v3/*******
Các địa chỉ của các nút được infura phân bổ cho mỗi người đăng ký khác nhau, ở đây*******
Những người khác cũng có thể sử dụng các phương tiện này để thu thập thông tin.
function main() {
let walletAddress = exchange.IO("address")
Log("测试网 goerli 钱包地址:", walletAddress)
}
Khi bạn biết địa chỉ ví của mình, bạn có thể sử dụng phương pháp RPC của Ethereum.eth_getTransactionCount
Số lượng giao dịch truy vấn địa chỉ ví. Trong Ethereum, số lượng này rất phổ biến, thực sự là những gì cần được truyền khi chuyển tiền.nonce
Trong Ethereum, nonce được sử dụng để đảm bảo rằng mỗi giao dịch là một số duy nhất. Nó là một số tăng dần và sẽ tự động tăng lên mỗi khi bạn gửi một giao dịch mới. Do đó, khi bạn gửi giao dịch đến hợp đồng thông minh, bạn cần phải cung cấp một nonce để đảm bảo giao dịch là duy nhất và thứ tự là đúng.
Đây là phần mềm Ethereum của ngôn ngữ GoPendingNonceAt
Các hàm thực sự được gọi.eth_getTransactionCount
Các phương pháp. Trong bài học trước, chúng ta đã học cách gọi phương pháp RPC, và chúng ta sẽ sử dụng nó một lần nữa.exchange.IO("api", "eth", ...)
Chức năng.
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))
}
Trước khi giải thích các hoạt động chuyển tiền, chúng ta chỉ cần hiểu một số khái niệm về việc chuyển tiền trên Ethereum sẽ tiêu thụ một số token ETH (như chi phí khí đốt). Chi phí khí đốt được xác định bởi hai tham số cụ thể:
gas Giá
Tuy nhiên, chi phí nhiên liệu trên mạng Ethereum luôn thay đổi theo nhu cầu của thị trường và chi phí người dùng sẵn sàng trả, do đó, viết giá nhiên liệu cố định trong mã đôi khi không phải là lựa chọn lý tưởng.eth_gasPrice
Phương pháp này có thể thu được giá trung bình của khí đốt.
gasLimit
Giới hạn khí đốt cho một giao dịch Ethereum tiêu chuẩn là 21000 đơn vị.
Được rồi.nonce
,gasPrice
,gasLimit
Các khái niệm này có thể được thử nghiệm chuyển khoản.
exchange.IO("api", "eth", "send", toAddress, toAmount)
Khi sử dụng như một khoản chuyển tiền,exchange.IO
Các đối số thứ ba được viết là "send".toAddress
Các tham số là địa chỉ nhận ETH khi chuyển tiền.toAmount
Số lượng ETH được chuyển.
nonce
,gasPrice
,gasLimit
Các tham số này có thể được sử dụng trên FMZ với các giá trị mà hệ thống mặc định tự động lấy. Bạn cũng có thể chỉ định:
exchange.IO("api", "eth", "send", toAddress, toAmount, {gasPrice: 5000000000, gasLimit: 21000, nonce: 100})
Tiếp theo, chúng tôi chuyển một số ETH vào một địa chỉ trên goerli trên mạng thử nghiệm:
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
}
Vì đơn vị của số lượng chuyển tiền Ethereum làwei
Bạn cần phải sử dụng một chức năng tùy chỉnh.toInnerAmount
xử lý nhưwei
Số lượng của đơn vị.
Tronghttps://etherscan.io/
Tìm kiếm Transaction Hash:0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e
。
Bạn cũng có thể viết mã truy vấn chuyển đổi hash0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e
Sử dụngeth_getTransactionReceipt
Cách tìm kiếm.
function main() {
let transHash = "0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e"
let info = exchange.IO("api", "eth", "eth_getTransactionReceipt", transHash)
return info
}
Kết quả tìm kiếm:
{
"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": []
}
Mỗi trường có mô tả tương ứng:
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 - 值的类型
Chúng ta đang ởĐọc thông tin hợp đồngTrong chương này, qua một ví dụ hoàn chỉnh, các phương pháp gọi các hợp đồng ENS được triển khai trên Ethereum đã lấy địa chỉ ví của V. Những phương pháp này thuộcRead
Các phương pháp này không cần thiết.gas
Trong chương này, chúng ta sẽ gọi một số hợp đồng thông minh trên Ethereum là các hợp đồng thông minh.Write
Phương pháp và thanh toángas
Các hoạt động này sẽ được xác minh bởi mỗi nút trên toàn mạng và các thợ mỏ và thay đổi trạng thái của blockchain.
Đối với các hợp đồng ERC20 (các hợp đồng token ERC20), nền tảng FMZ liệt kê ABI của hợp đồng ERC20 là ABI thông thường được tích hợp trực tiếp trong hệ thống, bỏ qua bước đăng ký ABI này. Đối với ABI, chúng tôi cũng đã tìm hiểu trong bài học trước đây, chúng tôi đã đăng ký ABI của hợp đồng ENS trước khi gọi phương pháp hợp đồng ENS.
Để hiểu rõ hơn về ABI, trước khi sử dụng, hãy xem ABI của hợp đồng ERC20 dưới đây:
[{"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"}]
Sử dụng nội dung sau đây:Goerli
Các nhà nghiên cứu cho biết:
Sau đó, chúng ta tập lại cách gọi hợp đồng.Read
Cách đọc thông tin hợp đồng, gọi hợp đồng ERC20balanceOf
Cách tìm kiếm số dư tokenbalanceOf
Phương pháp chỉ có một tham số, nhưng không được đặt tên, được nhìn thấy bằng kiểu là một địa chỉ (tức là địa chỉ của mã thông báo được truy vấn). Vì dữ liệu được trả về không được tính bằng một mã thông báo, nên cũng cần dữ liệu chính xác của mã thông báo để tính toán, độ chính xác của mã thông báo có thể được tính bằng hợp đồng ERC20.decimals
Phương pháp lấy. Chúng tôi sử dụng mạng thử nghiệm Ethereum.goerli
Để kiểm tra, hãy lưu ý rằng địa chỉ hợp đồng mã thông báo trên các chuỗi khác nhau cũng có thể khác nhau.
function toAmount(s, decimals) {
return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}
function main() {
let walletAddress = exchange.IO("address")
// goerli WETH address
let wethAddress = "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6"
// goerli LINK address
let linkAddress = "0x326C977E6efc84E512bB9C30f76E30c160eD06FB"
// 由于是ERC20合约,FMZ已经内置ABI注册,所以这里不用注册ERC20 ABI
let wethDecimals = exchange.IO("api", wethAddress, "decimals")
let linkDecimals = exchange.IO("api", linkAddress, "decimals")
let wethBalance = exchange.IO("api", wethAddress, "balanceOf", walletAddress)
let linkBalance = exchange.IO("api", linkAddres