利用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的檢索曠工是訂單匹配,儲存曠工負責儲存文件主體信息。

其餘的改動會在代碼中提現出來,暫時不在這裏一一列舉。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章