智能合约实践—便签墙

作者: 六天天天向上 | 来源:发表于2019-04-23 22:49 被阅读3次

    今天试用了一下迅雷链推出的智能合约IDE,支持以太坊的EVM和WASM虚拟机。
    今天使用的是EVM合约,整体感觉还不错,支持关键词提示,编译、错误提示,部署等,语法高亮也比较美观,但和Remix比起来没那么强大,不支持debug。
    试用地址:https://catalyst.onethingcloud.com/#/catalyst

    今天在catalyst上写了一个便签墙的智能合约,合约整体思路是:
    便签包括标题和内容,用户可以发布和修改自己便签,管理员可以关闭某些包含敏感词汇的便签,用户可以浏览所有未被关闭的便签。

    合约引用了catalyst编译器提供的Ownable权限合约,Ownable代码如下:

    pragma solidity >=0.4.22 <0.6.0;
    
    contract Ownable {
        address public owner;
    
        event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
        constructor(address _owner) public {
            owner = _owner;
        }
    
        modifier onlyOwner() {
            require(msg.sender == owner, "only owner operate");
            _;
        }
    
        function transferOwnership(address newOwner) public onlyOwner {
            require(newOwner != address(0), "new owner address should not be null");
            emit OwnershipTransferred(owner, newOwner);
            owner = newOwner;
        }
    
    }
    
    

    这个权限合约很简单,声明了一个合约所有者的owner全局地址与修改合约所有者的transferOwnership方法。

    便签墙主合约代码如下:

    pragma solidity >=0.4.22 <0.6.0;
    
    import "./Ownable.sol";
    
    contract NoteWall is Ownable {
        //声明了一个便签结构体
        struct Note {
            string title; //标题
            string content; //内容
            address owner; //便签创建者地址
        }
        //便签数组
        Note[] private notes;
        
        mapping(uint256 => bool) public closedNotes; //被管理员关闭的便签id
        
        //合约是否开启
        bool isopen;
        
        //验证合约是否开启
        modifier onlyOpen() {
            require(isopen == true, "The NoteWall is closed now!");
            _;
        }
        
        //构造函数,传递合约管理员地址,并开启合约
        constructor(address initialAccount) Ownable(initialAccount) public {
            isopen = true;
        }
        
        //修改项目的开启或关闭
        function changeOpen(bool openState) public onlyOwner returns(bool) {
            require(isopen != openState, "Please change the open state");
            isopen = openState;
            return true;
        }
        
        //验证标题长度
        modifier checkTitleLength(string _title) {
            require(bytes(_title).length > 0 && bytes(_title).length <= 60, "Title cannot be empty and less than 20 words");
            _;
        }
        
        //验证内容长度
        modifier checkContentLength(string _content) {
            require(bytes(_content).length > 0 && bytes(_content).length <= 600, "Title cannot be empty and less than 200 words");
            _;
        }
        
        //添加新的便签
        function addNewNote(string _title, string _content) public 
    onlyOpen checkTitleLength(_title) checkContentLength(_content) returns(uint256) {
            uint noteid = notes.length++;
            notes[noteid] = Note({
                title : _title,
                content : _content,
                owner : msg.sender
                });
            return noteid;
        }
        
        //修改自己的便签
        function updateNote(uint256 noteid, string _title, string _content) public 
    onlyOpen checkTitleLength(_title) checkContentLength(_content) returns(bool) {
            Note storage oneNote = notes[noteid];
            require(oneNote.owner == msg.sender, "this is not your note");
            oneNote.title = _title;
            oneNote.content = _content;
            return true;
        }
        
        //返回便签的长度
        function getNoteLength() public view returns(uint256) {
            return notes.length;
        }
        
        //获取便签信息,这里之所以单独写了一个方法而不是把notes数组设置成public,是要屏蔽查看被关闭的便签
        function getNoteInfo(uint256 noteid) public view returns(string, string) {
            require(notes.length >= noteid && closedNotes[noteid] == false, "this note is invisible");
            return(notes[noteid].title, notes[noteid].content);
        }
        
        //只有管理员可操作,关闭某一个便签
        function closeOnedNote(uint256 noteid) public onlyOwner returns(bool) {
            require(notes.length >= noteid && closedNotes[noteid] == false, "this note is invisible");
            closedNotes[noteid] = true;
            return true;
        }
        
    }
    
    

    此合约有几个知识点,需要注意一下:
    1、 string类型是一种特殊的动态数组,是没有length属性的,因此要计算string的长度需要先使用bytes显性转成动态数组。
    2、mapping类型的closedNotes变量,在key不存在的情况下返回0x0000000000000000000000000000000000000000000000000000000000000000

    相关文章

      网友评论

        本文标题:智能合约实践—便签墙

        本文链接:https://www.haomeiwen.com/subject/oqmcbqtx.html