avatar of 发明者量化-小小梦 发明者量化-小小梦
focar em Mensagem privada
4
focar em
1271
Seguidores

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

Criado em: 2023-03-28 13:32:48, atualizado em: 2024-11-11 22:28:24
comments   0
hits   3837

[TOC]

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

Tutorial EtherEaseWithFMZ

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

Ethereum é uma plataforma de contrato inteligente baseada na tecnologia blockchain, que fornece uma maneira descentralizada de escrever e implantar contratos inteligentes. Um contrato inteligente é um programa de computador especial que pode ser executado automaticamente no blockchain e pode implementar várias lógicas de negócios sem a necessidade de confiar em terceiros.

A plataforma de negociação quantitativa Inventor (FMZ.COM) fornece uma API fácil de usar que facilita a interação dos desenvolvedores com a blockchain Ethereum e seu ecossistema. Realize funções como acesso a exchanges descentralizadas (DEX), obtenção de dados on-chain e envio de transações.

Os exemplos neste tutorial usamJavaScriptEscrita de linguagem, uso de ambiente de testeRede principal EthereumRede de teste Goerli. Você também pode visualizar as interfaces de API usadas no tutorial, bem como descrições relacionadas e exemplos de código na documentação da API da plataforma FMZ.


Introdução ao FMZ

Antes de aprender a usar a plataforma de negociação quantitativa FMZ, precisamos estar familiarizados com vários conceitos básicos:

1. Arquitetura da plataforma de negociação quantitativa FMZ

Após se registrar e fazer login no site oficial da plataforma de negociação quantitativa FMZ (https://www.fmz.com), você pode usar as diversas funções da plataforma. O site da FMZ é o gerenciamento de todo o sistema, e os programas escritos pelos usuários são executados no host. O host é um programa de software que pode ser implantado em vários dispositivos, como servidores, computadores, etc. Quando um usuário escreve um programa e cria uma instância em execução no site da FMZ, a plataforma FMZ se comunica com o host e inicia uma instância do programa no host.

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

2. Anfitrião

Se você quiser executar uma instância de programa, você deve implantar um host. A implantação do host também é muito simples, e há um tutorial de implantação na plataforma. Você também pode usar o “host de implantação com um clique” fornecido na FMZ para implantar automaticamente usando o servidor alugado pela FMZ.

  • Implantar um host em um dispositivo pessoal

O programa custodiante pode ser implantado e executado em servidores, computadores pessoais e outros dispositivos, desde que a rede esteja normal (o alvo correspondente precisa estar acessível, como uma interface de troca, endereço de nó, etc.). As principais etapas da implantação são:

  1. Efetue login ou abra o dispositivo onde deseja implantar o programa host, comoFaça login no servidorouLigue o computador e entre no sistema operacional
  2. Baixe a versão correspondente do programa host (dependendo do sistema operacional do dispositivo), página de download: https://www.fmz.com/m/add-node Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum
  3. O arquivo baixado é um pacote compactado, que precisa ser descompactado.
  4. Execute o programa host. O programa host é um programa chamadorobotarquivo executável. Configure o endereço de comunicação do custodiante. Este endereço de comunicação é exclusivo para cada conta FMZ. Após efetuar login no FMZ,https://www.fmz.com/m/add-nodeA página pode visualizar seu próprio endereço (por exemplo:./robot -s node.fmz.com/xxxxxEsta sequência de endereços, aquixxxxxO conteúdo do local é exibido de forma diferente para cada conta FMZ). Por fim, você precisa digitar a senha da conta FMZ. Após configurá-las, execute o programa host.
  • Utilize a função “implantação de custodiantes com um clique” da plataforma FMZ

Adicione uma página de custodiante na plataforma FMZ, endereço:https://www.fmz.com/m/add-node

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

3. Ferramentas de depuração

A plataforma de negociação quantitativa FMZ fornece uma ferramenta de depuração gratuita que oferece suporteJavaScriptTypeScriptA página é: https://www.fmz.com/m/debug, porque a criação de uma instância e sua execução são cobradas. Esta ferramenta de depuração pode ser usada para testes e aprendizado durante o período inicial de aprendizado. A ferramenta de depuração não é diferente da criação de uma instância, exceto que o tempo de execução é limitado a 3 minutos.

usarTypeScriptAo usar a linguagem, você precisa escrevê-la na primeira linha do código// @ts-checkPara mudar paraTypeScriptModo, se não alternado, o padrão éJavaScriptlinguagem.

4. Trocas

Na FMZ, “exchange” é um conceito geral. Para uma exchange CEX, refere-se a uma configuração de conta de exchange específica. Para web3, essa troca se refere a informações de configuração, incluindo endereço do nó e configuração de chave privada.

Ao efetuar login na plataforma FMZ,https://www.fmz.com/m/add-platformNa página, você pode configurar as informações de troca, onde troca é um conceito geral.

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

escolherWeb3, configure o endereço do nó RPC e a chave privada. Você pode clicar em “Informações sensíveis são criptografadas e salvas usando uma chave privada independente” no canto inferior direito para visualizar o mecanismo de segurança.

Os nós podem ser autoconstruídos ou fornecidos por provedores de serviços de nós. Existem muitos provedores de serviços de nó, como:Infura. Após o registro, você pode visualizar o endereço do nó da sua conta. Há mainnet e testnet, o que é mais conveniente. Configure esse endereço de nó na figura acima.Rpc Addressnos controles. As tags podem ser nomeadas individualmente para distinguir os objetos de troca configurados.

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

Na figurahttps://mainnet.infura.io/v3/xxxxxxxxxxxxxÉ o endereço do nó RPC da rede principal privada Infura ETH.


Usando FMZ para interagir com Ethereum

Depois de implantar o programa de custódia e configurar o objeto de troca, você pode usar a “ferramenta de depuração” do FMZ.COM para testes. Chame os métodos RPC do Ethereum para interagir com o Ethereum. Além dos vários métodos RPC listados neste capítulo, você pode consultar a documentação para outros métodos RPC, comohttps://www.quicknode.com/docs

Vamos pegar alguns exemplos simples e começar com o básico. Existem formas de acessar o web3 para diversas linguagens e ferramentas, conforme mostrado na figura:

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

Chamadas de método RPC também são encapsuladas no FMZ. Essas funções são encapsuladas na função FMZ APIexchange.IOmeio. O método de chamada éexchange.IO("api", "eth", ...). O primeiro parâmetro é fixo."api", o segundo parâmetro é fixo"eth", outros parâmetros dependem do método RPC específico chamado.

Para saída de informações, utilizamos a plataforma FMZLogfunção,LogA função pode passar múltiplos parâmetros e então exibi-los na área de log da página “Debug Tool” ou “Real Trading” da plataforma FMZ. A página “Debug Tool” será a ferramenta principal para nossos testes.

eth_getBalance

Ethereumeth_getBalanceO método é usado para consultar o saldo ETH de um endereço no Ethereum. Este método requer que dois parâmetros sejam passados.

  • O endereço a ser consultado.
  • Etiqueta, geralmente “mais recente”.

Vamos conferir o fundador do EthereumV神Endereço da carteira ETH, os endereços conhecidos são:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045

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

O custodiante foi implantado (na figura: linux/amd64 …) e o objeto de troca foi configurado (na figura: Web3 test). Teste o código na ferramenta de depuração:

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

Clique no botão “Executar” para executar este código e exibir os resultados:

ethBalance: 0x117296558f185bbc4c6

LogA função imprimeethBalanceOs valores das variáveis ​​são:0x117296558f185bbc4c6, que é um tipo de string. simSaldo ETH em valor hexadecimal,porweiComo uma unidade,1e18 weié 1ETH. Portanto, ele precisa ser convertido em um saldo ETH decimal legível.

VaiethBalanceConverter em dados legíveis:

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

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

No topohttps://etherscan.io/Consulta:

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

Entretanto, esse processamento terá desvios devido à precisão da própria linguagem, por isso a plataforma FMZ possui duas funções integradas para processamento de dados:

  • BigInt: Converte uma string hexadecimal em um objeto BigInt.
  • BigDecimal: Converte um objeto do tipo numérico em um objeto BigDecimal que pode ser operado.

Ajuste o código novamente:

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

vitalikEthBalance: 5149.6244846875215

eth_chainId

eth_chainIdenet_versionOs usos são semelhantes, então os testamos juntos. Ambas as funções retornam o ID do blockchain ao qual o nó RPC atual está conectado. A diferença énet_versionRetorna o Id decimal.eth_chainIdRetorna o ID hexadecimal.

O nome da rede correspondente ao ID da cadeia

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

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

Use a rede de teste Ethereum configuradagoerliTeste de nó:

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

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

eth_gasPrice

Chamareth_gasPriceMétodo para consultar a cadeia atualgas 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))
}

Aqui escrevemos uma função para converter uma string hexadecimal em um valor legível:toAmount. Outra coisa a ser observada é que a unidade de gasPrice éwei, então o parâmetrodecimalsO parâmetro real correspondente pode ser passado como valor 0.

eth_blockNumbe

eth_blockNumbeUsado para consultar a altura do bloco.

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

Execute no depurador:

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

https://etherscan.io/Em consulta:

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

eth_getBlockByNumber

Informações do bloco de consulta.

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

As seguintes informações podem ser obtidas executando na “Ferramenta de Depuração”:

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum


Ler informações do contrato

Há um grande número de aplicativos de contratos inteligentes em execução no Ethereum.ENSé um deles.ENS, ou seja, o Ethereum Name Service, é um serviço descentralizado de resolução de nomes de domínio baseado na blockchain Ethereum. Lembra do exemplo no tutorial em que consultamos o saldo da carteira do fundador do Ethereum, Vitalik Buterin? Um dos endereços da carteira de Vitalik é:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045. Então como sabemos esse endereço? Na verdade, atravésENSContrato inteligente, usando um nome intuitivovitalik.eth(vitalik é o nome de Vitalik) para conduzir a consulta.

O conteúdo a seguir neste capítulo usa o ambiente de rede principal do Ethereum.ENSO documento mostra que o nome de domínio Ethereum a ser consultado precisa serHashing Names, use o seguinte código paravitalik.ethO nome é processado.

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

No exemplo de código acima, vemos outra função desconhecidaEncodeEsta função é a função API da plataforma FMZ, que é usada especificamente para executar operações de codificação na plataforma FMZ. Esta função suporta múltiplos métodos de codificação e múltiplos algoritmos de hash.

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

De acordo com a documentação do ENS, usesha3.keccak256Algoritmos processam dados.

ChamarnameHashFunções, por exemplo:Log(nameHash("vitalik.eth")), podemos obter:ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835, você precisa adicionar o prefixo “0x”.0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835Como um contrato inteligente ENSresolverOs parâmetros do método.

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

De acordo com o documento ENS, o endereço do contrato do aplicativo de contrato inteligente ENS é:0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e. Ao chamar o contrato inteligenteresolverAntes de prosseguirmos, precisamos preparar o contratoABI

Registrando ABI

Depois de aprender isso, não posso deixar de perguntar: o que é um contrato inteligente?ABITecido de lã?

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

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

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

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

Extraia o seguinte do ENS ABI:resolverO ABI completo também pode ser usado nohttps://etherscan.io/Você pode consultar o ABI do contrato no GitHub ou obtê-lo por outros meios (por exemplo, documentos relevantes do projeto).

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

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

Aqui temos que aprender um novo método de chamada na plataforma FMZ.exchange.IO("abi", address, abiContent), use este método para registrar ABI,addressO parâmetro é o endereço do contrato inteligente.abiContentO parâmetro é o ABI do contrato inteligente correspondente (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智能合约的地址

Chamando métodos de contrato inteligente

Em seguida, você pode chamar o contrato inteligente ENSresolvermétodo, que retornaENS: Public ResolverO endereço do contrato.

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

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

usarENS: Public ResolverContratualaddrMétodo para obter o endereço da carteira de Vitalik. Para chamarENS: Public ResolverO contrato ainda precisa registrar o ABI primeiro. As informações ABI deste contrato inteligente ainda podem ser encontradas emhttps://etherscan.io/Pegar.

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)

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

Última chamadaENS: Public ResolverContratualaddrMétodo, os parâmetros ainda sãoensNode

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

Saída da função Log:

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

vitalikAddress: 0xd8da6bf26964af9d7eed9e03e53415d37aa96045

Código completo para chamar 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)
}

Enviar ETH

Nos capítulos anteriores do curso, aprendemos como configurar chaves privadas. Para o objeto de troca configurado, como sabemos o endereço da carteira correspondente a essa chave privada? Disponível na FMZexchange.IO("address")A função obtém o endereço da carteira correspondente à chave privada configurada.

Uma vez que o conteúdo a seguir deste capítulo utilizaGoerliAmbiente de rede de teste, então o nó que eu uso é:https://goerli.infura.io/v3/*******, O Infura atribui diferentes endereços de nós a cada usuário registrado.*******O conteúdo específico está oculto.

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

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

Depois de saber o endereço da sua carteira, você pode usar o método RPC do Ethereumeth_getTransactionCountConsultar a contagem de transações de um endereço de carteira. Essa contagem é muito comumente usada no Ethereum. Na verdade, é o que precisa ser passado ao transferir dinheiro.nonceParâmetros: No Ethereum, nonce é um número usado para garantir que cada transação seja única. É um número crescente que é incrementado automaticamente cada vez que uma nova transação é enviada. Portanto, ao enviar uma transação para um contrato inteligente, você precisa fornecer um nonce para garantir que a transação seja única e esteja na ordem correta. Em alguns dados e documentos podemos encontrar:

https://goethereumbook.org/en/

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

Aqui está a biblioteca Ethereum em linguagem GoPendingNonceAtA função realmente chamaeth_getTransactionCountmétodo. No curso anterior, também aprendemos como chamar métodos RPC. Usaremos isso novamente aqui.exchange.IO("api", "eth", ...)função.

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 a operação de transferência, vamos entender brevemente alguns conceitos. Ao transferir dinheiro no Ethereum, uma certa quantia de tokens ETH será consumida (como taxas de gás). A taxa de gás é determinada por dois parâmetros:

  • gasPrice

No entanto, as taxas de gás na rede Ethereum estão sempre flutuando com base na demanda do mercado e no que os usuários estão dispostos a pagar, então, escrever uma taxa de gás fixa no código às vezes não é o ideal. Podemos usar o que aprendemos anteseth_gasPriceMétodo que permite obter o preço médio do gás.

  • gasLimit

O limite de gás para uma transferência de éter padrão é de 21.000 unidades.

EntendinoncegasPricegasLimitCom esses conceitos, você pode testar a transferência. Uma função de transferência muito simples e fácil de usar está encapsulada no FMZ.

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

Quando usado para transferência,exchange.IOO terceiro parâmetro é sempre “enviar”.toAddressO parâmetro é o endereço que recebe ETH durante a transferência.toAmountA quantidade de ETH transferida.

noncegasPricegasLimitEsses parâmetros podem utilizar os valores obtidos automaticamente pelo sistema por padrão no FMZ. Você também pode especificar:

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

Em seguida, transferimos uma certa quantidade de ETH para um determinado endereço na rede de teste 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
}

Porque a unidade do valor da transferência Ethereum éwei, você precisa usar uma função personalizadatoInnerAmountProcessado comoweiO valor da unidade.

existirhttps://etherscan.io/Hash de transação de consulta:0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e

Use o FMZ para começar facilmente com o desenvolvimento web3 baseado em Ethereum

Você também pode escrever código para consultar o hash de transferência0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e,usareth_getTransactionReceiptMétodo para consulta.

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

Resultados da consulta:

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

Descrição de cada campo:

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

Chamando o contrato inteligente Ethereum

Nós somosLer informações do contratoEsta seção usa um exemplo completo para chamar o método de contrato ENS implantado no Ethereum para obter o endereço da carteira de Vitalik. Esses métodos pertencem aReadMétodos, não é necessário chamar esses métodosgas(Lembra que falamos sobre gás antes?). Nesta seção, citaremos alguns contratos inteligentes no EthereumWriteMétodo e pagamentogas. Essas operações serão verificadas por cada nó e minerador em toda a rede e alterarão o estado do blockchain.

ERC20

Para contratos ERC20 (contratos de token ERC20), a plataforma FMZ lista o ABI do contrato ERC20 como um ABI comumente usado e o incorpora diretamente no sistema, eliminando a etapa de registro do ABI. Também aprendemos sobre ABI no tutorial anterior. Quando chamamos o método de contrato ENS, primeiro registramos o ABI do contrato ENS.

Para entender o ABI mais claramente, você pode verificá-lo antes de usá-lo. O seguinte é o ABI do contrato ERC20:

”`javascript [{“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”:“nonpayabl