React Native中调用web3(Android)

1,015 阅读2分钟

web3.js是一个库集合,它允许您使用 HTTP、IPC 或 WebSocket与本地或远程以太坊节点进行交互。
我们直接在React native中安装Web3JS的话会抛出各种错误,因为Web3JS有一些依赖关系,它们的核心是浏览器模块。
本篇文章主要介绍怎么在React Native中使用web3这个库,如果您已经具备了指定版本React Native完整原生环境
环境准备:

推荐使用 Linux(ubuntu) 系统。 Windows 系统我试了下是没有问题的

模板创建React Native项目

npx react-native init MyReactNativeDapp --version 0.66.3

cd MyReactNativeDapp

安装依赖包

  1. react-native-crypto模块重新实现了 node 的加密模块,以便它可以在 react-native 支持的环境中运行,并且该模块需要依赖于react-native-randombytes模块才能在React Native中正常工作

npm i --save react-native-crypto react-native-randombytes

npx react-native link react-native-randombytes

  1. 安装rn-nodeify并执行--install为核心节点模块安装 shim.js

npm i --save-dev rn-nodeify@latest

在package.json的scripts中加"hack": "rn-nodeify --install --hack"

npm run hack

npm i --save node-libs-browser base-64

  1. 修改根目录下metro.config.js文件
const extraNodeModules = require('node-libs-browser');
module.exports = {
  resolver: {
    extraNodeModules,
  },
  transformer: {
    getTransformOptions: async () => ({
    transform: {
      experimentalImportSupport: false,
      inlineRequires: false,
    },
   }),
  },
};
  1. 修改shim.js,该文件在刚刚执行npm run hack后会自动生成
import {decode, encode} from 'base-64'

if (!global.btoa) global.btoa = encode
if (!global.atob) global.atob = decode
if (typeof __dirname === 'undefined') global.__dirname = '/'
if (typeof __filename === 'undefined') global.__filename = ''
if (typeof process === 'undefined') {
global.process = require('process')
} else {
const bProcess = require('process')
for (var p in bProcess) {
if (!(p in process)) {
process[p] = bProcess[p]
}
}
}
process.browser = false
if (typeof Buffer === 'undefined') global.Buffer = require('buffer').Buffer
if (typeof location === 'undefined') global.location = { port: 80, protocol: 'https:' }
const isDev = typeof __DEV__ === 'boolean' && __DEV__
process.env['NODE_ENV'] = isDev ? 'development' : 'production'
if (typeof localStorage !== 'undefined') {
localStorage.debug = isDev ? '*' : ''
}
// If using the crypto shim, uncomment the following line to ensure
// crypto is loaded first, so it can populate global.crypto
require('crypto')
  1. 在根目录index.js文件中导入shim.js
import './shim.js'
  1. 安装web3

npm i web3

使用web3

在App.js文件中添加以下代码段

import Web3 from 'web3'

const web3 = new Web3('http://localhost:7545');
const newWallet = web3.eth.accounts.wallet.create(1);
const newAccount = newWallet[0];
console.log(newAccount);

可以看到控制台输出以下内容

{"address": "0x6486EA663f471B60Fc66aa3b9F39b5Fc40e1C395", "encrypt": [Function encrypt], "index": 0, "privateKey": "0x83a5f4a28fd3e21c4d9990b3d50ed08ab8383a48b90dd7283b9d5fff9d2616a1", "sign": [Function sign], "signTransaction": [Function signTransaction]}

如果你使用的是window系统,到这已经可以正常工作了,不过在Ubuntu上会出现报错,内容如下:

screenshot-nimbusweb.me-2022.09.12-16_06_09.png

看了一下react-native-crypto的安装教程,还需要执行npm i --save-dev tradle/rn-nodeifynpm run hack

screenshot-www.npmjs.com-2022.09.12-16_10_40.png

至此,web3可以正常工作了。比较坑的是我在用window尝试的时候出现过几次问题,不过最终可以正常工作。如果有遇到什么问题的话欢迎大家一起交流

参考