本系列文章是针对 https://blog.csdn.net/weixin_43668031/article/details/83962959 内容的实现所编写的。开发经历包括思考过程、重构和推翻重来。
已经完成了对最快的ipfs网关进行检测,接下去需要本地新建一个ipfs节点和一个eth节点。
eth节点可以使用全节点方式,使用bin文件启动一个全节点进程,去同步日志数据,达到数据完整性的目的,当然在浏览器端这样做肯定不方便,因此我调用web3接口,并且检测浏览器有没有加载MetaMask插件,如果加载了插件就是用插件提供的eth链路,如果没有安装插件,是用公开的ethrpcjson服务,当然这一点,连接怎么样的eth链路用户是可以自己选择的。
我事先定义了一些文件,诸如前文中的gateways.conf,这里我多定义了2个静态文件config.js和ABI,
https://github.com/bill080307/douyinWithEth/blob/8c489f3f9945e42d3650a00c7cabd477c1864589/public/config.js
https://github.com/bill080307/douyinWithEth/blob/8c489f3f9945e42d3650a00c7cabd477c1864589/public/videoShare_abi.js
config.js 文件里的数据我还没有想好是否真正使用js格式,或者使用json格式的配置文件更适合呢?有可能未来会来回变动。
let web3js;
//检查是否开启的插件
if (typeof web3 !== 'undefined') {
//使用插件的ethAPI
web3js = new Web3(web3.currentProvider);
} else {
//使用外置的ethAPI
web3js = new Web3(new Web3.providers.HttpProvider(config["network"][0]["httpApi"]));
}
如果浏览器加载插件,检查web3这个变量就可以了,因为加载插件后在浏览器对象windows.web3, web3js 是web3类的一个实例。
//定义合约
const videoShare = new web3js.eth.Contract(videoShareAbi, config["network"][0]["contractAddress"]);
this.$store.commit('setVideoShare', videoShare);
//检测是否登陆
web3js.eth.getAccounts((error, result) => {
if (result.length > 0) {
this.$store.commit('setUserAccount', result[0]);
this.userAccount.address=result[0];
//获取用户信息
videoShare.methods.getUserInfo(this.userAccount.address).call().then((res) => {
console.log(res)
if(res.nickname!==""){
this.userAccount.nickname=res.nickname;
} else {
this.userAccount.nickname=addressab(this.userAccount.address);
}
console.log(res);
})
}
})
变量videoShare是一个合约实例,并储存在全局变量中,在eth网络这边,也有几种状态:
1.未连接到eth网络中
2.仅仅能获取数据,连接到了eth网络,但是未登录,有可能是通过外部公共jsonrpc连入网络的,也有可能是没有对账号解锁,或者没有新建账号过,读取不到用户。
3.已经有账号了,而且已经解锁状态了,能获取到账号地址。
这几种状态都有不同的特征,不同的权限,这里需要注意一下,后面会用得到的。
我定义了一些助手函数,比如addressab,我觉得eth地址太长了,中间可以用…去缩短一些,这样看上去美观一点。在标示用户的时候可以使用昵称,如果用户没有设置昵称可以用这个地址缩写来表示。
复制编译好的ipfs.js文件到public目录,然后在index.html引入。
创建一个ipfs节点:app.vue
const ipfsNode = new window.Ipfs({
// TODO fix issue with persistance
repo: '/ipfs-' + Math.random(),
config: {
Addresses: {
Swarm: [
'/dns4/ws-star.discovery.libp2p.io/tcp/443/wss/p2p-websocket-star/'
]
}
},
EXPERIMENTAL: {
pubsub: true
}
});
其中repo: '/ipfs-' + Math.random(),
每次都需要新开一个空间,否则会有权限错误,
'/dns4/ws-star.discovery.libp2p.io/tcp/443/wss/p2p-websocket-star/'
是一个libp2p的连接节点,通过他可以连接到其他ipfs节点。
扩展属性里我加了EXPERIMENTAL: {pubsub: true}
初期暂时还用不到,计划在以下场景里使用:
1 观看一个视频时,可以统计有多少人和你一起在看。
2 观看直播(视频)时,发送实时弹幕
接下去就是一个检测,每10秒,输出一下我当前的状态
ipfsNode.once('ready', () => {
console.log("ipfs node ready.");
//每隔10秒输出一下连上的ipfs节点的数量
setInterval(() => {
ipfsNode.swarm.peers((err, peerInfos) => {
if (err) {
throw err
}
if (peerInfos.length > 0) {
console.log(peerInfos.length+" ipfs node Connect.");
}
})
}, 10000)
})
这是控制台,启动节点了,并一直在打印有多少个节点与我建立了连接。可以看到节点数量稳定在35-36个左右,我相信未来会有更多的节点连入,当ipfs的网络更加健壮。
这是网络的信息,可以看到我连接了一个libp2p节点,并通过他我连接到了更多的节点。正在发现并连接到更多的节点。
挖坑:
我一开始采用了nodejs里的IPFS,通过npm install ipfs --save 来完成安装,但是没有跑通。由于我对nodejs并不熟悉,不想再这个地方花太多时间,这里采用了调用别人编译好的ipfs.js足足达到了可怕的2.4M,未来我一定要打好基础,重新使用npm的方式。