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

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. Linux 常用命令整理

    系统 切换用户 su 关机/重新启动 shoutdown,reboot,halt,poweroff 内存数据写入磁盘 sync 查询命令用法  "命令 –help" 或 " ...

  2. 身份认证系统(一)单WEB应用的身份认证

    身份认证技术,也就是所谓的登录功能,是现代WEB系统最常见的功能之一.本系列文章就试图为大家详细的介绍身份认证技术. Basic认证模式 Basic认证模式是较早被广泛应用的一种HTTP标准提供的认证 ...

  3. 学习笔记 - Ford-Fulkerson & EK

    Ford-Fulkerson & EK - 学习笔记 之前网络流什么的快忘完了 老师讲课的时候一脸懵逼--开始系统复习,从最大流开始 标签:网络流-最大流 『预备』 首先复习了网络流的概念-- ...

  4. Zabbix——设置模板

    前提条件: Zabbix版本为4.0 可以正常使用Server 1. 添加H3C网络交换机的CPU和内存模板,并配置自动发现. 注意,需要添加完成后,重新进行搜索后再此进入才有下列选项. 添加CPU的 ...

  5. Python基础知识--Slice(切片)和Comprehensions(生成式)

    最近在Youtube的Python视频教程上学习Python相关的基础知识,视频由Corey Schafer制作,讲得十分简单明了,英文发音也比较清晰,几乎都能听懂,是一个不错的Python入门学习的 ...

  6. 在vue中如何实现购物车checkbox的三级联动

    最近用vue写一个电商项目,自然就少不了要写一个购物车的相关页面,功能完整的购物车的checkbox应该是三级联动的,1级checkbox是选中购物车中所有的商品,2级checkbox是选中某个店铺下 ...

  7. python开发的学生管理系统

    python开发的学生管理系统(基础版) #定义一个函数,显示可以使用的功能列表给用户 def showInfo(): print("-"*30) print(" 学生管 ...

  8. Java性能优化的50个细节

    在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重要,能够显著地提升程序性能. 1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时 ...

  9. 【C】关键字void的用法

    void有两种功能 [1]没有 [2]任意类型 void出现的位置不同会有不同的解释 [1]void func( void ) func左边的void,代表『没有返回值』 func右边的括弧里的voi ...

  10. Python学习1——关于变量

    在python中,使用变量之前不需要声明变量的数据类型, 但是,使用变量前,必须要先对变量进行赋值: 例: num01 += 100 print('num01') 上述例子中,表示的意思是 num01 ...