利用IPFS构建短视频应用开发经历(五)

本系列文章是针对 https://blog.csdn.net/weixin_43668031/article/details/83962959 内容的实现所编写的。开发经历包括思考过程、重构和推翻重来。

其实上一节中对智能合约的部分代码已经写完,但当我想要开动下一篇幅时,发现这个合约漏洞百出,我还是打算先改掉一些问题再进行下一部分的编写。
1.由于eth对堆栈的限制,像方法的返回的地址长度不能超过16个256bit整数,对函数来说不能返回过多的数据,这一点很头疼,因此部分地方采用了比较隐晦的方法,无法讲所有想输出的变量即使返回出去。

    function getVideo (uint _videoId) view public returns (string memory title, string memory cover, string memory videoinfo, string memory info, uint duration, uint timestamp, address author, uint commentsNum, uint gratuityNum, uint gratuitySum) {
        if (videos[_videoId].permission == 0 || msg.sender == videos[_videoId].author) {
            Video storage _video = videos[_videoId];
            for (uint i = 0; i < _video.gratuityNum; i++) gratuitySum += _video.gratuitys[i].gratuity;
            return (_video.title, _video.cover, _video.videoinfo, _video.info, _video.duration, _video.timestamp, _video.author, _video.commentsNum, _video.gratuityNum, gratuitySum);
        }
    }

比如getVideo我在最近才加上视频长度时间,但是在原先代码10个参数上多加上一个后发现返回参数的地址长度是超过16个256bit整数的,以太坊编译器直接报错CompilerError: Stack too deep, try removing local variables.其中不同的视频轨数量这个值 其实我没必要第一时间去获取到的,所以我这这里去掉了视频轨数量的获取,加上了视频时长的输出。在获取单个视频轨的函数上,会输出这个视频一共有多少个轨道。第一次调用可以采取传入轨道参数=0,因为0轨道是创建视频时就会创建的第一个视频轨,在大部分情况下,有且仅有当视频轨道0时,就不需要再次扫描其他轨道。
在这里我还是要解释一下,Videofile结构体是存放视频文件的地方,更准确的定义应该算是轨道吧,可以是视频轨,可以是音频轨,可以是个字幕文件等等,甚至可以做一些扩展,如互动类脚本也可以作为一个轨存入Videofile结构体。当然目前来说这里放的文件是视频+音频的封装好的轨。

2.在发布函数中添加了发布的视频同步到用户结构体中。

    function publish (string memory _title, string memory _cover, string memory _videoinfo, string memory _info, uint _duration, string memory _filename, string memory _fileinfo, uint _size, uint32 _width, uint32 _height, uint32 _fps) public returns (uint articleId) {
        videos[videoNum++] = Video(_title, _cover, _videoinfo, _info, _duration, now, msg.sender, 0, 0, 0, 0, 0);
        videos[videoNum].videofiles[videos[videoNum].fileNum++] = Videofile(_filename, _fileinfo, _size, _width, _height, _fps, 0);
        users[msg.sender].videos[users[msg.sender].videoNums++] = videoNum - 1;
        return videoNum - 1;
    }

users[msg.sender].videos[users[msg.sender].videoNums++] = videoNum - 1;
这样就可以把用户发布的视频放到用户结构体里。

2.由于eth智能合约的solidity语言目前只能返回固定数量的返回值,列表查询功能和自定义结构还无法做到,需要上层程序辅助来做。比如

        while (num >= this.videoIn - 5 && num >= 0) {
          let cnum = num;
          video.methods.getVideoPreview(num).call().then((res) => {
            this.list.push({
              title: res.title,
              cover: '/ipfs/' + res.cover,
              time: res.timestamp,
              gratuity: res.gratuityNum,
              comment: res.commentsNum,
              videoid: cnum
            });
          });
          num--;
        }

这一点对于习惯使用sql语言的数据库使用者来说难以接受,希望未来eth可以做到。

3.我在这次合约编写的过程中发现一个很严重的问题,我是用字符串来储存ipfs的CID的,用户可以任意提交这些字符串,不管是不是ipfs正确的对象,不管是不是被ipfs所存储,目前这一点无法避免。当然也想过理想化的程序,在eth代码中引入ipfs和filecoin的结构类型,合约添加一个类型即ipfs对象,添加视频文件时对ipfs对象进行验证,这样可以确保合约存储正确的储存对象。eth代码中添加ffmpeg代码,一些用户提交的检索参数让eth自己去获取。
以上2点我是想到了,但是由于水平有限,无法实现。

我这里也有检索旷工和储存旷工的区分,但是和filecoin的检索旷工不一样,我的检索旷工储存了链上数据的索引和交易,储存旷工包括了filecoin的检索旷工和储存旷工。filecoin的检索旷工是订单匹配,储存旷工负责储存文件主体信息。

其余的改动会在代码中提现出来,暂时不在这里一一列举。

原创文章 29 获赞 21 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43668031/article/details/85332930
今日推荐