【Web3技术分享系列专题】- 以太坊的入口,区块链钱包分享
一、区块链钱包行业现状
1.1 市场分析
- DappRadar发布了 2022 年 8 月的报告显示,DApps 活动逐月持续下跌,唯一活跃钱包(UAW,指与给定智能合约交互的唯一地址)已降至 167 万个的最低点,2022 年 8 月,UAW 与上个月相比下跌了 2.53%,与 2021 年 8 月相比也下跌了 14.73%
- 钱包同质化严重,但头部效应也很明显,在安卓设备上最受欢迎的 5 个加密货币钱包(Trust、Metamask、Crypto.com、imToken和 BitPay)累计安装量超过 2000万,远远超过排名靠后的钱包。
- 用户需求多样化,从原来单纯的存储和交易代币,发展到质押投票、流动性挖矿、使用DeFi,收藏和展示NFT,游玩Gamefi,参与Web3建设。
1.2 商业模式分析
基础功能 + 增值服务的商业模式
- 基础功能:收款、转账、查询,Dapp浏览器
- 增值服务:
- 交易及兑换类服务 · 行情资讯服务
- 理财服务 · POS挖矿服务
- 资产聚合类服务 · 社交聊天
- Dapp Store
1.3 钱包分类
1.4 主流钱包对比
二、区块链钱包关键技术
2.1 HD(Hierarchical Deterministic)分层确定性钱包
HD钱包由来:在HD Wallet出现之前,比特币钱包是通过随机数生成互不相关的多个私钥,这种类型的钱包被称作非确定钱包。为了解决非确定性钱包的私钥管理问题,社区成员提出了一种使用“种子”和 哈希函数单向生成一组私钥的方法,并在这种思想的基础上,增加了密钥派生(BIP32)、助记词(BIP39)、派生路径规范(BIP43/44)等功能,形成了现在统一规范的HD wallet。
2.1.1 BIP32
钱包可以看做是一个私钥的容器,按照上面的方法,我们可以生成一堆私钥(一个人也有很多账号的需求,可以更好保护隐私),而每个私钥都需要备份就特别麻烦的,为了解决这种麻烦,就有了BIP32 提议: 根据一个随机数种子通过分层确定性推导的方式得到n个私钥,这样保存的时候,只需要保存一个种子就可以,私钥可以推导出来,大致流程如下:
- 根种子输入到HMAC-SHA512算法中就可以得到一个主私钥(m) 和 一个主链编码
- 上一步生成的密钥(由私钥或公钥)及主链编码再加上一个索引号,将作为HMAC-SHA512算法的输入继续衍生出下一层的私钥及链编码
推导过程是确定(相同的输入,总是有相同的输出)也是单向的,子密钥不能推导出同层级的兄弟密钥,也不能推出父密钥。如果没有子链码也不能推导出孙密钥。
2.1.2 BIP39
BIP39使用助记词的方式生成种子,这样用户只需要记住12(或24)个单词,通过 PBKDF2 与 HMAC-SHA512 函数创建出随机种子作为 BIP32 的种子。
助记词生成:先生成一个128位随机数,再加上对随机数做的校验4位,得到132位的一个数,然后按每11位做切分,这样就有了12个二进制数,然后用每个数去查BIP39定义的单词表,这样就得到12个助记词。
助记词推导出种子:使用PBKDF2函数把助记词明文和盐值作为输入参数,然后重复进行运算最终产生生成一个更长的(512 位)密钥种子,再构建一个确定性钱包并派生出它的密钥。
2.1.3 BIP44
BIP44为秘钥路径约定了一个规范的含义(也扩展了对多币种的支持),指定了包含5个预定义树状层级的结构:
m / purpose' / coin' / account' / change / address_index
m是固定的, purpose也是固定的,值为44
coin type:这个代表的是币种,0代表比特币,1代表比特币测试链,60代表以太坊,完整的币种列表地址:https://github.com/satoshilabs/slips/blob/master/slip-0044.md
account:代表这个币的账户索引,从0开始
change:常量0用于外部(收款地址),常量1用于内部(也称为找零地址)。外部用于在钱包外可见的地址(例如,用于接收付款)。内部链用于在钱包外部不可见的地址,用于返回交易变更。 (所以一般使用0)
address_index:这就是地址索引,从0开始,代表生成第几个地址,官方建议,每个account下的address_index不要超过20
助记词生成以太坊地址示例:
var bip39 = require('bip39’)
var hdkey = require('ethereumjs-wallet/hdkey’)
var util = require('ethereumjs-util’)
var seed = bip39.mnemonicToSeed(mnemonic, "pwd");
var hdWallet = hdkey.fromMasterSeed(seed);
var key1 = hdWallet.derivePath("m/44'/60'/0'/0/0");
console.log("私钥:"+util.bufferToHex(key1._hdkey._privateKey));
var address1 = util.pubToAddress(key1._hdkey._publicKey, true);
console.log("地址:"+util.bufferToHex(address1));
2.2 Web3Auth原理简介 - Torus钱包
Web3Auth是用于Web3钱包和应用程序的身份验证基础架构,支持Web和移动原生平台上主流社交登录(谷歌、Twitter、GitHub、微信等),用户不需要保存记录冗长的助记词,减少了用户由于助记词丢失造成资产损失的情况。同时Web3Auth架构保证用户完整加密私钥不会记录在密钥基础架构系统的任何地方。
目前已在Binance Extension Wallet、Ubisoft、Kukai、Skyweaver等钱包和应用程序上保护了每月超过100万用户和800万密钥。
用户私钥被拆分三个share,与现有的2FA系统类似,用户需要证明至少拥有3份秘密中的2份,以便检索并组装成用户的私钥。三个share如下:
- Social Login Share:加密存储在Web3Auth Auth Network中,与用户社交账号关联检索。
- Trusted Device Share:存储在用户可信的设备上,可以是浏览器本地存储或者Dapp应用上下文中。
- Recovery Share:由用户保留的额外共享,可以保存在单独设备上。
优势 | 弊端 |
|
|
2.3 WalletConnect原理简介
WalletConnect是一个开源项目,是基于⼆维码建立连接的基础通讯设施,主要解决使用移动端钱包登录PC端Dapp问题。Dapp登录期间虽然获取到了钱包地址,但私钥始终安全地存储在我们的移动设备上,Dapp上进行的每笔交易都需要我们通过移动端钱包软件进行额外的手动确认。WalletConnect 只是⼀套加密的通讯协议,具体传输信息由Dapp和Wallet决定。
详细交互流程如下:
三、以太坊钱包开发
3.1 以太坊钱包开发常用开源库
3.1.1 开源库1 keythereum
示例1 生成keystore并存储
var keythereum = require("keythereum");
var params = { keyBytes: 32, ivBytes: 16 };
var dk = keythereum.create(params);
keythereum.create(params, function (dk) {
var password = "wheethereum";
var kdf = "pbkdf2";
var options = {
kdf: "pbkdf2",
cipher: "aes-128-ctr",
kdfparams: {
c: 262144,
dklen: 32,
prf: "hmac-sha256"
}
};
keythereum.dump(password, dk.privateKey, dk.salt, dk.iv, options, function (keyObject) {
keythereum.exportToFile(keyObject);
});
});
示例2 导入keystore
var datadir = "/home/jack/.ethereum-test";
var keyObject = keythereum.importFromFile(address, datadir);
console.log(keyObject)
keythereum.importFromFile(address, datadir, function (keyObject) {
console.log(keyObject)
});
示例3 从keystore中恢复私钥
var privateKey = keythereum.recover(password, keyObject);
console.log(privateKey)
keythereum.recover(password, keyObject, function (privateKey) {
console.log(privateKey)
});
3.1.2 开源库2 ethereumjs-tx
示例4 交易签名
const transaction = require('ethereumjs-tx’);
var rawTx = {
nonce:'0x' + transactionNonce,
gasPrice: '0x5208',
gas:'0x4a817c800', //+ oxgasFeeToWei,
to: '0x' + toAddress,
value:'0x' + oxNumBalance,
data: '',
chainId: 1
};
var tx = new transaction(rawTx);
tx.sign(privateKey);
var serializedTx = tx.serialize();
if serializedTx == null {
console.log("Serialized transaction fail")
} else {
console.log("The sender address is " + tx.getSenderAddress().toString('hex'));
if (tx.verifySignature()) {
console.log('Signature Checks out!')
} else {
console.log("Signature checks fail")
}
}
3.1.3 开源库3 web3库
示例5 web3.js初始化Provider
var Web3 = require("web3");
if (typeof web3 !== 'undefined')
{
web3 = new Web3(web3.currentProvider);
} else {
web3 = new Web3(new Web3.providers.HttpProvider("http://10.23.1.209:8545"));
}
示例6 获取账户余额
web3.eth.getBalance("0x68db18a9cd87403c39e84467b332195b43fc33b5", function(err, result)
{
if (err == null)
{
console.log('~balance Ether:' +web3.fromWei(result, "ether"));
} else {
console.log('~balance Ether:' + web3.fromWei(result, "ether"));
}
});
示例7 发起交易
web3.eth.sendRawTransaction('0x' + serializedTx.toString('hex'), function(err, hash) {
if (!err)
{
console.log(“hash:” + hash);
} else {
console.log(err);
}
});
3.1.4 开源库4 blockchain-wallet-sdk
示例8 创建助记词并生成以太坊地址
var mnemonicS = require("../sdk/mnemonic/generateWord");
var address = require("../sdk/address/generateAddress");
var mnemonic= mnemonicS.createHelpWord(12, 'english');
var seed = mnemonicS.mnemonicToSeed(mnemonic);
var addressParmas = {
"seed":seed,
"coinType":"ETH",
"number":"0",
"bipNumber":"60",
"receiveOrChange":“0",
"coinMark":"ETH"
}
var addr = address.blockchainAddress(addressParmas);
console.log(addr);
示例9 单笔转账签名
const testEthSign = require('../sdk/sign/ethereumSign');
var privateKey = "a2506976294fc506f6969e8f914ae9371804b104163f07e8d0e96794d5b43189";
var nonce = 78;
var toAddress = "0xe558be4e90b2ac96ae5cad47dc39cd08316f2e57";
var gasPrice = 9000000000;
var gasLimit = 120000;
var sendToBalance = 10;
var signValue = testEthSign.ethereumSign(privateKey, nonce, toAddress, sendToBalance, gasPrice, gasLimit);
console.log(signValue);
3.2 开源钱包TrustWallet - Android源码分析
Github地址:https://github.com/trustwallet/trust-wallet-android-source
依赖的Ethereum相关开源包
主要目录结构:
四、区块链钱包未来发展
当前区块链钱包行业存在的困境:同质化严重,在任何一款钱包都能满足用户基本需求的时候,就都失去了用户粘性;区块链的“去中心化”特性,使得用户的钱包账号以及相关数据是完全互通的,无信息壁垒;以下是针对金融属性和互联网属性两个方面简单分析了区块链钱包未来发展方向。
本文参考或涉及到的网站或链接:
https://github.com/satoshilabs/slips/blob/master/slip-0044.md
https://web3auth.io/docs/overview/what-is-web3auth
https://github.com/Web3Auth/web3auth-web
https://github.com/WalletConnect
https://github.com/trustwallet/trust-wallet-android-source
- 点赞
- 收藏
- 关注作者
评论(0)