В процессе загрузки ресурсов... загрузка...

Легкое введение в разработку web3 на базе Ethereum с FMZ

Автор:Изобретатели количественного измерения - мечты, Создано: 2023-03-28 13:32:48, Обновлено: 2024-11-11 22:28:24

[TOC]

使用FMZ轻松入门基于以太坊的web3开发

Урок EtherEaseWithFMZ

Легкое введение в разработку web3 на базе Ethereum с FMZ

Ethereum - это платформа умных контрактов, основанная на технологии блокчейн, которая предоставляет децентрализованный способ написания и развертывания умных контрактов; умные контракты - это специальные компьютерные программы, которые могут автоматически выполняться на блокчейне и реализовывать различные бизнес-логики без необходимости доверять третьим лицам.

FMZ.COM предоставляет удобный для использования API, позволяющий разработчикам более легко взаимодействовать с блокчейном Ethereum и его экосистемой.

Использование примеров в этом урокеJavaScriptНаписание языков, использование тестовых средЭфириумГёрли тестирует сетьВ API-документации FMZ-платформы также можно посмотреть API-интерфейсы, используемые в учебниках, а также их описания и примеры кода.


FMZ использует вход

Перед тем, как научиться использовать квантовую торговую платформу FMZ, нам необходимо ознакомиться с несколькими основными концепциями:

1 FMZ - архитектура квантовой платформы

На официальном сайте FMZhttps://www.fmz.com)注册、登录后就可以使用平台的各种功能了。FMZ网站是整个系统的管理端,用户编写的程序实际上是运行在托管者上。托管者这个软件程序可以部署在各种设备上,例如服务器、电脑等。当用户在FMZ网站上编写好程序创建运行实例时,FMZ平台就会和托管者通信,在托管者上启动一个程序实例。

使用FMZ轻松入门基于以太坊的web3开发

2. Хранители

Если вы хотите запустить экземпляр программы, вам нужно будет развернуть хостера, развертывание хостера также очень простое, есть инструкции по развертыванию на платформе.

  • Развернуть хост на персональных устройствах

Программа может быть развернута на серверах, персональных компьютерах и других устройствах, при условии, что сеть функционирует. Основные шаги в развертывании:

1. Зарегистрироваться или открыть устройство, на котором вы хотите развернуть программу администратора, например:Вход на серверИлиОткрыть компьютер и войти в операционную системуЯ не знаю. 2. Загрузить соответствующую версию хостпрограммы (в зависимости от операционной системы устройства), загрузить страницу:https://www.fmz.com/m/add-node 使用FMZ轻松入门基于以太坊的web3开发3, загружается пакет сжатия, который требует разжатия. 4, чтобы запустить этот хост, хост должен быть программой под названиемrobotИспользуемый файл. Конфигурируйте адрес обмена сообщениями администратора, который является уникальным для каждой учетной записи FMZ, после входа в FMZhttps://www.fmz.com/m/add-nodeНа странице можно посмотреть свой адрес (т.е../robot -s node.fmz.com/xxxxxЭто адресная строка, здесь.xxxxxСодержимое местоположения, показываемое каждой учетной записью FMZ, отличается). Наконец, необходимо ввести пароль учетной записи FMZ, который необходимо настроить, после чего можно запустить администраторную программу.

  • Использование FMZ-платформы с функцией "Одна кнопка развертывания хостера"

Добавить страницу хозяина на платформе FMZ, адрес:https://www.fmz.com/m/add-node

使用FMZ轻松入门基于以太坊的web3开发

3. Инструменты для декомпиляции

FMZ Quantitative Trading Platform предоставляет бесплатный инструмент для декомпенсации, поддерживающий:JavaScriptTypeScriptНа странице написано:https://www.fmz.com/m/debug, поскольку создание экземпляров платного действия. В начальном классе можно использовать этот инструмент для тестирования, обучения. Кроме ограничения времени выполнения на 3 минуты, другие аспекты не отличаются от создания экземпляров.

ИспользованиеTypeScriptВ языке, который требует написания в первой строке кода// @ts-checkДля переключения наTypeScriptПо умолчанию, не переключаетсяJavaScriptЯзык.

4., биржа

В FMZ "биржа" является общей концепцией, которая для биржи CEX означает конкретную конфигурацию учетной записи биржи. Для web3 эта биржа означает конфигурационную информацию, содержащую адрес узла, конфигурацию частного ключа.

На сайте FMZ можно посмотреть видео, сделанное в режиме онлайн.https://www.fmz.com/m/add-platformНа странице, на которой можно настроить информацию об биржах, где биржа является общей концепцией.

使用FMZ轻松入门基于以太坊的web3开发

ВыборWeb3Для того, чтобы установить адрес RPC-нота или установить частный ключ, нажмите в нижнем правом углу "Сохранение конфиденциальной информации с использованием независимого частного ключа" для просмотра механизма безопасности.

Нод может быть создан самостоятельно или предоставлен сервером. Нод-серверов много, например:ИнфураПосле регистрации можно посмотреть адрес своего аккаунта. Главная сеть, тестовая сеть доступны, более удобно, чтобы настроить этот адрес в графике выше.Rpc AddressВ контроле.tag можно дать себе название, чтобы отличить объекты биржи, на которых они настраиваются.

使用FMZ轻松入门基于以太坊的web3开发

На рисункеhttps://mainnet.infura.io/v3/xxxxxxxxxxxxxЭто адрес RPC-нота частной сети ETH Infura.


Взаимодействие с FMZ и Ethereum

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

Мы перечислим несколько простых примеров, чтобы начать с основ.

使用FMZ轻松入门基于以太坊的web3开发

В FMZ также были завернуты вызовы методов RPC, которые были завернуты в функции API FMZ.exchange.IOВ среднем.exchange.IO("api", "eth", ...)Первый параметр - фиксированный поток."api"Второй параметр - фиксированный поток."eth"Другие параметры определяются в зависимости от конкретного метода RPC.

Мы использовали платформу FMZ для вывода информации.LogФункцияLogФункция может вводить несколько параметров, а затем выводить их в регионе журналов на странице FMZ "Дебютные инструменты" или "Физический диск", где страница "Дебютные инструменты" будет основным инструментом для нашего тестирования.

eth_getBalance

Эфириумeth_getBalanceМетод, используемый для запроса баланса ETH на адрес на Ethereum, требует передачи 2 параметров.

  • Например, в 2010 году в Нью-Йорке вспыхнул пожар.
  • На этикетках, как правило, используется "latest".

Давайте спросим у основателя Ethereum.V神На данный момент существует только один ETH-кошелек.0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045

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

Уже развернуты хостеры (изображение: linux/amd64...) и настроены объекты биржи (изображение: Web3 test), в дебаторе тестируется код:

使用FMZ轻松入门基于以太坊的web3开发

Нажмите кнопку "Выполнить", чтобы запустить этот код, и вы увидите результат:

EthБалканс: 0x117296558f185bbc4c6


将```ethBalance```转换为可读的数据:

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

使用FMZ轻松入门基于以太坊的web3开发

Вверхhttps://etherscan.io/Запрос:

使用FMZ轻松入门基于以太坊的web3开发

Однако это объясняется тем, что в вопросах точности языка могут быть отклонения, поэтому платформа FMZ встроена в две функции для обработки данных:

  • Big:Int преобразует шестнадцатизначную строку в объект BigInt.
  • BigDecimal: преобразует объекты с числовым типом в обрабатываемые объекты BigDecimal.

Новый код:

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

ВиталикЭтБалкан: 5149.6244846875215

eth_chainId


链Id对应的网络名称

```desc
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

使用FMZ轻松入门基于以太坊的web3开发

Использование хорошо настроенной тестовой сети EthereumgoerliНоты тестирования:

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

使用FMZ轻松入门基于以太坊的web3开发

eth_gasPrice

Звонокeth_gasPriceМетод, запрос на текущую цепочкуgas 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))
}

Здесь мы записываем функцию, которая преобразует шестнадцатизначную строку в читаемую числовую величину:toAmountТакже стоит отметить, что единицей цены на газ являетсяweiИ поэтому мы используем фигуруdecimalsСоответствующее значение реального параметра передачи может быть равно нулю.

eth_blockNumbe


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

Дебютные инструменты:

使用FMZ轻松入门基于以太坊的web3开发


![使用FMZ轻松入门基于以太坊的web3开发](/upload/asset/16a432a58ede048f98b6.png) 

### eth_getBlockByNumber

查询区块信息。

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

В инструменте "Дебют" вы можете получить следующую информацию:

使用FMZ轻松入门基于以太坊的web3开发


Читать информацию о контракте

На эфире работает множество приложений для умных контрактов.ENSОн был одним из них.ENSEthereum Name Service - это децентрализованная служба анализа доменных имен, основанная на блокчейне Ethereum. Помните, что в нашем уроке мы спрашивали примеры с балансом кошелька основателя Ethereum, Бога V?0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045Но как мы узнаем этот адрес?ENSУмные контракты, использующие интуитивно понятные названияvitalik.ethНапример, в одном из интервью, который я читал в своем блоге, я написал, что я хочу узнать больше о жизни человека.

В этой главе мы рассмотрим следующее:ENSДокументы, которые требуются для запроса доменного имени EthereumHashing NamesИспользуйте следующий кодvitalik.ethНазвание обрабатывается.

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

В этом примере мы увидели еще одну необычную функцию.EncodeФункция, API-функция для платформы FMZ, предназначена для кодирования операций на платформе FMZ. Функция поддерживает множество методов кодирования и поддерживает множество хэширующих алгоритмов.

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

Использование в соответствии с описанием в документации ENSsha3.keccak256Алгоритмы обрабатывают данные.

ЗвонокnameHashФункции, например:Log(nameHash("vitalik.eth"))В этом случае:ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835, необходимо добавить префикс 0x.0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835В качестве интеллектуального контракта ENSresolverПараметры метода.

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

В документе ENS указано, что адрес контракта на приложение ENS Smart Contract:0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e‒ В связи с этим, я не могу сказать, что я не знаю, что делать.resolverМы должны подготовить контракт, прежде чем приступить к работе.ABI

Регистрация ABI

Именно поэтому мы пришли сюда, чтобы узнать, что такое умные контракты.ABIЧто это?

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

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

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

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

Вытащить ABI из ENSresolverЧасть методов, также можно использовать с полным ABI, можно использовать вhttps://etherscan.io/Вы можете запросить ABI по контракту или получить ABI другими способами (например, документация по проекту).

使用FMZ轻松入门基于以太坊的web3开发

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

В этой статье мы узнаем о новом способе вызова на платформе FMZ.exchange.IO("abi", address, abiContent)В этом случае, если вы хотите зарегистрироваться в ABI, используйте этот метод.addressПараметры - это адреса смарт-контрактов.abiContentПараметры - это соответствующие умные контракты ABI (строки).

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智能合约的地址

Как вызвать умные контракты

В следующий раз мы сможем настроить систему, которая будет называться ENS Smart Contract.resolverСделано. Сделано.ENS: Public ResolverАдрес контракта.

使用FMZ轻松入门基于以太坊的web3开发

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

ИспользованиеENS: Public ResolverКонтрактaddrСпособы получения адреса кошелька бога V.ENS: Public ResolverКонтракт по-прежнему требует регистрации ABI.https://etherscan.io/Доступ к материалам.

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)

使用FMZ轻松入门基于以太坊的web3开发

Последний звонокENS: Public ResolverКонтрактaddrМетод, параметры остаютсяensNode

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

Вывод функции Log:

使用FMZ轻松入门基于以太坊的web3开发

vitalikAddress: 0xd8da6bf26964af9d7eed9e03e53415d37aa96045

Полный код вызова 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)
}

Отправка ETH

В предыдущих главах мы уже говорили о том, как настроить частный ключ, и как мы узнаем, что этот частный ключ соответствует адресу кошелька для конфигурированного объекта биржи?exchange.IO("address")Функция получает конфигурированный частный ключ, соответствующий адресу кошелька.

В связи с использованиемGoerliЯ использую следующие узлы для тестирования веб-среды:https://goerli.infura.io/v3/*******Инфура распределяет различные адреса узлов для каждого зарегистрированного пользователя.*******В частности, в Twitter появилась статья, в которой говорится, что в ней скрыто определенное содержание.

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

使用FMZ轻松入门基于以太坊的web3开发

После того, как вы узнаете свой адрес кошелька, вы можете использовать метод RPC на Эфириуме.eth_getTransactionCountСчет транзакций для запроса адреса кошелька. В Эфириуме этот счет очень часто используется, на самом деле, это то, что нужно передать при операции по переводу.nonceПараметры, в Ethereum nonce используется для обеспечения того, чтобы каждая сделка была уникальной цифрой. Это увеличивающееся число, которое автоматически увеличивается при каждом отправлении новой сделки. Поэтому, когда вы отправляете сделки в умные контракты, необходимо предоставить nonce, чтобы убедиться, что сделка уникальна и в правильном порядке.

https://goethereumbook.org/en/

使用FMZ轻松入门基于以太坊的web3开发

Здесь вы можете увидеть, что происходит в репозитории Ethereum на языке GoPendingNonceAtФункция, на самом деле, называетсяeth_getTransactionCountМетод. В предыдущих уроках мы также изучали, как использовать метод RPC, и мы используем его снова.exchange.IO("api", "eth", ...)Функция.

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

Перед тем, как рассказать о том, как происходит транзакция, мы просто познакомимся с некоторыми понятиями, которые потребляют определенные токены ETH при транзакции на Ethereum (как расходы на газ).

  • Газовый

Тем не менее, стоимость газа в сети Ethereum всегда колеблется в зависимости от потребностей рынка и того, что пользователи готовы заплатить, поэтому фиксированная стоимость газа, записанная в коде, иногда не является идеальным вариантом.eth_gasPriceВ этом случае, если вы хотите получить среднюю цену на газ, используйте один из следующих методов:

  • Газовой лимит

Газовый лимит на стандартную транзакцию эфиримов составляет 21000 единиц.

Понимаю.noncegasPricegasLimitЭти концепции можно протестировать. В FMZ упакованы очень простые и удобные функции перевода.

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

Поскольку они используются в качестве перевода денег, они могут быть использованы в качестве платежных средств.exchange.IOТретий параметр фиксируется как send.toAddressПараметры - это адрес, на котором получается ETH при переводе.toAmountКоличество ETH для перевода.


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

Далее мы переводим определенную сумму ETH в адрес на тестовом сайте goerli:

function toInnerAmount(s, decimals) {
    return (BigDecimal(s)*BigDecimal(Math.pow(10, decimals))).toFixed(0)
}

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

    let ret = exchange.IO("api", "eth", "send", "0x4D75a08E870674E68cAE611f329A27f446A66813", toInnerAmount(0.01, 18))
    return ret    // 返回Transaction Hash : 0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e
}

Потому что единицей количества транзакций в Эфириуме являетсяweiДля этого нужно использовать специальную функцию.toInnerAmountОбработкаweiЧисло в единице.

Вhttps://etherscan.io/Например:0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e

使用FMZ轻松入门基于以太坊的web3开发

Вы также можете написать код для запроса, передачи хештегов.0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734eИспользованиеeth_getTransactionReceiptКак сделать запрос?

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

Результаты поиска:

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

Описание каждого поля:

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

Смарт-контракты на Ethereum

Мы находимсяЧитать информацию о контрактеВ этой главе приведен полный пример того, как методы вызова ENS-контрактов, развернутых на Эфириуме, получают адрес кошелька Бога V. Эти методы относятся кReadВ этом случае вы не должны использовать эти методы.gasВ этой главе мы будем называть некоторые из этих умных контрактов на Эфириуме.WriteСпособы и оплатаgasЭти операции будут проверены каждым нотом по всей сети, а также майнером, и изменят состояние блокчейна.

ERC20

Для ERC20 контрактов (ERC20 token contracts) платформа FMZ включает ABI ERC20 контрактов как обычный ABI прямо в систему, без регистрации ABI.

Для более полного понимания ABI, перед тем как использовать его, вы можете посмотреть следующий ABI для ERC20 контракта:

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

Использование:GoerliПроверка сетевой среды.

баланс

И затем мы повторяем еще раз, как вызвать контракт.ReadМетод чтения контрактной информации и вызова контракта ERC20balanceOfКак узнать баланс токенов?balanceOfМетод имеет только один параметр, но не имеет названия, который можно увидеть по типу как адрес (т. е. адрес запрошенного токона). Так как возвращенные данные не являются единицами в виде токенов, для их расчета также требуются данные о точности токенов, то точность токенов может быть определена по контракту ERC20.decimalsМетод получения. Мы используем тестовую сеть EthereumgoerliПроведите тестирование и обратите внимание, что в разных цепочках могут быть разные адреса контрактов на токены.

` javascript функция toAmount ((s, десятичные знаки) { возвращение числа (BigDecimal) (BigInt) (s) / (BigDecimal) (Math.pow), десятичных знаков (toString)) Я не знаю.

функция 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

Больше информации