[TOC] ¿Qué quieres decir?
Introducción fácil con FMZ al desarrollo web3 basado en Ethereum
Ethereum es una plataforma de contratos inteligentes basada en la tecnología blockchain que ofrece una forma descentralizada de escribir y implementar contratos inteligentes. Los contratos inteligentes son programas informáticos especiales que pueden ejecutarse automáticamente en la cadena de bloques y pueden implementar una variedad de lógicas de negocio sin la necesidad de confiar en terceros.
El inventor de la plataforma de intercambio cuantitativoFMZ.COMLa plataforma de intercambio digital (DEX) ofrece una API fácil de usar que permite a los desarrolladores interactuar con la cadena de bloques Ethereum y su ecosistema con mayor facilidad.
Los ejemplos de este tutorialJavaScript
Escribir lenguajes y usarlos en entornos de pruebaLa red de Ethereum、Goerli prueba la redTambién puede consultar la documentación API de la plataforma FMZ para ver las interfaces API utilizadas en el tutorial, así como sus descripciones y ejemplos de código.
Antes de aprender a usar la plataforma de comercio cuantitativo FMZ, necesitamos familiarizarnos con algunos conceptos básicos:
En la página oficial de la plataforma de cambio de FMZhttps://www.fmz.comEl sitio web de FMZ es el terminal administrativo de todo el sistema, y los programas escritos por el usuario se ejecutan en el host. El programa del host se puede implementar en varios dispositivos, como servidores, computadoras, etc. Cuando el usuario escribe un buen programa en el sitio web de FMZ para crear una instancia de ejecución, la plataforma de FMZ se comunica con el host para iniciar una instancia de programa en el host.
Si se quiere ejecutar una instancia de programa, se debe implementar un administrador, que también es muy simple de implementar, con tutoriales de implementación en la plataforma. También se puede implementar automáticamente con el "administrador de implementación de un solo botón" que se ofrece en FMZ en lugar de un servidor de alquiler en FMZ.
Implementación de administradores en dispositivos personales
Los programas administradores pueden ser implementados en servidores, ordenadores personales, etc., siempre y cuando se asegure que la red funcione correctamente. Los principales pasos para implementar son:
1. iniciar sesión o abrir el dispositivo para implementar el programa administrador, por ejemplo:Ingresar al servidor¿Qué es esto?Abre el ordenador y entra en el sistema operativo¿Qué es esto?
2. Descargar la versión correspondiente del programa administrador (dependiendo del sistema operativo del dispositivo), descargar página:https://www.fmz.com/m/add-node
3, el descarga es un paquete de compresión que necesita descomprimir.
4. Para ejecutar este administrador, el administrador es un programa llamadorobot
La dirección de comunicación de un administrador de configuración, que es única para cada cuenta FMZ, se puede utilizar para iniciar sesión en FMZ.https://www.fmz.com/m/add-node
La página puede ver su dirección (es decir,./robot -s node.fmz.com/xxxxx
Esta serie de direcciones, aquí.xxxxx
El contenido de la ubicación, cada cuenta de FMZ muestra diferente) ; por último, también es necesario introducir el código de la cuenta de FMZ, para configurarlos y luego ejecutar el programa de administrador.
Utilizando la función de "Un solo botón para implementar administradores" de la plataforma FMZ
En la plataforma FMZ se ha añadido una página de administradores, con la dirección:https://www.fmz.com/m/add-node
La plataforma de comercio cuantitativo FMZ ofrece una herramienta de depuración gratuita, que es compatible con el uso de la plataforma de intercambio.JavaScript
,TypeScript
La página es:https://www.fmz.com/m/debug, ya que la creación de una instancia de ejecución es de pago. Durante la escuela primaria, se puede usar esta herramienta de depuración para probar, aprender. La herramienta de depuración no difiere en otros aspectos de la creación de una instancia de ejecución, excepto la limitación de tiempo de ejecución de hasta 3 minutos.
UsoTypeScript
En el lenguaje, se requiere escribir en la primera línea del código.// @ts-check
Se utiliza para cambiarTypeScript
El patrón, no cambiar por defecto esJavaScript
El idioma también.
En FMZ, "intercambio" es un concepto genérico que para el intercambio CEX se refiere a una configuración de cuenta de intercambio específica. Para web3, este intercambio se refiere a una información de configuración que contiene la dirección del nodo, la configuración de la clave privada.
En la plataforma FMZ, el usuario puede acceder a la información en la siguiente forma:https://www.fmz.com/m/add-platform
En la página, se puede configurar la información de los intercambios, donde los intercambios son conceptos generales.
SelecciónWeb3
Para configurar la dirección de los nodos RPC y configurar la clave privada, puede hacer clic en la parte inferior derecha "Encriptar información sensible con una clave privada independiente" para ver el mecanismo de seguridad.
Los nodos pueden ser construidos por ellos mismos o por un servidor de nodos.InfuraDespués de registrarse, puede ver la dirección del nodo de su cuenta. La red principal, la red de prueba también están disponibles, es más conveniente configurar esta dirección en el gráfico anterior.Rpc Address
En el control de la etiqueta, la etiqueta puede darse un nombre para distinguir los objetos de intercambio configurados.
En el dibujohttps://mainnet.infura.io/v3/xxxxxxxxxxxxx
La dirección de los nodos RPC de la red ETH de la empresa privada Infura.
在部署好托管者程序、配置好交易所对象的前提下,就可以使用FMZ.COM的「调试工具」进行测试了。调用以太坊RPC方法和以太坊交互,除了本章节列举介绍的几个RPC方法,其它RPC方法可以查询资料了解,例如https://www.quicknode.com/docs。
Para empezar, vamos a poner algunos ejemplos sencillos. Hay diferentes maneras de acceder a web3 para diferentes lenguajes y herramientas:
En FMZ también se envuelven las llamadas de métodos RPC, que están envueltas en las funciones API de FMZ.exchange.IO
El modo de llamada es:exchange.IO("api", "eth", ...)
El primer parámetro es el de entrada fija."api"
El segundo parámetro es la entrada fija."eth"
Los otros parámetros dependen del método de RPC que se está llamando.
En la actualidad, la plataforma FMZ es la única que puede exportar información.Log
La funciónLog
La función puede ingresar varios parámetros y luego exportarlos a la zona de registro en la página de "Herramientas de depuración" o "Disco real" de la plataforma FMZ, donde la página de "Herramientas de depuración" será la principal herramienta que probaremos.
El dinero de Ethereumeth_getBalance
Método utilizado para consultar el saldo de ETH de una dirección en Ethereum que requiere la transmisión de dos parámetros.
Vamos a preguntar al fundador de Ethereum.V神
La dirección conocida de la cartera de ETH es:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
。
function main() {
let ethBalance = exchange.IO("api", "eth", "eth_getBalance", "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest")
Log("ethBalance:", ethBalance)
}
Ya se ha implementado un administrador (en el gráfico: linux/amd64...) y se ha configurado un objeto de intercambio (en el gráfico: Web3 test), se ha probado el código en la herramienta de depuración:
Haga clic en el botón "Executar" y ejecute este código, que muestra el resultado:
EthBalance: 0x117296558f185bbc4c6
Log
Las funciones se imprimen.ethBalance
El valor de la variable es:0x117296558f185bbc4c6
, es el tipo de cadena. SíSaldo de ETH en el valor de los 16 dígitos¿Qué es esto?wei
En cuanto a las unidades,1e18 wei
Es igual a 1.ETH
Por lo tanto, también necesita ser convertido para convertirse en un saldo decimal de ETH legible.
¿Qué es esto?ethBalance
Convierte a datos legibles:
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)
}
En la parte superiorhttps://etherscan.io/
Encuestas:
Sin embargo, esto se debe a que el problema de la precisión del lenguaje en sí mismo puede tener desviaciones, por lo que la plataforma FMZ tiene dos funciones integradas para procesar datos:
El código se ha modificado:
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()))
}
El saldo de la vida es de 5149,6244846875215.
eth_chainId
ynet_version
Las dos funciones devuelven el Id de la cadena de bloques a la que el nodo RPC actual accede, con la diferencia de que el valor de la función RPC es el valor de la cadena de bloques.net_version
El número de números que se devuelve es el número decimal Id.eth_chainId
Devolver el Id de los dieciséis dígitos
Nombre de la red correspondiente a la cadena 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
Utilizando una red de pruebas de Ethereum bien configuradagoerli
Las pruebas en los nodos:
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))
}
Llamadoeth_gasPrice
Métodos para consultar la cadena actualgas 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))
}
Aquí estamos escribiendo una función que convierte una cadena de 16 dígitos en una operación que puede ser leída:toAmount
También hay que tener en cuenta que la unidad de gasPrice es:wei
Así que, por ejemplo,decimals
El valor del parámetro real correspondiente es 0.
eth_blockNumbe
Para consultar la altura de los bloques.
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))
}
La herramienta de depuración funciona en:
https://etherscan.io/
Encuestas:
Encuentra información sobre el bloque.
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])
}
}
En la herramienta de depuración se puede obtener la siguiente información:
En la actualidad, Ethereum cuenta con una gran cantidad de aplicaciones de contratos inteligentes.ENS
El blogger de Twitter, que también es uno de ellos, escribió:ENS
El servicio de nombres de dominio Ethereum (Ethereum Name Service) es un servicio de resolución de nombres de dominio descentralizado basado en la cadena de bloques Ethereum.
¿Recuerdan que en el tutorial consultamos el ejemplo del saldo de la cartera de V, el fundador de Ethereum?0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
Entonces, ¿cómo sabemos la dirección?ENS
Los contratos inteligentes, con un nombre intuitivovitalik.eth
El nombre del dios V (vitalik) para hacer una consulta.
En este capítulo, el siguiente contenido se utiliza en el entorno de la red Ethereum, basado en:ENS
Se sabe que se requiere documentación para realizar la consulta de nombres de dominio de Ethereum.Hashing Names
Para hacer esto, utilice el siguiente código:vitalik.eth
El nombre está siendo procesado.
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))
}
}
En el ejemplo de código anterior, vemos otra función extraña.Encode
Esta función es una función de la API de la plataforma FMZ, que se utiliza específicamente para realizar operaciones de codificación en la plataforma FMZ. La función admite múltiples métodos de codificación y soporta múltiples algoritmos de hash.
Encode(algo, inputFormat, outputFormat, data, keyFormat, key string)
Según lo descrito en la documentación ENS, el usosha3.keccak256
Los algoritmos procesan los datos.
LlamadonameHash
Funciones, por ejemplo:Log(nameHash("vitalik.eth"))
¿Qué es lo que está sucediendo?ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835
, con el prefijo "0x".0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835
Los contratos inteligentes de ENSresolver
Los parámetros del método.
let ensNode = "0x" + nameHash("vitalik.eth") // 准备好调用resolver方法的参数ensNode
La dirección del contrato para la aplicación de contratos inteligentes de ENS se encuentra en:0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
¿Qué es lo que está sucediendo?resolver
Antes de abordar el tema, también necesitamos preparar el contrato.ABI
。
Aprender a venir aquí no puede dejar de preguntarse, ¿qué es un contrato inteligente?ABI
¿Qué es eso?
ABI,即应用程序二进制接口(Application Binary Interface),是智能合约与外部世界进行通信的接口标准。
智能合约的 ABI 定义了合约的函数接口、参数类型、返回值等信息,以及调用合约的方式和参数传递方式等规范。
智能合约的 ABI 通常以 JSON 格式存储,包含以下信息:
合约的函数接口:函数名、参数列表、返回值等信息。
函数参数类型:如 uint256、bool、string 等。
函数的输入参数和输出参数的编码方式:智能合约使用一种称为 Solidity ABI 的编码方式来编码函数的输入参数和输出参数,
以便与以太坊网络进行交互。
在以太坊网络中,使用智能合约的 ABI 来调用合约的函数。当需要调用合约函数时,需要提供函数名和函数参数,以及将函数参数按照 ABI 编码方式编码后的字节码。
以太坊节点会将这些信息打包成一笔交易,并将交易发送到以太坊网络中执行。
智能合约的 ABI 在 Solidity 语言中可以通过 interface 关键字来定义。以太坊开发工具如 Remix IDE、Truffle 等也提供了 ABI 编辑和生成工具,
使得开发者可以方便地创建和使用智能合约的 ABI。
Se extrae de la ABI de la ENSresolver
La parte de los métodos, también puede utilizar el ABI completo, se puede encontrar enhttps://etherscan.io/
Encuentra el ABI del contrato o obtén el ABI por otros medios (por ejemplo: documentación del proyecto).
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"}]`
En este caso, vamos a aprender una nueva forma de llamar en la plataforma FMZ.exchange.IO("abi", address, abiContent)
En la actualidad, la mayoría de los usuarios de Twitter están registrados en el sitio web de ABI.address
Los parámetros son las direcciones de los contratos inteligentes.abiContent
Los parámetros son los correspondientes contratos inteligentes 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智能合约的地址
Ahora podemos llamar a los contratos inteligentes ENS.resolver
El método es el método de regreso.ENS: Public Resolver
La dirección del contrato.
let resolverAddress = exchange.IO("api", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", "resolver", ensNode)
UsoENS: Public Resolver
El contratoaddr
Métodos para obtener la dirección de la billetera de V.ENS: Public Resolver
El contrato aún requiere registrar el ABI.https://etherscan.io/
¿Qué es lo que está pasando?
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)
Última llamadaENS: Public Resolver
El contratoaddr
El método, los parámetros siguen siendoensNode
。
let vitalikAddress = exchange.IO("api", resolverAddress, "addr", ensNode)
Log("vitalikAddress:", vitalikAddress)
La función Log tiene una salida:
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)
}
En los capítulos anteriores del curso hemos aprendido cómo configurar la clave privada, ¿cómo sabemos que la clave privada corresponde a la dirección de la cartera para el objeto de intercambio que se ha configurado?exchange.IO("address")
La función obtiene la dirección de la billetera correspondiente a la clave privada configurada.
Debido a lo siguiente:Goerli
En el caso de la red, la red es un entorno de prueba, así que el nodo que uso es:https://goerli.infura.io/v3/*******
En el caso de los usuarios registrados, infura les asigna diferentes direcciones de los nodos.*******
El contenido específico está oculto.
function main() {
let walletAddress = exchange.IO("address")
Log("测试网 goerli 钱包地址:", walletAddress)
}
Una vez que se conoce la dirección de su billetera, se puede usar el método RPC de Ethereum.eth_getTransactionCount
El conteo de transacciones para consultar la dirección de la billetera. En Ethereum, este conteo es muy común, en realidad, es lo que se necesita para ingresar operaciones de transferencia.nonce
Parámetros, en Ethereum, el nonce se utiliza para asegurarse de que cada transacción es un número único. Es un número incremental que se incrementa automáticamente cada vez que se envía una nueva transacción. Por lo tanto, cuando envías transacciones a un contrato inteligente, es necesario proporcionar un nonce para asegurarse de que las transacciones son únicas y en el orden correcto.
Aquí está el archivo de Ethereum en Go.PendingNonceAt
La función es lo que se llama.eth_getTransactionCount
Métodos. En las clases anteriores también aprendimos cómo llamar al método RPC, y lo volveremos a usar aquí.exchange.IO("api", "eth", ...)
La función.
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))
}
Antes de explicar cómo funciona la transferencia, simplemente entendemos algunos conceptos que consumen ciertos tokens de ETH en la transferencia en Ethereum (como gas).
Gas precio
Sin embargo, la tarifa de gas en la red Ethereum siempre fluctúa según la demanda del mercado y lo que los usuarios están dispuestos a pagar, por lo que escribir una tarifa de gas fija en el código a veces no es una opción ideal.eth_gasPrice
El método que se utiliza para obtener el precio promedio del gas.
GasLimit
El límite de gas para una transferencia estándar de Ethereum es de 21000 unidades.
Ya lo entiendo.nonce
,gasPrice
,gasLimit
Estos conceptos pueden ser probados con transferencias.
exchange.IO("api", "eth", "send", toAddress, toAmount)
En la actualidad, la mayoría de los usuarios de Twitter no tienen acceso a la red social.exchange.IO
El tercer parámetro de la función se escribe fijamente como "send".toAddress
Los parámetros son la dirección de ETH que se recibe en el momento de la transferencia.toAmount
La cantidad de ETH para transferir.
nonce
,gasPrice
,gasLimit
Estos parámetros se pueden usar en FMZ con valores que el sistema obtiene automáticamente por defecto. También se puede especificar:
exchange.IO("api", "eth", "send", toAddress, toAmount, {gasPrice: 5000000000, gasLimit: 21000, nonce: 100})
A continuación, transferimos un cierto número de ETH a una dirección en el goerli de la web de pruebas:
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
}
La cantidad de transferencias en Ethereum eswei
Para ello, se necesita una función de configuración.toInnerAmount
Tratamiento comowei
El valor de la unidad.
En elhttps://etherscan.io/
Encuentra el hash de transacción:0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e
。
También puede escribir el código de búsqueda de transferencia de hash.0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e
¿Cómo se usa?eth_getTransactionReceipt
¿Cómo hacer una consulta?
function main() {
let transHash = "0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e"
let info = exchange.IO("api", "eth", "eth_getTransactionReceipt", transHash)
return info
}
Los resultados de la búsqueda:
{
"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": []
}
Cada campo tiene una descripción correspondiente:
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 - 值的类型
Estamos enLeer la información del contratoEn este capítulo se obtiene la dirección de la billetera de V de Dios mediante un ejemplo completo de cómo llamar a un contrato ENS implementado en Ethereum.Read
No hay necesidad de llamarlos.gas
En este capítulo vamos a llamar a algunos de los contratos inteligentes en Ethereum.Write
Métodos y pagosgas
Estas operaciones serán validadas por cada nodo de la red y por los mineros, y cambiarán el estado de la cadena de bloques.
En el caso de los contratos ERC20 (los contratos de tokens ERC20), la plataforma FMZ incluye los contratos ERC20 como ABI de uso común directamente integrados en el sistema, omitiendo este paso de registro de ABI.
Para una mejor comprensión de los ABI, antes de usarlos, vea los siguientes ABI de los contratos 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"}]
El contenido de este capítulo:Goerli
Los usuarios de Twitter también pueden usar el servicio de Facebook para probar sus redes.
Y luego volvemos a practicar una vez más cómo llamar a los contratos.Read
El método para leer la información de los contratos y llamar a los contratos ERC20balanceOf
El método para consultar el saldo de los tokensbalanceOf
El método tiene un solo parámetro, pero no tiene nombre, y se puede ver por el tipo como una dirección (es decir, la dirección del token consultado). Dado que los datos devueltos no están en un solo token, también se requieren datos de precisión de los tokens para intercambiarlos, la precisión de los tokens se puede calcular con contratos ERC20.decimals
Método de obtención. Utilizamos la red de pruebas de Ethereum.goerli
Para hacer una prueba, tenga en cuenta que las direcciones de los contratos de tokens en diferentes cadenas también pueden ser diferentes.
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