矩阵元区块链智能合约开发指南

1 适用范围

本规范描述了矩阵元区块链系统智能合约的开发约束与规范,用以指导DAPP开发者按照本规范开发基于矩阵元区块链运行的应用。

2 术语解释

术语 术语解释
DAPP 去中心化应用
Truffle 智能合约开发IDE

3 Quick Start

本章节描述一个简单的智能合约开发样例,用以描述基于矩阵元区块链的智能合约开发标准与规范。给DAPP应用的开发提供参考。

3.1 合约功能描述

此合约开发用例用来管理学生数据,并给不同用户分配不同的数据处理权限,实现数据

的访问控制。

3.2 合约规划与列表说明

3.2.1 合约存储规划

学生数据在合约的存储属性为:

id 学生id(对应于钱包地址)
name 学生名字
classId 学生所属班级id
status 标记学生数据是否开除: 0 未开除 1 已开除

3.2.2 合约接口规划

//新增学生
func addStudent(string _studentJson) public returns{}; //开除学生
func deleteStudentById0(string id) public{}; //根据Id查询用户
func findStudentById(string id) constant public returns{};

3.2.3 合约权限规划

角色列表 角色具有的权限
校长 deleteStudentById, addStudent, findStudentById
班主任 addStudent, findStudentById
学生 findStudentById

3.2.4 合约文件规划

LibStudent.sol: 学生的数据结构合约;

StudentManager.sol: 实现对学生数据的各种处理;

ModuleManager.sol: 实现对合约、角色、权限的模块化处理。

3.3 合约代码样例

LibStudent.sol:

pragma solidity ^0.4.2;

import "LibInt.sol";
import "LibString.sol";
import "LibJson.sol"; library LibStudent {
using LibJson for *;
using LibString for *;
using LibInt for *;
using LibStudent for *; //引入库的语法 //student对象结构体
struct Student{
address id; //学生Id
string name; //学生名称
string classId; //学生班级Id
uint status; //学生状态 0 未开除 1 开除
} //将student对象转换成json字符串
function toJson(Student storage _self) internal returns(string _strjson){
_strjson = "{";
string memory strAddr = "0x";
strAddr = strAddr.concat(_self.id.addrToAsciiString());
_strjson = _strjson.concat(strAddr.toKeyValue("id"), ",")
_strjson = _strjson.concat(_self.name.toKeyValue("name"), ",");
_strjson = _strjson.concat(_self.classId.toKeyValue("classId"), ",");
_strjson = _strjson.concat(uint(_self.status).toKeyValue("status"), " ");
_strjson = _strjson.concat("}");
} //从student的json字符串中提取相应值
function fromJson(Student storage _self, string _stuJson) internal returns(bool) {
_self.clear(); string memory strAddr = _stuJson.getStringValueByKey("id");
strAddr = _stuJson.getStringValueByKey("id");
_self.id= strAddr.toAddress();
_self.name = _stuJson.jsonRead("name");
_self.classId= _stuJson.jsonRead("classId");
_self.status = _stuJson.jsonRead("status").toUint();
return true;
} //将student对象置空
function clear(Student storage _self) internal {
_self.id= address(0);
_self.name = "";
_self.classId= "";
_self.status = 1;
} //重置student对象
function reset(Student storage _self) internal {
clear(_self);
_self.clear();
}
}

StudentManager.sol:

pragma solidity ^0.4.2;

import "LibStudent.sol";
import "LibString.sol";
import "LibInt.sol"; contract StudentManager { using LibStudent for *;
using LibString for *;
using LibInt for *; //引入所需库合约 event Notify(uint _errno, string _info); //定义事件处理 //此mapping对象将地址映射到对象本身
mapping(address=>LibStudent.Student) studentMap;
address[] addrList;
address[] tempList; LibStudent.Student internal student;
string[] tmpArray; //错误码定义
enum StudentError {
NO_ERROR,
BAD_PARAMETER,
NAME_EMPTY,
CLASS_NOT_EXISTS,
STUDENT_NOT_EXISTS
} uint errno = 0; //构造函数
function StudentManager() {
} //新增学生
function addStudent(string _studentJson) public returns(uint) {
log("insert", "StudentManager"); if (student.fromJson(_studentJson) == false) {
log("insert bad json", "StudentManager");
errno = 9000 + uint(StudentError.BAD_PARAMETER);
Notify(errno, "insert bad json");
return errno;
} if (student.name.equals("")) {
log("student name is invalid", "StudentManager");
errno = 9000 + uint(StudentError.NAME_EMPTY);
Notify(errno, "student name is invalid");
return errno;
} if (student.classId.equals("")) {
log("student classId is invalid", "StudentManager");
errno = 9000 + uint(StudentError.CLASS_NOT_EXISTS);
Notify(errno, "student classId is invalid");
return errno;
} student.status = uint(0); studentMap[student.id] = student;
addrList.push(student.id); errno = uint(StudentError.NO_ERROR); log("add a student succcess", "StudentManager");
Notify(errno, "insert a student succcess");
student.reset();
return errno;
} //根据学生Id查找学生
function findStudentById(address _id) constant public returns(string _ret) {
_ret = "{\"ret\":0,\"data\":{"; if (studentMap[_id].status != 1) {
_ret = _ret.concat(studentMap[_id].toJson());
} else {
_ret = _ret.concat(""));
}
_ret = _ret.concat("}}");
} //根据学生Id删除学生
function deleteStudentById(address _id) public { if (studentMap[_id].status == 1) {
log("student not exists: ", _id);
errno = 9000 + uint(StudentError.STUDENT_NOT_EXISTS);
Notify(errno, "student not exists");
return;
}
delete tempList;
for (uint i = 0; i < addrList.length; i++) {
if(_id == studentMap[addrList[i]].id) {
continue;
}
else {
tempList.push(addrList[i]);
}
} delete addrList;
for (uint j = 0; j < tempList.length; ++j) {
addrList.push(tempList[j]);
} studentMap[_id].status = 1;
Notify(errno, "fire student success");
}
}

ModuleManager.sol:

pragma solidity ^0.4.2;

import "LibModule.sol";
import "LibContract.sol";
import "BaseModule.sol"; contract ModuleManager is BaseModule{ //构造module对象
LibModule.Module tmpModule; //构造contract对象
LibContract.Contract tmpContract; //构造函数,发布入链即自动执行
func ModuleManager(){
register("ModuleManager","0.0.1.0");
tmpModule.reset();
string[] memory tmpArr; tmpModule = LibModule.Module({moduleId:"systemModule001",moduleName:"系统模块",moduleVersion:"0.0.1.0",deleted:false,moduleEnable:1,moduleDescription:"系统模块管理",moduleCreateTime:nowTime,moduleUpdateTime:nowTime,moduleCreator:msg.sender,contractIdList:tmpArr,roleIds:tmpArr});
addModule(tmpModule); //添加此模块
initContractData(); //添加合约
initActionData(); //添加权限
initRoleData(); //添加角色 } //添加合约数据
func initContractData() private returns(uint){
address userAddr = rm.getContractAddress("UserManager","0.0.1.0");
tmpContract.moduleId = sysModuleId;
tmpContract.cctId = innerContractMapping["UserManager"];
tmpContract.cctName = "用户管理";
tmpContract.cctVersion = "0.0.1.0";
tmpContract.deleted = false;
tmpContract.enable = 1;
tmpContract.description = "用户管理合约";
tmpContract.createTime = nowTime;
tmpContract.updateTime = nowTime;
tmpContract.creator = msg.sender;
tmpContract.cctAddr = userAddr;
addContract(tmpContract.toJson());
return 1;
} //添加权限数据
func initActionData() private returns(uint){
string memory actionStr = ""; //权限数据对象
jsonStr="{\"id\":\"action1000\",\"moduleId\":\"module001\",\"name\":\"addStudent\",\"resKey\":\"StudentManager\",\"opKey\":\"addStudent(string)\"}";
addAction(jsonStr);
jsonStr="{\"id\":\"action1001\",\"moduleId\":\"module001\",\"name\":\"findStudentById\",\"resKey\":\"StudentManager\",\"opKey\":\"findStudentById(string)\"}";
addAction(jsonStr);
jsonStr="{\"id\":\"action1002\",\"moduleId\":\"module001\",\"name\":\"deleteStudentById\",\"resKey\":\"StudentManager\",\"opKey\":\"deleteStudentById(string)\"}";
addAction(jsonStr);
return 1;
} //添加角色数据
func initRoleData() private returns(uint){
string memory roleJsonStr=""; //角色数据对象
roleJsonStr="{\"id\":\"role1000\",\"name\":\"校长\",\"status\":1,\"moduleId\":\"systemModule001\",\"actionIdList\":[\"action1000\",\"action1001\",\"action1002\"]}";
addRole(roleJsonStr);
roleJsonStr="{\"id\":\"role1001\",\"name\":\"班主任\",\"status\":1,\"moduleId\":\"systemModule001\",\"actionIdList\":[\"action1000\",\"action1001\"]}";
addRole(roleJsonStr);
roleJsonStr="{\"id\":\"role1002\",\"name\":\"学生\",\"status\":1,\"moduleId\":\"systemModule001\",\"actionIdList\":[\"action1001\",]}";
addRole(roleJsonStr);
return 1;
}
}

3.4 合约编译发布

3.4.1 前提要求

本地矩阵元区块链平台已经启动运行。

矩阵元区块链平台搭建请参考《矩阵元区块链环境安装部署》文档;

本地已搭建好Truffle环境。

Truffle编译发布环境搭建请参考《矩阵元区块链Truffle环境搭建》文档。

3.4.2 合约编译与发布

1)Truffle环境初始化

新建合约目录DAPP
在新建的合约目录DAPP下执行truffle init初始化目录结构 修改truffle.js文件中RPC地址为平台地址
删除示例合约ConvertLib.sol,MetaCoin.sol,Migrations.sol

2)上传应用智能合约

将编写的上述智能合约上传到truffle init生成目录结构下的contract中

3)合约编译

在新建的Dapp目录下执行命令truffle compile完成合约的编译

4)合约发布

修改部署配置文件:
在migrations目录下修改migrations/1_initial_migration.js
注释掉deployer.deploy(Migrations); 在migrations目录下修改migrations/2_deploy_contracts.js
添加自己要发布的合约,例:
module.exports = function(deployer) {
deployer.deploy(StudentManager);
deployer.deploy(ModuleManager);
}; 在新建的Dapp目录下执行命令truffle migrate完成合约的发布。

3.4.3 合约测试

进入truffle控台: truffle console

实例化待测合约对象,如StudentManager.sol

> var stu = StudentManager.deployed();
undefined

或者:

> var stu = StudentManager.at(“0x002b4f09741a896e757f276d8f5f0c24bca870bf”);
undefined

注:该处此地址为合约发布时输出的对应地址。

调用合约函数:

> stu.addStudent(‘{“id”: “0x006d8f5f0c24bca870bf2b4f09741a896e757f27”, “name”: “juzix”,     “classId”: “SuperClass”,“status”: 0}’);
“0x00aa1676c77bb7861ef115652715671880aa1677”
> stu.findStudentById(“0x006d8f5f0c24bca870bf2b4f09741a896e757f27”);
‘{“id”: “0x006d8f5f0c24bca870bf2b4f09741a896e757f27”, “name”: “juzix”, “classId”: “SuperClass”,“status”: 0}’
> stu.deleteStudentById(“0x006d8f5f0c24bca870bf2b4f09741a896e757f27”);
“0x5652715671880aa00aa1676c77bb7861ef11ba21”

4 系统合约接口说明

系统Library库合约以及系统合约接口说明请参考智能合约开发指南_矩阵元区块链文档

4.3 系统角色与权限说明

系统内置四种角色以及每个角色对应的权限,分别为:节点管理员、链管理员、系统管理员、权限管理员,每个角色为相关合约下的所有接口,四大角色所有权限如下:

角色名称 节点管理员
角色权限 权限描述 四大合约权限以及节点信息管理权限
所有权限 UserManager, DepartmentManager, ActionManager, RoleManager, NodeInfoManager
角色名称 链管理员
角色权限 权限描述 四大合约权限、链文件以及节点申请权限
所有权限 UserManager, DepartmentManager, ActionManager, RoleManager, NodeApplyManager, FileInfoManager, FileServerManager
角色名称 系统管理员
角色权限 权限描述 四大合约权限以及系统配置权限
所有权限 UserManager, DepartmentManager, ActionManager, RoleManager, SystemConfig
角色名称 权限管理员
角色权限 权限描述 机构、用户、角色权限管理员,四大合约权限以及权限控制
所有权限 UserManager, DepartmentManager, ActionManager, RoleManager, RoleFilterManager

5 合约业务开发流程介绍

使用智能合约开发业务,需按照以下5个步骤进行:

1)完成合约基础数据的处理;

2)实现注册合约;

3)定义业务数据的结构,并实现对业务数据的处理;

4)根据接口文档实现业务合约的业务逻辑;

5)模块化管理。

流程详情请参考智能合约开发指南_矩阵元区块链文档

truffle框架快速开发合约步骤的更多相关文章

  1. 使用 CodeIgniter 框架快速开发 PHP 应用(三)

    原文:使用 CodeIgniter 框架快速开发 PHP 应用(三) 分析网站结构既然我们已经安装 CI ,我们开始了解它如何工作.读者已经知道 CI 实现了MVC式样. 通过对目录和文件的内容进行分 ...

  2. 使用 CodeIgniter 框架快速开发 PHP 应用(七)

    原文:使用 CodeIgniter 框架快速开发 PHP 应用(七) CodeIgniter 和对象这是玩家章节.它讲述的是 CodeIgniter 的工作原理,也就是揭开CI头上'神秘的面纱'.如果 ...

  3. 使用 CodeIgniter 框架快速开发 PHP 应用(六)

    原文:使用 CodeIgniter 框架快速开发 PHP 应用(六) 简化使用 Session 和安全理论说得够多了! 现在让我们开始写我们自己的应用. 在这一章里,我们将会大致描述一下我们要建立的一 ...

  4. 使用 CodeIgniter 框架快速开发 PHP 应用(五)

    原文:使用 CodeIgniter 框架快速开发 PHP 应用(五) 简化 HTML 页面和表格设计这一章介绍了又一个节约你的时间而且使你的代码更具安全性和逻辑性的领域.第一,我们将会介绍创建视图的各 ...

  5. 使用 CodeIgniter 框架快速开发 PHP 应用(四)

    原文:使用 CodeIgniter 框架快速开发 PHP 应用(四) 使用 CI 简化数据库开发你学习CI 是因为你想要使编程更容易和更有生产力.这一章讲述CI的Active Record类. 如果C ...

  6. 使用 CodeIgniter 框架快速开发 PHP 应用(二)

    原文:使用 CodeIgniter 框架快速开发 PHP 应用(二) 二分钟: 建立一个 CodeIgniter 网站用CI建一个网站很容易. 这一章很短,解释了用CI制作网站时发生了些什么,哪些文件 ...

  7. 使用 CodeIgniter 框架快速开发 PHP 应用(一)

    原文:使用 CodeIgniter 框架快速开发 PHP 应用(一) 对 CodeIgniter 的介绍大多数PHPer都想写出运行状态良好的应用程序,而且希望尽可能做得简单且不费事.这篇文章是有关 ...

  8. Scut游戏服务器免费开源框架--快速开发(2)

    Scut快速开发(2) Python脚本开发 1   开发环境 Scut Lib版本:5.2.3.2 需要安装的软件 a)        IIS和消息队列(MSMQ) 进入控制面板,程序和功能 b)  ...

  9. Scut游戏服务器免费开源框架--快速开发(3)

    Scut快速开发(3) 1     开发环境 Scut Lib版本:5.2.3.2 需要安装的软件 a)        IIS和消息队列(MSMQ) b)        数据库,Sql2005以上版本 ...

随机推荐

  1. Unity 游戏框架搭建 (十七) 静态扩展GameObject实现链式编程

    本篇本来是作为原来 优雅的QChain的第一篇的内容,但是QChain流产了,所以收录到了游戏框架搭建系列.本篇介绍如何实现GameObject的链式编程. 链式编程的实现技术之一是C#的静态扩展.静 ...

  2. chromium之scoped_ptr

    看看怎么使用 // Scopers help you manage ownership of a pointer, helping you easily manage the // a pointer ...

  3. Java5~11新特性

    Java5~11版本新特性 Java5 Java6 Java7 Java8 Java9 Java10 Java11 Java5 Java5开发代号为Tiger(老虎),于2004-09-30发行 特性 ...

  4. 爬虫——Scrapy框架案例二:阳光问政平台

    阳光热线问政平台 URL地址:http://wz.sun0769.com/index.php/question/questionType?type=4&page= 爬取字段:帖子的编号.投诉类 ...

  5. 【Linux】Linux 的慢动作基础

    了解一下刀片服务器: 刀片服务器是指在高标准度的机架式机箱内插装多个卡式的服务器单元,是一种实现HAHD的低成本服务器平台,其中每一片刀片实际上就是一块系统主板. Linux: Linux操作系统构成 ...

  6. ubuntu系统的软件包管理工具

    ubuntu系统的软件包管理工具有两种,一种是离线管理,另一种是在线管理 1.离线管理 dpkg工具可以对本地存放的deb安装包进行安装,卸载,查看状态等. dpkg -i app_name_vers ...

  7. mint-ui message box 问题;

    当引用 mint-ui message box 的 出现的问题,我暂时是不知道为什么: 官网是这样写的: 于是 我也这么做的:(这里用小写,具体我也不清楚,毕竟文档上写的也不是很清楚,但是只有这样写, ...

  8. jQuery获取Select option 选择的Text和 Value

    获取一组radio被选中项的值:var item = $('input[name=items][checked]').val();获取select被选中项的文本var item = $("s ...

  9. spring-集成redis

    Redis是key-value存储的非关系型数据库.Spring Data Redis包含了多个模板实现,用来完成Redis数据库的数据存取功能 1.如何连接Redis? Spring Data Re ...

  10. Linux awk基础笔记

    正则表达式含义与构成:用单个字符串来描述或者匹配一系列符合某个句法规则的字符串,一般是由普通字符与特殊字符组成 awk 选项 '模式或者命令{编辑指令}' 文件名 awk '//{print}' aw ...