今天试用了一下迅雷链推出的智能合约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
网友评论