Day 15【web3.js】一袋米要扛几楼

【前言】
这两天的文章都是 web3.js 的学习笔记,大部分内容都来自他们的官方文件!之後还会有 ethers.js 的学习笔记。然後延伸探讨到底要使用什麽方法来取得 Token Owner 以及 Account Balance 比较好。不过看了越多官方文件就越痛苦,更不用说还要实作…

【web3.js】
we3.js 是一个 JavaScript 的套装 library,里面拥有许多函数或介面可以让开发者利用 HTTP, IPC 或 WebSocket 远端连动以太坊上的节点,进而取得链上讯息、合约资料、帐户资讯。甚至是在取得使用者登入签名後进行交易动作。

下载套件:

npm install web3
yarn add web3

we3.js 的四个重要模组:

  • web3-eth 用於以太坊的区块链以及智能合约
  • web3-shh 用於 **Whisper 通讯协议(Ehtereum’s inter-application communication protocol)**和 在 P2P 对等式网路中连动或播送
  • web3-bzz 用於 Swarm 记帐协议(Swarm Accounting Protocol,SWAP)去中心化的资料储存
  • web3-utils 提供 Dapp 开发者可能会需要用到的功能函数。

因为篇幅有限所以我这几天介绍 web3.js 的文章重点会放在 web3-eth 以及 web3-utils,如果明年我还有参加铁人赛也许会更加详细的介绍这些模组!

如果在支援 MetaMask 的浏览器中有下载 MetaMask,便可以透过 EIP-1193: Ethereum Provider JavaScript API 这项协定来利用 window.ethereum 来达到同样目的!这也是为什麽在我之前【连动 MetaMask】的系列文章之中有透过这个方法得到登入者资料过。

EIP-1193: Ethereum Provider JavaScript API

利用以下的程序码中的 givenProvider 测试是不是已经取得以太坊连动!如果变数 web3 回传 null 的话表示还没连上。

// In Node.js use: const Web3 = require('web3');

const web3 = new Web3(Web3.givenProvider || "ws://localhost:8545");

【we3.eth】
web3-eth 是一个用於以太坊的区块链以及智能合约的模组,我们在取得连动之後就可以透过 getAccounts 取得当前节点的地址资料。

const Web3 = require('web3'); // In Node.js
web3.eth.getAccounts(console.log);
> ["0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe" ,"0x85F43D8a49eeB85d32Cf465507DD71d507100C1d"]

要注意的是透过 we3.js 回传的所有地址资料都是核对和地址(checksum addresses),也就是说里面可能包含一些大写字母以及一些小写字母。如果想要规避错误检测的话可以把整个字串转为小写。之前【连动 MetaMask】的系列文章之中有提到过这篇文章!

How can I check if an Ethereum address is valid?

【we3.eth.accounts】
web3.eth.accounts 做为以太坊帐户的变数型态,可以来核准交易或传递资料。

var Accounts = require('web3-eth-accounts');

// Passing in the eth or web3 package is necessary to allow retrieving chainId, gasPrice and nonce automatically
// for accounts.signTransaction().
var accounts = new Accounts('ws://localhost:8546');

web3.eth.accounts.create([entropy]) 可以产生一个以太坊帐户的物件。

web3.eth.accounts.create([entropy]); // Generates an account object with private key and public key.
// example
web3.eth.accounts.create(web3.utils.randomHex(32));
> {
    address: "0xe78150FaCD36E8EB00291e251424a0515AA1FF05",
    privateKey: "0xcc505ee6067fba3f6fc2050643379e190e087aeffe5d958ab9f2f3ed3800fa4e",
    signTransaction: function(tx){...},
    sign: function(data){...},
    encrypt: function(password){...}
}

Parameters:
entropy - String (optional): 可以使用任意字串来增加乱度,想要使用这个参数的话至少要提供 32 个字元的字串。如果没有的话会自动使用 randomhex() 产生随意字串。
Returns:
Object - 此以太坊帐户物件会包含以下资料结构:

  • address - string: 以太坊帐号地址。
  • privateKey - string: 帐号私钥。为了安全问题,私钥永远不可以被分享或储存在未加密过的储存空间,并且在使用後需要确保这个值是 null 的。
  • signTransaction(tx [, callback]) - Function: 此函数用於签核交易,详细可见 web3.eth.accounts.signTransaction()
  • sign(data) - Function: 此函数用於签核交易,详细可见 web3.eth.accounts.signTransaction()

web3.eth.accounts.wallet 此变数型态可包含已记录的多个以太坊帐户资料,这些帐户可以被用在 web3.eth.accounts.signTransaction()

web3.eth.accounts.wallet;
> Wallet {
    0: {...}, // account by index
    "0xF0109fC8DF283027b6285cc889F5aA624EaC1F55": {...},  // same account by address
    "0xf0109fc8df283027b6285cc889f5aa624eac1f55": {...},  // same account by address lowercase
    1: {...},
    "0xD0122fC8DF283027b6285cc889F5aA624EaC1d23": {...},
    "0xd0122fc8df283027b6285cc889f5aa624eac1d23": {...},

    add: function(){}, 
		// Adds an account using a private key or account object to the wallet.
		// Return The added account(object)
    remove: function(){}, 
		// Removes an account from the wallet.
		// Return a Boolean(true if the wallet was removed)
    save: function(){},
		// Stores the wallet encrypted and as string in local storage.
		// Return a Boolean
    load: function(){},
		// Loads a wallet from local storage and decrypts it.
		// Return The wallet(object)
    clear: function(){},
		// Securely empties the wallet and removes all its accounts.
		// Return The wallet(object)

    length: 2,
}

【we3.eth.personal】
web3-eth-personal 这个套件可以让开发者与以太坊节点的帐户连动,节点的决定由 provider 提供。要注意的是这个套件里面的函数会回传许多敏感资讯像是密码或者私钥!

// or using the web3 umbrella package

var Web3 = require('web3');
var web3 = new Web3(Web3.givenProvider || 'ws://some.local-or-remote.node:8546');

// -> web3.eth.personal
// Warning!! Never call these functions over a unsecured Websocket or HTTP provider, as your password will be sent in plain text!

我们可以利用 setProvider 来设定当前想要的 provider

// Example: Local Geth Node
var web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
// Example: Remote Node Provider
var web3 = new Web3("https://eth-mainnet.alchemyapi.io/v2/your-api-key");

provider 其实就是 we3 如何与区块链联系,也就是一个具有访问以及连动区块链的能力的节点。其会使用一个 JSON-RPC requests 并且回传一个 response。通常会被递交一个 request 给 HTTP 或 IPC socket based server。

web3.eth.personal.sign 此函数可产出 Ethereum 特定的 signature

web3.eth.personal.sign(dataToSign, address, password [, callback])sign
// Warning!! Sending your account password over an unsecured HTTP RPC connection is highly unsecure.

// example
web3.eth.personal.sign(web3.utils.utf8ToHex("Hello world"), "0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe", "test password!")
.then(console.log);
> "0x30755ed65396facf86c53e6217c52b4daebe72aa4941d89635409de4c9c7f9466d4e9aaec7977f05e923889b33c0d0dd27d7226b6e6f56ce737465c5cfd04be400"

Parameters:

  1. String - Data to sign. If String it will be converted using web3.utils.utf8ToHex.
  2. String - Address to sign data with.
  3. String - The password of the account to sign data with.
  4. Function - (optional) Optional callback, returns an error object as first parameter and the result as second.
    Returns:
    Promise returns String - The signature.

web3.eth.personal.getAccounts 会回传一个此节点控制的地址们的阵列。利用 provider 和 calling RPC method personal_listAccounts。使用 web3.eth.accounts.create() 不会在这个 list 里面增加帐号。需要使用 web3.eth.personal.newAccount() 才能达到在 list 里面增加帐号的效果。

web3.eth.personal.getAccounts([callback])

// example
web3.eth.personal.getAccounts()
.then(console.log);
> ["0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe", "0xDCc6960376d6C6dEa93647383FfB245CfCed97Cf"]

此函数和 web3.eth.getAccounts() 的结果是一样的,除非是 calls RPC method eth_accounts。

Returns:
Promise<Array> - 一个此节点控制的地址们组成的阵列。

【小结】
今天就简单介绍了几个 we3.eth.accounts 以及 we3.eth.personal 的相关函数和基本资讯,明天会接续介绍 we3.eth.contractweb3.utis 这两个套件!

【参考资料】
web3.js - Ethereum JavaScript API - web3.js 1.0.0 documentation


<<:  Day 12 docker 安装 nginx 後的细部设定

>>:  [Lesson12] RecyclerView

使用WSL2在Windows下快速打造Linux开发环境(含Docker)

对於习惯使用windows在开发大部分工作的开发者来说,如果想要同时开发适合在Linux-based...

[day15]几个常用的LineAPI

今天Heroku大当机0rz,写一点Line API的使用教学 LineSDK已经将大部分的实作功能...

Day 17 - SwiftUI开发学习1(按钮)

我们统整一下前16天的内容,我们花了很多的时间学习swift语言的基本,学完语言之後我们要开始进入到...

[Day22] Follow Along Links

[Day22] Follow Along Links 需要用到的技巧与练习目标 1.getBound...

DAY30 AI好难,但很好玩

时间过得真快,一转眼三十天就过去了,小编也总算是完成了这个挑战,一路走来其实相当辛苦,会这东西是一回...