最近因为星云链主网上线推出的星云激励计划,导致nas的价格一定拉升,肯定有不少朋友感觉幸运链的DAPP挺神秘的,其实不然,这里手把手教你如何开发一款基于星云链的dapp。
星云链主页:https://nebulas.io/cn/index.html
哪类人群适合阅读本教程呢?
只要您具备 JavaScript 、 HTML 和 CSS一些基础知识,您就可以阅读本教程,进而开发出一款基于星云链的dapp。
话不多说,直接上截图:
背景图片是可以轮播变换的,这时候想象下放些从恋爱时约会、求婚、结婚、生娃、老年陪伴的图片做背景图,循环播放是不是很有感觉呢。
好了,上代码前先附上我的目录结构:
其中 lib 文件夹中的nebPay.js. 和nebulas.js 需要下载
1. 合约编写
跟以太坊类似,Nebulas实现了NVM虚拟机来运行智能合约,NVM的实现使用了JavaScript V8引擎,所以当前的开发版,我们可以使用JavaScript、TypeScript来编写智能合约。
编写智能合约的简要规范:
智能合约代码必须是一个Prototype的对象;
智能合约代码必须有一个init()的方法,这个方法只会在部署的时候被执行一次;
智能合约里面的私有方法是以_开头的方法,私有方法不能被外部直接调用;
定义文件:contract.js
"use strict";
//合约 n1eMo1ANL5DymS7saJz67ou1Z7kRTCGoULU
//hash ea3f9680c61b93262e9e031b82e676312dc53dbf82119de317bbc0af5b3b1a63
//作为单独的类,封装一些参数,这些参数都是页面提交过来或者想展示到页面上的集合体
var LoveInfo = function (arrys) {
if (arrys) {
var obj = JSON.parse(arrys);
this.mn = obj.mn;
this.wm = obj.wm;
this.ai = obj.ai;
this.now = obj.now;
this.author = obj.author;
} else {
this.mn = "";
this.wm = "";
this.ai = "";
this.now = "";
this.author = "";
}
};
//定义方法,转换成字符串
LoveInfo.prototype = {
toString: function () {
return JSON.stringify(this);
}
};
//结婚登记
var Married = function () {
//LocalContractStorage.defineMapProperty是合约存储区内定义好的方法,可以直接使用,如果有小伙伴不知道怎么使用的话下面会给个链接讲解,很容易理解的
//简单的理解就是给当前合约申明了一个属性叫love,然后love内部又有两个方法,parse和stringify对应着从区块链读取数据,后面操作区块链可以直接使用this.love调用对应的存取方法完成操作
LocalContractStorage.defineMapProperty(this,"love",{
parse : function (arrys) {
return new LoveInfo(arrys)
},
stringify: function (res) {
return res.toString()
}
});
};
//合约内定义的方法
Married.prototype = {
init:function() {
},
//保存到区块链的方法 需要传递的三个参数,男人名字,女人名字,爱情宣言,当前时间
save:function (mn,wm,ai,now) {
//做去空格处理
mn = mn.trim();
wm = wm.trim();
ai = ai.trim();
now = now.trim();
//空字符串处理
if (mn === ""|| mn === ""||mn === ""||mn === ""){
throw new Error("请检查登记信息,禁止登记空信息")
}
if (ai.length > 1024){
throw new Error("可能你们彼此只想说一句简单的'我爱你'")
}
//获取添加来自哪个地址
var from = Blockchain.transaction.from;
//这里我们设定的key是两个名字加一起的字符串
var loveInfo = this.repo.get(mn+wm);
//如果链上有信息,说明保存过,返回提示信息
if (loveInfo){
throw new Error("信息已存在链上,可直接查看婚姻状况")
}
//没有信息就添加到区块链中
loveInfo = new LoveInfo();
loveInfo.mn = mn;
loveInfo.wm = wm;
loveInfo.now = now;
loveInfo.ai = ai;
loveInfo.author = from;
//保存
this.love.put(mn+wm,loveInfo);
}
//从区块链获取的方法 我这里定义的是两个参数,拼接在一起就是要从区块链查询的key值了
get: function (mn,wm) {
mn = mn.trim();
wm = wm.trim();
if ( mn === "" ) {
throw new Error("男方姓名不能为空")
}
if ( wm === "" ) {
throw new Error("女方姓名不能为空")
}
return this.love.get(mn+wm);
}
};
module.exports = Married;
如果对上面调用的 LocalContractStorage.defineMapProperty 不太理解的可以点击下面的链接,有详细解释
这样只能合约就写好了,是不是很简单,接下来就是部署了,部署方法也很简单,如果有不会的可以查看我前面写的文章
使用星云WEB钱包部署合约:https://www.jianshu.com/p/9c990453767c
提示:如果你们去看其他已提交的基于星云的dapp,合约都大同小异,唯一不同的就是前端页面的变化,所以,如果你的前端技术不错的话,完全可以写出几十种不同的DAPP,
2 页面编写
我这里使用到了bootstrap
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>婚姻登记所</title>
<script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="assets/css/bootstrap-responsive.css" rel="stylesheet">
<!--这是我自定义的css文件,用来实现页面的一些效果 -->
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<!-- <div class="div01">
<div class="search">
男方姓名:<input id="mn" class="input-xlarge" type="text" placeholder="username"><br />
女方姓名:<input id="wm" class="input-xlarge" type="text" placeholder="username"><br />
爱情宣言:<br /><textarea rows="3" id = "ai"></textarea><br />
<button id="add" class="btn btn-large btn-block btn-primary" type="button">登记</button>
</div>
</div> -->
<div class="div01">
<div class="form row">
<div class="form-horizontal col-md-offset-3" id="login_form">
<h3 class="form-title">婚姻登记</h3>
<div class="col-md-9">
<div class="form-group">
<!--<i class="fa fa-user fa-lg"></i>-->
男方姓名:<input class="form-control required" type="text" placeholder="man name" id="mn" name="username" autofocus="autofocus" maxlength="20"/>
</div>
<div class="form-group">
<!--<i class="fa fa-user fa-lg"></i>-->
女方姓名:<input class="form-control required" type="text" placeholder="woman name" id="wm" name="username" autofocus="autofocus" maxlength="20"/>
</div>
<div class="form-group">
<!--<i class="fa fa-apple fa-lg"></i>-->
爱情宣言:
<textarea maxlength="120"></textarea>
</div>
<div class="form-group col-md-offset-9">
<button class="btn btn-large btn-block btn-primary" type="button" id = 'add'>登记结婚</button>
</div>
</div>
</div>
</div>
</div>
<script src=lib/nebPay.js></script>
<script src=lib/nebulas.js></script>
<script>
"use strict";
<!--合约地址-->
var dappAddress = "n1eMo1ANL5DymS7saJz67ou1Z7kRTCGoULU";
//导包 nebulas 的 API
var nebulas = require("nebulas"),
//账户
Account = nebulas.Account,
//neb:一套API
neb = new nebulas.Neb();
//设置网络:主网 测试网 本地网 这里使用的是测试网,所以部署合约的时候就要把合约部署到测试网上
neb.setRequest(new nebulas.HttpRequest("https://testnet.nebulas.io"));
//添加数据,需要支付手续费 这里导包
var NebPay = require("nebpay"); //https://github.com/nebulasio/nebPay
var nebPay = new NebPay();
var serialNumber
var intervalQuery
// 添加信息功能: 像合约中添加婚姻登记信息
$("#add").click (() => {
//获取当前时间
function p(s) {
return s < 10 ? '0' + s: s;
}
var myDate = new Date();
//获取当前年
var year=myDate.getFullYear();
//获取当前月
var month=myDate.getMonth()+1;
//获取当前日
var date=myDate.getDate();
var h=myDate.getHours(); //获取当前小时数(0-23)
var m=myDate.getMinutes(); //获取当前分钟数(0-59)
var s=myDate.getSeconds();
var now = year+'-'+p(month)+"-"+p(date)+" "+p(h)+':'+p(m)+':'+p(s);
console.log(now);
//合约地址
var to = dappAddress;
var value = "0";
//调用的合约内哪个方法
var callFunction = "save";
//发送的参数
var callArgs = "[\"" + $("#mn").val() + "\",\"" + $("#wm").val() +"\",\"" +$("#ai").val()+ "\",\"" + now +"\"]"
//调用nebpay自带的方法,开始往区块链添加数据
serialNumber = nebPay.call(to, value, callFunction, callArgs, { //使用nebpay的call接口去调用合约,
listener: cbPush //设置listener, 处理交易返回信息
});
//定时器监听交易信息
intervalQuery = setInterval(function () {
funcIntervalQuery();
}, 5000);
});
function funcIntervalQuery() {
nebPay.queryPayInfo(serialNumber)
.then(function (resp) {
console.log("tx result: " + resp)
var respObject = JSON.parse(resp)
if(respObject.code === 0){
console.log("已完成登记")
clearInterval(intervalQuery)
}
})
.catch(function (err) {
console.log(err);
});
}
function cbPush(resp) {
console.log("response of push: " + JSON.stringify(resp))
}
</script>
</body>
</html>
定义的 style.css 文件
.div01{
background: url("../img/love01.jpeg");
height: 830px;
animation-name:myPics;
background-size: cover;
animation-duration:30s;
/*变换时间*/
animation-delay:2s;
/*动画开始时间*/
animation-iteration-count:infinite;
/*下一周期循环播放*/
animation-play-state:running;
/*动画开始运行*/
}
/* .search {
width: 50%;
height: 50%;
margin: auto;
}
.search button {*/
/*width: 18%;*/
/*height: 30px;*/
/*margin-left: 6px;*/
/*box-shadow: 3px 5px grey, 1px 1px #333;*/
/*}
@keyframes myPics
{
0% {background:url("../img/love01.jpeg");background-size: cover;}
25% {background:url("../img/love02.jpeg");background-size: cover;}
/*50% {background:url("../img/love3.jpeg");background-size: cover;}*/
/*75% {background:url("../img/love4.jpeg");background-size: cover;}*/
/*100% {background:url("../img/love5.jpeg");background-size: cover;}*/
}
.form{background: rgba(255,255,255,0.2);width:400px;margin:120px auto;}
/*阴影*/
.fa{display: inline-block;top: 27px;left: 6px;position: relative;color: #ccc;}
input[type="text"]{padding-left:26px;}
.checkbox{padding-left:21px;}
这样前端页面部分也就完成啦,现在让我测试下:
打开index.html
大功告成!!!!!!
如果有心的哥们,肯定会发现我没有写查询的方法,因为时间紧张还有其他事要做,这块就留给你们了。还是那句话,在我看来前端技术好了,写星云的dapp很简单。
另:如果你也想赢取星云dapp开发奖,可以去找些现成的项目改成合约版的啦,不说了,我要去再找些了。
版权声明:博客中的文章版权归博主所有,转载请注明出处,联系方式:lixuan111222(微信)