Vue项目接入波卡钱包技术指南(一)
前言
1、 什么是波卡链
-
Polkadot 是由以太坊核心开发者推出的第三代公开无需授权的区块链科技,设计核心理念为即时拓展性和延伸性,旨在解决当今两大阻止区块链技术传播和接受的难题。
-
波卡链 Polkadot 是一种异构的多链架构,旨在成为可扩展的异构多链框架,在确保安全和传输的基本功能下,通过非信任节点的激励机制,弱化内生绑定关系。
-
它允许不同区块链以一种无信任成本的方式传输消息、数据、价值的平台。可以同时共享它们的独特功能和安全性。波卡完全灵活并且对网络中链的性质或结构没有任何的定式要求,非区块链系统在满足波卡设计的标准后也可能成为平行链。
2、 Polkadotjs 简介
Polkadotjs是Polkadot官方基于Substrate框架开发的一套JS API框架,API与链上交互的函数是根据链上元数据动态生成。Polkadot-JS系列库可以为任何基于 Substrate 的链创建富客户端应用程序 。
扩展:Substrate 是下一代区块链创新框架。它是一个模块化框架,使你能够通过组合自定义或预构建组件来创建专门构建的区块链。
3、 如何安装波卡钱包
- 安装Polkadot {js} 插件 (波卡钱包插件)
波卡官方开发的浏览器插件钱包,类似以太坊生态里的MetaMask 小狐狸钱包。区别:波卡钱包里无法看到账户余额,也无法进行账户间的转账。插件下载地址:polkadot.js.org/extension/ ,下载完成后,添加到浏览器扩展程序
3、 如何创建波卡账户
(1)创建账户,点击“+”号,选择“Create new account” ,保存好12 位种子短语/助记词(私钥), 以便找回账户。然后点击”Next step”,
- Derive from an accoun / 从一个账户衍生出来:
从现有的账户中创建一个新账户,使用相同的种子短语/助记词(私钥)来创建另一个衍生账户。
- Import account from pre-existing seed / 从已存在的种子导入账户:
使用其他钱包(如 Polkawallet 和 Fearless 钱包)账户的种子短语导入 Polkadot.js。
- Restore account from backup JSON file / 从备份 JSON 文件恢复账户:
另一种恢复账户的方法是使用 JSON 备份文件导入。
(2)设置账户名和密码,然后点击"Add the account with the generated seed / 用生成的种子添加账户"。
(3)创建账户成功,该钱包地址可以用于波卡生态的所有网络。通过选择“Dispaly Address Format For”可以在里面选择不同的链。
只要你在Polkadot {js} 插件中创建了一个帐户(公钥-私钥对),该帐户就可以派生一堆地址,每条基于 Substrate 的链都可以使用一个地址。同一帐户可以有一个用于 Polkadot 的地址,一个用于 Kusama 的地址,另一个可以用于 Acala 的地址。是因为它们都共享相同的私钥和公钥。
冷知识:基于Substrate 的链使用的地址格式是 SS58,它是对比特币使用的 Base-58-check 稍加修改得到的。这个格式包含了地址类型前缀,来表示某个地址属于一个特定的网络。例如:波卡地址以 1 开头,Kusama 地址以大写字母如 C、D、F、G、H、J... 开头,通用的 Substrate 地址以 5 开头。
4、 weby应用安装依赖
1、 安装@polkadot/api
执行yarn add @polkadot/api 下载依赖
2、安装@polkadot/extension-dapp
文档地址:[https://polkadot.js.org/docs/extension](https://polkadot.js.org/docs/extension)<br /> 执行yarn add @polkadot/extension-dapp 下载依赖
5、获取波卡钱包账户
import { stringToHex } from "@polkadot/util";
import { web3Accounts,web3Enable,web3FromSource} from "@polkadot/extension-dapp";
async connectWallet() {
const extensions = await web3Enable("Data tranding market");
if (extensions.length === 0) { // 未安装波卡钱包插件
console.log("Please create cess-hacknet chain account.");
return;
}
let allAccounts = await web3Accounts(); // 获取所有波卡钱包账户
console.log("allAccounts========", allAccounts);
state.accountList = allAccounts;
if (allAccounts.length == 0) { //未创建钱包账户
console.log("Please create account fisrt.");
return;
}
}
6、选择钱包账户并签名
let account = allAccounts[0];
const injector = await web3FromSource(account.meta.source); //web3FromSource方法将返回一个 InjectedExtension 类型
console.log(
"we can use web3FromSource which will return an InjectedExtension type",
injector
);
const signRaw = injector?.signer?.signRaw;
console.log("signRaw=============", signRaw);
if (signRaw) {
await signRaw({
address: item.address,
data: stringToHex(account.address),
type: "bytes",
})
.then((res) => {
console.log("获取签名", res, res.signature.slice(2));
})
.catch((err) => {
console.log(err);
});
}
7、使用波卡钱包实现登录功能实战部分代码片段
连接钱包登录按钮
<div class="login-btn" v-if="!isLogined" @click.stop="authorization()">
<img src="../../assets/icons/logo-icon.png" width="15px" />
Log in
</div>
methods: {
authorization() {
this.$store.dispatch("userInfo/authorization");
}
}
显示所有钱包账户的弹窗
<template>
<div class="menu" ref="menu" >
<div v-if="kind == 'accounts'" class="accounts-title">
<img src="../assets/icons/logo-icon.png" width="15px" />Select Account
<img src="../assets/icons/close-icon2.png" width="22px" class="close-icon" @click="closeMenu"/>
</div>
<ul class="customDropDown" ref="ul" :style="kind == 'normal'? '': 'padding-bottom:40px'" @touchmove.stop>
<li
v-for="(item, index) in items"
:key="index"
@click="item.callback(item);
closeMenu();">
<p :class="item.value ? 'flex' : ''" v-if="kind == 'normal'">
<img :src="item.icon" width="17px" />
<span style="margin-right: 10px">{{ item.text }}</span
><span>{{ item.value }}</span>
</p>
<div v-if="kind == 'accounts'" class="accounts-item">
<img :src="item.icon" width="33px" />
<div>
<div class="accounts-name">{{ item.meta.name }}</div>
<div class="accounts-add">{{ item.address }}</div>
</div>
</div>
</li>
</ul>
</div>
</template>
store/action部分
import { Message } from "element-ui";
import { stringToHex } from "@polkadot/util";
import { web3Accounts, web3Enable, web3FromSource } from "@polkadot/extension-dapp";
async authorization({ commit, state }) {
const extensions = await web3Enable("Data tranding market");
if (extensions.length === 0) {// 未安装波卡钱包插件
state.noExtension = true;
return;
}
let allAccounts = await web3Accounts(); // 获取所有波卡钱包账户
console.log("allAccounts========", allAccounts);
state.accountList = allAccounts;
if (allAccounts.length == 0) {
Message.error("Please create cess-hacknet chain account.");
return;
}
if (state.accountOperator.length == 0) {
state.accountList.forEach((item) => {
console.log("item==========", item);
let obj = {
icon: require("../../assets/icons/default-avater.png"),
meta: item.meta,
address: item.address,
callback: async (item) => {
console.log(item);
state.account = item;
const injector = await web3FromSource(item.meta.source); //web3FromSource方法将返回一个 InjectedExtension 类型
console.log(
"we can use web3FromSource which will return an InjectedExtension type",
injector
);
const signRaw = injector?.signer?.signRaw;
console.log("signRaw=============", signRaw);
if (signRaw) {
await signRaw({
address: item.address,
data: stringToHex(item.address),
type: "bytes",
})
.then((res) => {
console.log("获取签名", res, res.signature.slice(2));
let data = {
myAddress: item.address,
signature: res.signature.slice(2),
account: item,
};
commit("setUserInfo", data);
})
.catch((err) => {
console.log(err);
});
}
},
};
state.accountOperator.push(obj);
});
}
state.accountsVisible = true;
state.userInfoVisible = false;
},
查询钱包账户余额
async queryBanlance() {
let _this = this;
// Create the instance
const wsProvider = new WsProvider("ws://106.15.44.155:9947/");
this.api = await ApiPromise.create({ provider: wsProvider });
console.log(_this.$store.state.userInfo.data.account);
// this call fires up the authorization popup
const extensions = await web3Enable("Data trading market");
if (extensions.length === 0) {
console.log("未安装波卡钱包插件);
return;
}
console.log("extensions", extensions);
// The actual address that we use
const ADDR = this.$store.state.userInfo.data.myAddress;
const acct = await this.api.query.system.account(ADDR); // 查询钱包余额
let free = acct.data.free.toString(10);
let freeBalance = (Number(free) / 1000000000000).toFixed(4);
if (freeBalance > _this.detailData.estimateSpent) {
_this.toBuy(); // 余额大于交易金额 继续后续业务流程
}
}
转载自:https://juejin.cn/post/7148365463896981534