Explicação detalhada da construção do objeto de transação Ethereum em Js

       Este artigo usa a ethersbiblioteca como a implementação subjacente e descreve as propriedades detalhadas do objeto de transação Ethereum criado em Javascript. Este artigo pressupõe que o leitor tenha um certo conhecimento básico de Ethereum.

1. O que é uma ethersbiblioteca

       O que se segue é uma introdução original de seu documento:

       A biblioteca ethers.js pretende ser uma biblioteca completa e compacta para interagir com o Ethereum Blockchain e seu ecossistema. Ele foi originalmente projetado para uso com ethers.io e desde então se expandiu para uma biblioteca de uso muito mais geral.

       O significado aproximado é ethers.jsuma biblioteca completa e compacta aplicada ao Ethereum e seu ecossistema. Ele foi originalmente projetado para ser usado em ethers.io e lentamente expandido em uma biblioteca multifuncional.

       ethersA biblioteca possui as seguintes características:

  • A chave privada é armazenada no cliente, segura e livre de riscos
  • Suporte para importação e exportação de carteiras em formato json (pode ser usado para Geth ou Paridade)
  • Suporte para importação e exportação de palavras mnemônicas e carteira de hardware, palavras mnemônicas suportam vários idiomas
  • Suporta vários formatos ABI, incluindo ABIv2 e ABI legível por humanos
  • Suporta várias maneiras de se conectar a nós Ethereum, como JSON-RPC, INFURA, Etherscan ou MetaMask.
  • Os nomes ENS são totalmente suportados como a primeira categoria de elementos
  • A biblioteca é muito pequena (versão não compactada de 284kb, versão compactada de 88kb)
  • Funções completas para atender a todas as suas necessidades para Ethereum
  • Documentação detalhada
  • Adicionados muitos casos de teste
  • TypeScript legível
  • Certificado MIT (incluindo suas dependências), totalmente de código aberto

Em segundo lugar, construa um objeto comercial

       Em ethers.js, um objeto de transação Ethereum é um objeto comum {}, que contém os seguintes atributos opcionais:

  • para
  • gasLimit
  • gasPrice
  • nonce
  • dados
  • valor
  • chainId

       Os atributos acima são todos opcionais, o que significa que podem ser omitidos, mas não todos, deve haver pelo menos um atributo. Criamos um objeto de transação da seguinte maneira:

// All properties are optional
let transaction = {
    
    
    nonce: 0,
    gasLimit: 21000,
    gasPrice: utils.bigNumberify("20000000000"),

    to: "0x88a5C2d9919e46F883EB62F7b8Dd9d0CC45bc290",
    // ... or supports ENS names
    // to: "ricmoo.firefly.eth",

    value: utils.parseEther("1.0"),
    data: "0x",

    // This ensures the transaction cannot be replayed on different networks
    chainId: ethers.utils.getNetwork('homestead').chainId
}

       Abaixo, explicamos esses atributos por meio de transações reais na rede de teste Kovan.

3. Explicação detalhada dos atributos do objeto de transação

       Existem os seguintes trechos de código, nós modificaremos ou adicionaremos a este trecho em transações futuras. Esta é uma transação que cria um contrato:

let data='0x60....'
let provider = ethers.getDefaultProvider('kovan')
let wallet_new = wallet.connect(provider)
let trans = {
    
    
    data:inputData
}
wallet_new.sendTransaction(trans).then( tx => {
    
    
    console.log(tx)
}).catch( err => {
    
    
    console.log(err)
})

Como você pode ver, nosso objeto de transação tem apenas um atributo datae seu valor é o bytecode para criar o contrato. Nota: O bytecode ao criar o contrato não é o bytecode compilado pelo contrato de criação, mas o bytecode que pode ser obtido executando o bytecode do contrato criado.

       Vamos dar uma olhada na resposta da transação impressa (Transaction Response):
Insira a descrição da imagem aqui
       você pode ver que no objeto de resposta da transação, além dos toatributos, existem outros atributos. Portanto, o atributo mencionado acima pode ser omitido significa que ele pode ser omitido ao construir o objeto de transação. Se omitido, a ethersbiblioteca subjacente irá configurá-lo automaticamente para você. Vamos começar com este objeto de negociação mais simples, aumentar e explicar suas propriedades passo a passo.

3,1 to

       Já que o toatributo é null, começaremos com o toatributo. toRepresenta o endereço do receptor na transação.

       Uma transação no Ethereum deve ter um iniciador (conta externa, conta sem contrato), normalmente from. Porque a ethersbiblioteca que usamos usa a carteira para assinar transações, então quem assina é quem assina from. A transação geralmente tem um destinatário (conta externa e conta do contrato), ou seja to. Por que isso é normal? Porque, como nosso exemplo agora, não há recebedor quando o contrato é criado. Embora o endereço do contrato seja toretornado como um atributo após a criação do contrato , esse toendereço está vazio quando é criado . Vamos dar uma olhada na captura de tela do etherscan para aprofundar essa impressão:
Insira a descrição da imagem aqui
       você pode ver que depois que a transação é executada, este toatributo é o endereço do novo contrato. Deixe-me acrescentar que o endereço do contrato é calculado com base no endereço do chamador e no número de transações (nonce) que o chamador concluiu. Portanto, antes da implantação efetiva de um contrato, o endereço é definido e pode ser obtido.

       Para resumir, o toatributo é o endereço do receptor na transação. Especificamente: se você estiver transferindo ETH para uma conta externa, é o endereço de recebimento da ETH; se você estiver chamando um contrato (transferir ETH para uma conta de contrato também é um contrato de chamada), é o endereço do contrato; se você estiver criando um contrato, porque não há nenhum destinatário no momento, Basta padronizá-lo.

3,2 data

       Em seguida, falar sobre o código acima usa a propriedade: data. Durante a transação, podemos enviar dados da transação junto com a transação. Os dados de transação podem ser chamadas de método para o contrato ou alguns dados sem sentido, que às vezes são chamados payload. No exemplo acima, datao valor do atributo é o bytecode do contrato que criamos. Vamos adicionar um toatributo ao objeto de transação acima e modificar datao valor do atributo:

let trans = {
    
    
    data:"0x496c6f7665457468657265756d",
    to:"0xDD55634e1027d706a235374e01D69c2D121E1CCb"
}

       Aqui toestá um endereço de conta externa, que dataé a string "I love Ethereum" convertida em valor hexadecimal ( datadeve 0xcomeçar com). A resposta após o envio da transação é a seguinte:
Insira a descrição da imagem aqui
       Vamos ver o resultado no etherscan:
Insira a descrição da imagem aqui
       A partir do trecho de código, podemos ver que enviamos diretamente uma mensagem (string) para uma conta. Na parte inferior de InputData, ele exibe dados nativos por padrão. Selecione View Input As UTF-8, e IloveEthereum será exibido. Nenhum espaço é mostrado aqui porque a ferramenta que usei não codificava espaços. Essa função de enviar uma string para uma conta parece enviar uma mensagem curta para um número de telefone celular? Você pode até enviar um artigo (mas com muitas taxas), o Ethereum é interessante?

       Se os dados enviados são os dados quando o método de contrato é chamado, geralmente têm um formato fixo e não podem ser dados arbitrários. Os exemplos são os seguintes:

data:0x07391dd6000000000000000000000000000000000000000000000000000000000000000a

       Aqui, os primeiros 8 bits 07391dd6dos primeiros 32 bytes são seletores de função e, após 32 bytes, estão os dados do tipo correspondente. Os leitores interessados ​​podem ler artigos relacionados na codificação Ethereum por conta própria.

       Bem, para resumir: o dataatributo são os dados enviados com a chamada. Se o objeto chamado for um contrato, geralmente é o código do método de chamada do contrato; se for para criar um contrato, é o bytecode criado; se o objeto chamado for uma conta externa, o conteúdo desses dados é arbitrário (a conta externa não tem código , E não executará os dados enviados).

3,3 value

       valueO atributo representa a quantidade de Ether enviada com esta transação. Independentemente de o tipo de transação ser transferência direta de ETH (incluindo transferência para o contrato e transferência para uma conta externa), criação de um contrato (neste caso, ETH será usada como a ETH inicial do contrato criado) ou chamada de contrato (o método de contrato é payable), é registrado fielmente A quantidade de ETH que você enviou na transação (sem incluir a taxa de manuseio, a taxa de manuseio é um consumo adicional). Vamos apenas adicionar uma valuepropriedade do objeto de transação , seu valor são weiunidades de atenção . E geralmente quando estamos em uma referência geral às etherunidades monetárias Ethernet , precisamos fazer uso de uma conversão.

let trans = {
    
    
    data:"0x496c6f7665457468657265756d",
    value:ethers.utils.parseEther('0.1'),
    to:"0xDD55634e1027d706a235374e01D69c2D121E1CCb"
}

valueO valor no código é 0,1 ETH. Vamos enviar esta transação:
Insira a descrição da imagem aqui
       Em JS, se o número for relativamente grande, ele excederá o limite superior da representação decimal js (cerca de 10 ** 15), então BigNumber é geralmente usado para interagir com Ethereum. Você pode ver que o número de WEI enviado é convertido em um BigNumber. Vejamos o resultado do etherscan novamente:
Insira a descrição da imagem aqui
       ele não é mostrado aqui dataporque não cliquei em Clique para ver mais para expandir. Como você pode ver, enviamos 0,1 ETH com a transação.

3.4 gasLimitegasPrice

       A seguir, apresentaremos dois atributos relacionados ao gás: gasLimite gasPrice. Isso gasLimitse refere ao consumo máximo de gás da transação e gasPriceao preço que você está disposto a pagar pelo gás efetivamente consumido. A quantidade específica de gás consumido é multiplicada pela gasPricetaxa que você está disposto a pagar ao minerador. Após a transação ser executada, o gás não consumido será devolvido a você (a situação do erro de transação não será discutida aqui, neste caso às vezes o gás não consumido não será reembolsado).

       gasLimitNormalmente usado para limitar uma determinada transação não pode consumir muitos recursos. Aqui está um cenário de uso: Muitas vezes usamos MetaMask para transferir fundos diretamente para contas externas. O gasLimitvalor padrão no MetaMask é 23.000 , e o mínimo não pode ser inferior a 21.000.
Insira a descrição da imagem aqui

       Vejamos uma transação de transferência específica no etherscan:
Insira a descrição da imagem aqui
       Como você pode ver na figura acima, quando não enviamos nenhum dado com a transação (o dataatributo está vazio, se não estiver vazio, gás adicional será consumido), para um externo A transferência da conta consumirá 21 mil gás, o que é basicamente fixo. Portanto, o gasLimitlimite superior desta transação também é definido 21000, a taxa de utilização 100%.

       O nosso na foto acima gasPriceé 5 Gwei. Quanto mais alto o preço oferecido, mais rápida será a transação e, claro, maior será sua taxa de manuseio. Normalmente gasPrice, quando falamos sobre isso, todos nós o usamos Gweicomo uma unidade, mas ainda temos que convertê-lo quando o usamos wei. Este 5 Gweimultiplicado pelo gás consumido 21000é exatamente o que é mostrado na figura acima Transaction Fee: 0.000105ETH. Quando o autor escreve aqui, o preço da ETH gira em torno de US $ 205, então a taxa de manuseio para o envio é de cerca de 0.15RMB.

       Vamos adicionar esses dois atributos ao objeto de transação para ver se o excesso de gás é consumido. Nossa gasLimit está definido para 100000, gasPricedefinida como 3 Gwei, vamos reenviar a transação:

let trans = {
    
    
    data:"0x496c6f7665457468657265756d",
    value:ethers.utils.parseEther('0.1'),
    gasLimit:100000,
    gasPrice:ethers.utils.parseUnits("3",'gwei'),
    to:"0xDD55634e1027d706a235374e01D69c2D121E1CCb"
}

       Aqui, como o nosso gasLimitnão pode exceder o limite decimal de JS, o sistema decimal é usado diretamente 100000. A resposta da transação é:
Insira a descrição da imagem aqui
       olhamos diretamente para o resultado da transação no etherscan:
Insira a descrição da imagem aqui
       como enviamos I love Ethereumesta string com a transação , consumimos 208 mais gás. De acordo com a taxa que deduzimos, o gás não utilizado não está incluído no custo.

       Para gasLimitfalar geralmente em uso ethers, não é necessário definir a biblioteca, deixe-o como padrão na linha. Se quiser defini-lo manualmente, você pode usá-lo para estimar primeiro e, em seguida, expandi-lo para cima de forma adequada, como o seguinte snippet de código:

let args = [_address,amount]
let gasLimit = await contract.estimate.transfer(...args)
let step = ethers.utils.bigNumberify(1000)
gasLimit = gasLimit.add(step)

       Para gasPricefalar, geralmente definido como 5 Gweiou em circunstâncias normais 6 Gwei. Pode ser definido como 1.5 Gweiou quando o gás consumir muito ou a rede estiver ociosa 2 Gwei. No entanto, o tempo de transação será estendido dessa forma e pode até falhar. Se você quiser negociar rapidamente, defina-o como 10 Gweiou 20 Gweiaté mais alto, mas isso custará mais. Se você tiver mais dinheiro, será rápido e, se não tiver dinheiro suficiente, será lento. E tenha cuidado: uma taxa muito baixa pode fazer com que nenhum mineiro empacote a transação, e a transação irá falhar. Claro, se você estiver no testnet, você pode definir um valor mais alto, porque você não precisa realmente gastar dinheiro.

3,5 nonce

       No objeto de transação, noncerepresenta o número de transações concluídas pelo endereço. Começa em 0 e é um número inteiro que aumenta automaticamente. Normalmente, não precisamos defini-lo. Mas em alguns casos especiais, ele pode ser definido manualmente. Um cenário é ao cobrir transações. Você pode definir manualmente o nonce para o valor nonce de uma transação que foi enviada, mas ainda não concluída, para substituir a transação. Normalmente, o objetivo disso é acelerar a transação (aumentar gasPrice) ou usar completamente uma nova transação. Isso também é fácil de entender. Por exemplo, minha transação nº 122 é enviar uma ETH para A, mas antes que esta transação não seja enviada ou concluída, fiz uma modificação urgente para alterar esta transação nº 122 para enviar uma ETH para B. Nesse ponto, só preciso definir o nonce da nova transação como 122.

       Se você deseja definir no objeto de transação que você normalmente usa, você precisa consultar o número de transações concluídas.Este número é o valor nonce que você deve usar. Use o seguinte código:

let address = "0x02F024e0882B310c6734703AB9066EdD3a10C6e0";

provider.getTransactionCount(address).then((transactionCount) => {
    
    
    console.log("Total Transactions Ever Sent: " + transactionCount);
});

       É importante notar que: nonce tem um uso especial, você pode especificar um valor futuro. Por exemplo, se o número de transações que você concluiu atualmente é 2096, o valor do nonce para a próxima transação deve ser 2097. Neste ponto, você também pode pular 2097 e defini-lo como 2098, então o que acontecerá? Neste momento, a transação de número 2098 é equivalente a uma transação atrasada, que será enviada, mas não será executada, e você não poderá consultá-la no etherscan. Em seguida, realizamos uma transação normal com o valor nonce definido como 2097, e a transação será enviada e executada. Aí vem o ponto importante: no próximo bloco, a transação com um nonce de 2098 também será executada (porque 2097 já foi executada, é a sua vez).

3,6 chainId

       chainIdRepresenta o ID de rede com o qual você deseja iniciar uma transação. Pegue a rede principal e as três principais redes de teste como exemplos. A rede principal (mas ethersainda chamada de homesteadcasa na China) é 1, a Ropstenrede de teste é 3, a Rinkebyrede de teste é 4 e a Kovanrede de teste é 42. A rede personalizada pode ser configurada por você, etc.

       De modo geral, não há necessidade de configurar isso ao usar a carteira chainId. Como o login da carteira irá vincular uma rede, é a rede de seu objeto de transação. Mas você também pode definir manualmente um valor específico para evitar transações na rede errada. Você pode usar diretamente o valor numérico decimal acima ou pode usar etherso código de amostra em:

chainId: ethers.utils.getNetwork('homestead').chainId

       Se estivermos negociando na rede de teste Kovan, os parâmetros do método devem ser alterados kovan. Vamos adicionar chainIde nonceà transação. E altere o valor para 0,01ETH para distinguir.

let count = await provider.getTransactionCount(wallet_new.address)
let trans = {
    
    
    data:"0x496c6f7665457468657265756d",
    value:ethers.utils.parseEther('0.01'),
    gasLimit:100000,
    nonce: count,
    chainId:ethers.utils.getNetwork('kovan').chainId,
    gasPrice:ethers.utils.parseUnits("3",'gwei'),
    to:"0xDD55634e1027d706a235374e01D69c2D121E1CCb"
}

Aqui está a resposta da transação:
Insira a descrição da imagem aqui
       Como os números 2097 e 2098 noncesão consumidos ao usar valores futuros , o número agora é 2099. Vamos dar uma olhada nos resultados no etherscan:
Insira a descrição da imagem aqui
       você pode ver que a quantidade de ETH enviada é 0,01 ETH e o nonce é 2099. Alguém pode perguntar por que ele não é exibido no etherscan chainId, porque o etherscan é dividido em vários sites com base na mainnet e testnet, e cada site exibe apenas transações em sua própria rede. Por exemplo, o URL real do etherscan que visitei é:

https://kovan.etherscan.io/tx/0x4db8e6b4096d6c27be341b73af99a8d0477e19ba483248c1fdb6fb431fbb3646

       Todas as transações mostradas neste site chainIdsão 42.

Quatro, resumo

       Neste artigo, fornecemos uma introdução detalhada às propriedades específicas do objeto de transação Ethereum criado manualmente. Esses atributos podem ser omitidos, mas não podem ser omitidos (porque não faz sentido omitir todos eles). Os mais comumente usados ​​são to, valuee dataatributos. Nota: Este é apenas um atributo que precisa ser definido ao criar manualmente um objeto de transação no código; se você usar diretamente uma carteira comum (como MetaMask ou Trust wallet), a carteira terá uma interface de IU para ajudá-lo a configurar tudo. No entanto, é necessário esclarecer a base da implementação.Espero que este artigo possa fornecer uma ajudinha aos desenvolvedores do Ethereum.

Você pode deixar uma mensagem para apontar erros ou sugerir melhorias.

Acho que você gosta

Origin blog.csdn.net/weixin_39430411/article/details/104188489
Recomendado
Clasificación