【Web3】web3.js库中常用的工具以及查询链上区块、交易

1,665 阅读8分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

前言

上次我介绍了新建 web3 项目的全过程,今天来介绍一下 web3.js 这个库。在学习一个新的工具时我们可以参考二八定律,即只需要掌握这个工具百分之二十的常用 API ,就能胜任大多数情况的开发需求。

接下来我介绍一下 web3.js 提供的一些常用工具,以及使用 JavaScript 代码与区块链上的块(block)和交易(transaction)进行交互。

Web3.js 常用工具

web3.js库中一些封装好的、常用的工具类。

大数据处理

在JavaScript中,默认的数字精度较小。但是对于以太坊而言,内部总是以 wei 作为单位来表示费用。因此在 weiether 单位之间做转换时,JavaScript中默认的数字精度无法确切表示。因此,在Web3.js中,会自动添加一个依赖库 BigNumber

var bigNumber = require('bignumber.js');
  • 在web3.js中,数值会被转换成 BigNumber 的类型:
const bigNumber = require('bignumber.js')

const num = new BigNumber('123456789012345678901234567890')
console.log(num) // BigNumber { s: 1, e: 29, c: [ 12, 34567890123456, 78901234567890 ] }
console.log(num.toString()) // 科学计数法 1.2345678901234567890123456789e+29
console.log(num.toString(10)) // 123456789012345678901234567890
console.log(num.toString(2)) // 1100011101110100100001111111101101100001101110011111000001110111001001110001111110000101011010010
console.log(num.toString(16)) //18ee90ff6c373e0ee4e3f0ad2
  • web3.utils.isBigNumber() 检查给定的参数是否为一个bigNumber对象:
const bigNumber = require('bignumber.js')
const web3 = require('web3')

const num = new bigNumber('123456789012345678901234567890')
console.log(web3.utils.isBigNumber(num))

以太单位转换

  • web3.utils.fromWei() 将给定的以wei为单位的值转换为其他单位的数值。
  • wei是最小的以太单位,应当总是使用wei进行计算,仅在需要显示时进行转换。
// web3.utils.fromWei(String[, unit])
// 单位有:ehter、finney、szabo、shannon

数值转换

  • web3.utils.toHex() 将任意给定值转换为16进制字符串。数值字符串将解释为数值,字符串将解释为utf-8字符串。
web3.utils.toHex('234')

web3.utils.toHex(234)

web3.utils.toHex(new bigNumber('12345678901234567890'))
  • web3.utils.hexToNumberString() 将给定的16进制字符串转化为数值字符串。返回值为 String 类型。
  • web3.utils.hexToNumber() 将给定的16进制字符串转化为数值。返回值为 Number 类型。
  • web3.utils.hexToUtf8() 将给定的16进制值转换为对应UTF-8字符串。
  • web3.utils.asciiToHex() 将给定ASCII码值转换为对应的16进制数值。
  • web3.utils.hexToBytes() 将给定16进制数值转化为对应的Bytes数组。

地址相关

  • web3.utils.isAddress(address) 检查指定的字符串是否是有效的以太坊地址。如果地址同时使用了大小写字符,该方法也会检查校验和。
web3.utils.isAddress('0x123abc45Def67gH...')
// 全部改为大写 true
web3.utils.isAddress('0X123ABC45DEF67GH...')
// 全部改为小写 true
web3.utils.isAddress('0x123abc45def67gh...')
// 去掉 0x 前缀 true
web3.utils.isAddress('123abc45Def67gH...')
// 只改其中某个字符的大小写返回 false
web3.utils/isAddress('0x123Abc45Def67gH...')

查询区块信息

查询最新的区块号(height)

  • web3.eth.getBlockNumber([callback]) 返回当前的块编号。

查询最新区块

  • web3.eth.getBlock(blockNum[,returnTxObj = false , callback]) 返回指定块编号或块哈希对应的块详细信息:

    • blockNum 表示指定的区块,取值可以为:

      • 区块号

      • 区块的hash值

      • 字符串枚举值

        • earlist:创世区块
        • latest:最新区块
        • pending:当前开采区块
    • returnTxObj,可选参数:

      • true:返回块中交易的详细交易信息
      • false:只返回块中交易的hash值

查询区块中的交易

  • web3.eth.getTransactionFromBlock(StringOrHashNumber, indexNum[, callback]) 返回指定块中的交易对象
  • web3.eth.getBlockTransactionCount(blockNum[, callback]) 返回指定地址中的交易个数
web3.eth.getBlockTransactionCount('0x30a499135f2376ed149d50363ca77afb8d162d24df1a92e6dabdcc31028dcba8')
  .then(val => {
    web3.eth.getTransactionFromBlock('0x6faf41c7cb929841548d125519df066c789509c622aac4e051a8303a9d5762a4', val - 1)
      .then(res => {
        console.log(res)
      })
  })

Web3.js 交易

账户相关

  • web3.eth.getAccounts([callback]) 返回当前节点控制的账户列表

image.png

  • web3.eth.personal.newAccount(password[, callback]) 创建一个新账户,返回新账户的hash信息。
  • web3.eth.isMining() 返回当前节点是否正在挖矿。
  • web3.eth.getCoinbase([callback]) 获取当前接收挖矿奖励的账户地址。ganache测试网默认为第一个账户。

交易相关

  • web3.eth.getBalance(address [,defaultBlock, callback) 获取指定块中特定账户地址的余额。
web3.eth.getBalance('0x326C6C15CEca232CB2813D9Af73E647E6dC8B16e')
  .then((res) => {
    const bal = res.toString()
    console.log(web3.utils.fromWei(bal, 'ether'))
  })
  • web3.eth.getGasPrice([callback]) 获取当前的gas价格,该价格由最近的若干块的gas价格中值决定。

交易执行相关

  • web3.eth.sendTransaction(transactionObj[, callback]) 向以太网络提交一个交易。

    • transactionObj

      • from:发送者地址。
      • to(可选):接收者地址。发送的为合约则为空。
      • value:发送的币。
      • gas:gas限制。
      • gasPrice:每个gas的价格。
      • data:若发送的为合约,则为合约的ABI文件。否则为说明信息。
      • noce:账号的前一个交易计数。必须为16进制。
// 从一个账户向另一个账户转1eth
const txObj = {
  from: '0x326C6C15CEca232CB2813D9Af73E647E6dC8B16e',
  to: '0xc46f9f90Bc70aD71e84e67D20806C253f2327907',
  value: web3.utils.toWei('1', 'ether'),
  data: ''
}
web3.eth.sendTransaction(txObj).then(val => console.log(val))

/* 输出结果
{
  transactionHash: '0x23af23ebfc6f74e5ddd4fb629bd2c4d8462e0168f2bddcb4059e7df78ecac5ea',
  transactionIndex: 0,
  blockHash: '0xfb1755fd55b231cc4328aa3803b10e92ab1c20080f099cc69e9a99df0854d72e',
  blockNumber: 5,
  from: '0x326c6c15ceca232cb2813d9af73e647e6dc8b16e',
  to: '0xc46f9f90bc70ad71e84e67d20806c253f2327907',
  gasUsed: 21000,
  cumulativeGasUsed: 21000,
  contractAddress: null,
  logs: [],
  status: true,
  logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
}
*/
  • web3.eth.getTransaction(txHash[,callback]) 返回具有指定哈希值的交易对象。

    • txHash:交易hash

    • 返回值

      • hash-String:交易哈希
      • nonce-Number:发送人在此之前的交易次数。
      • blockHash-Number:所在块的块哈希。打包中的交易其值为 null
      • transactionIndex-Number:该交易在区块中的位置索引。打包中的交易其值为 null
      • from-String:交易发送人地址。
      • to-String:交易接收人地址。
      • value-String:转账金额。以 wei 为单位。
      • gas-Number:由发送人指定的gas数量。
      • gasPrice-String:由发送人指定的gas价格。以 wei 为单位。
      • input-String:伴随交易发送的数据。
  • web3.eth.getTransactionReceipt(hash[, callback]) 查询已经被打包进入区块链的区块信息。

    • 如果交易处于pending状态,返回 null

总结

介绍完了 web3.js 库中常用的一些工具和与查询区块、交易的 API ,接下来我们将编写简单的智能合约并尝试与其交互。