React Native DApp 开发全栈实战·从 0 到 1 系列(钱包、发布Token)

  • 木西
  • 发布于 6天前
  • 阅读 632

前言本文全面解析加密钱包从创建到上链的完整闭环:钱包生成:助记词、私钥、地址的派生与恢复链上交互:余额查询、签名、转账、合约部署资产发行:一键创建ERC-20同质化代币、ERC-721非同质化资产实现钱包创建和导入的实现实现核心说明:主要借助Ethers实现创建随机钱包和导

前言

本文全面解析加密钱包从创建到上链的完整闭环:

  • 钱包生成:助记词、私钥、地址的派生与恢复
  • 链上交互:余额查询、签名、转账、合约部署
  • 资产发行:一键创建 ERC-20 同质化代币、ERC-721 非同质化资产

实现钱包创建和导入的实现

实现核心说明:主要借助Ethers实现创建随机钱包和导入现有钱包

  • 创建钱包核心代码

<!---->

# 创建随机钱包
import { ethers } from "ethers";
const wallet = ethers.Wallet.createRandom();
console.log("创建钱包地址:",wallet.address)
console.log("创建钱包助记词:",wallet.mnemonic)
console.log("创建钱包私钥:",wallet.privateKey)
  • 导入钱包核心代码

<!---->

import { ethers } from "ethers";
# 助记词
const mnemonic=""//助记词
const walletmnemonic = ethers.Wallet.fromPhrase(mnemonic);
# 私钥
const privateKey=""//私钥
const wallet = new ethers.Wallet(privateKey)
console.log("创建钱包地址:",wallet.address)
  • 钱包方法说明
分类 方法 / 属性 说明 示例
创建 Wallet.createRandom() 生成随机钱包(新私钥 + 助记词) Wallet.createRandom()
Wallet.fromPhrase(mnemonic, path?, wordlist?) 从助记词恢复(默认路径 m/44'/60'/0'/0/0) Wallet.fromPhrase('apple …')
new Wallet(privateKey) 从私钥构造钱包 new Wallet('0x1234…')
Wallet.fromEncryptedJson(json, password) 从 keystore V3 解密钱包 Wallet.fromEncryptedJson(json, pw)
Wallet.fromEncryptedJsonSync(json, password) 同步版本(文件小可用) 同上
属性 wallet.address 钱包地址(EIP-55 校验和) wallet.address
wallet.publicKey 未压缩公钥(0x04…) wallet.publicKey
wallet.privateKey 私钥(0x…) wallet.privateKey
wallet.mnemonic 助记词对象(.phrase 取出字符串) wallet.mnemonic.phrase
签名 wallet.signMessage(message) 对字符串/字节签名 wallet.signMessage('hello')
wallet.signTransaction(tx) 对交易对象签名 wallet.signTransaction(tx)
wallet.signTypedData(domain, types, value) EIP-712 结构化签名 wallet.signTypedData(…)
发送 wallet.sendTransaction(tx) 签名并广播交易 wallet.sendTransaction(tx)
连接 Provider wallet.connect(provider) 返回带有 Provider 的新钱包实例 wallet.connect(provider)
加密 / 导出 wallet.encrypt(password, options?) 导出 keystore V3 JSON wallet.encrypt('mypw')

如果需要了解更多关于Ethers的内容可以查看作者的另外两篇文章《ethers.js 全栈开发实战:从 Provider 到 Utils 的 6 大核心模块深度解析》《基于 ethers.js 的区块链事件处理与钱包管理实践指南》

特别说明:React Native 构建app和PC端在使用Ethers时需要在入口文件(index.tsx)中导入import 'react-native-get-random-values';组件才能正常使用

创建代币

实现核心说明:借助solidity和openzeppelin编写合约代码,通过ethers调用合约

  • ERC20代币核心代码

    // SPDX-License-Identifier: MIT
    // Compatible with OpenZeppelin Contracts ^5.0.0
    pragma solidity ^0.8.22;
    import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
    import {ERC20Burnable} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
    import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
    import "hardhat/console.sol";
    contract MyToken is ERC20, ERC20Burnable, Ownable {
    constructor(string memory name_,string memory symbol_,number memory amount_,string memory address initialOwner)
        ERC20(name_, symbol_,amount_,)
        Ownable(initialOwner)
    {
        _mint(msg.sender, amount_ * 10 ** decimals());
    }
    
    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }
    }
  • 部署合约
    # 借助hardhat部署
    module.exports = async  ({getNamedAccounts,deployments})=>{
    const getNamedAccount = (await getNamedAccounts()).firstAccount;
    const TokenName = "BoykayuriToken";
    const TokenSymbol = "BTK";
    const {deploy,log} = deployments;
    const Token=await deploy("MyToken",{
        from:getNamedAccount,
        args: [TokenName,TokenSymbol,getNamedAccount],//根据参数不同调整
        log: true,
    })
    // await hre.run("verify:verify", {
    //     address: TokenC.address,
    //     constructorArguments: [TokenName, TokenSymbol],
    //     });
    console.log('合约地址',TokenC.address)
    }
    module.exports.tags = ["all", "token"];
  • 关于合约编译、部署、测试:可以参考作者写的另一篇文章《 智能合约开发、测试、部署全流程(实操篇)》,《web3相关知识分享》专栏中也有大量的案例供参考
  • Ethers调用合约
    
    import { ethers } from 'ethers';

// 1. 配置 const RPC_URL = 'https://sepolia.infura.io/v3/&lt;YOUR_INFURA_KEY>';//可以通过注册infura获取YOUR_INFURA_KEY const PRIVATE_KEY = '0x你的私钥'; // 测试钱包的私钥

// 2. 合约字节码 & ABI const bytecode = '0x608060405234801561001057600080fd5b50...'; // Remix 编译后复制 const abi = [];//可以通过编译生成json文件中取

// 3. 连接 const provider = new ethers.JsonRpcProvider(RPC_URL); const wallet = new ethers.Wallet(PRIVATE_KEY, provider);//可操作

// 4. 部署 async function deploy() { const factory = new ethers.ContractFactory(abi, bytecode, wallet);//合约地址 const contract = await factory.deploy( 1_000_000, // 发行 100 万枚 { gasLimit: 2_000_000 } ); await contract.waitForDeployment(); console.log('合约地址:', contract.target); } await deploy();


# 创建NFT
**说明**:基本同创建ERC20代币合于大同小异,主要的区别在IPFS存储部分,
关于NFT合约部分可以参考作者的另一篇文章
[《快速实现一个标准的NFT合约(实操篇)》](https://learnblockchain.cn/article/11241)
# 效果图
&lt;div style="display:flex,">
&lt;img src="https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/72ca609580c2473a8fc9ffb454e59d02~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5pyo6KW_:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMjQzNjE3MzQ5Njg0NTU0OSJ9&rk3s=f64ab15b&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1755703612&x-orig-sign=jIkCmztHo94aAnYFxBX%2FxLNXDqc%3D" width="200" alt="图8转存失败,建议直接上传图片文件">
&lt;img src="https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/ca8ac6dace8d457b90f1a69213c22612~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5pyo6KW_:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMjQzNjE3MzQ5Njg0NTU0OSJ9&rk3s=f64ab15b&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1755703612&x-orig-sign=4ijNC4oimiSMihTgwvzapnHwrMU%3D" width="200" alt="图1">
&lt;img src="https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/07e65c8de8644706b1a273e7eb0e7012~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5pyo6KW_:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMjQzNjE3MzQ5Njg0NTU0OSJ9&rk3s=f64ab15b&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1755703612&x-orig-sign=XkRact42cwGMyRUNbQwD8ol5Za4%3D" width="200" alt="图6">
&lt;img src="https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/3e5099f1ce2e41f8af9c13d1dfc03b9c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5pyo6KW_:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMjQzNjE3MzQ5Njg0NTU0OSJ9&rk3s=f64ab15b&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1755703612&x-orig-sign=0nXNqLeU0q%2FwSgD725RRnn4FYCI%3D" width="200" alt="图7">
&lt;img src="https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/e34ae29d61b94620afd8dec4eadac120~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5pyo6KW_:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMjQzNjE3MzQ5Njg0NTU0OSJ9&rk3s=f64ab15b&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1755703612&x-orig-sign=c606GrCXsE0mS09s1%2BaZJtJ67%2B0%3D" width="200" alt="图5">
    &lt;img src="https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/e4d8ee2b717444968ffc3791209f3d00~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5pyo6KW_:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMjQzNjE3MzQ5Njg0NTU0OSJ9&rk3s=f64ab15b&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1755703612&x-orig-sign=FrDTnscfCD3nllIbxuCXpiUQ3ug%3D" width="200" alt="图4">
&lt;img src="https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/43ccd6bd9625480dbcd9dda71e3ec396~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5pyo6KW_:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMjQzNjE3MzQ5Njg0NTU0OSJ9&rk3s=f64ab15b&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1755703612&x-orig-sign=JEI4l%2BNk99pQOLhtuY0NpvNagJk%3D" width="200" alt="图3">
&lt;/div>

# 总结
至此,你已掌握加密钱包的完整生命周期:  
从「随机生成 / 助记词恢复」到「私钥-地址派生」,再到「签名、发送交易」。  
更进一步,凭借这些密钥即可在链上 **一键部署并发行** ERC-20 同质化代币或 ERC-721 非同质化资产,实现资产的确权与自由流转。
点赞 0
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
木西
木西
0x5D5C...2dD7
江湖只有他的大名,没有他的介绍。