bank demo 是一个基于星云链智能合约编写的的Dapp,它的功能包括存储,取出,查询功能,而星云链是全球首个主网上线的区块链3.0公链,所有代码全部重新构建,比起以太坊更清晰,更简练,对开发者极度友好,智能合约语言基于当下最流行的javascript,此demo可以作为刚刚接触NAS 想开发Dapp的开发者作为学习参考,下面我就一步步带大家去了解怎样做出一个在星云链上的Dapp。
https://xingyun.io/dapp/nasbank/
制作这个DApp,我们分四个步骤:
- 编写Web页面。
- 用JavaScript或者TypeScript 编写几十行代码的智能合约。
- 部署智能合约
- 完成Web页面与智能合约的交互。
首先看下目录结构 :
imageimg 放置图标
lib 放库
smartContract 放置智能合约
第一步,Web页面制作。
从这个页面我们可以获取到的信息有以下信息:
1、页面的背景
2、顶部的名称,logo,接下来的提示语NOTE:Please install WebExtensionWallet to use bank demo 是因为还没有安装星云钱包插件给个提示(什么是星云钱包插件?文章后面会说到)
3、三个编辑框 ,三个按钮 (save, balance,takeout)
下面是对应的布局代码:
<body>
<div class="contenner">
<div class="logo">
<div class="name">bank demo</div>
<div class="img logo_rotate">
<img src="img/logo.png" alt="">
</div>
</div>
<div class="noExtension hide" id="noExtension">
NOTE: Please install <a target="_blank" href="https://github.com/ChengOrangeJu/WebExtensionWallet">WebExtensionWallet</a> to use bank demo
</div>
<div class="search">
<input id="search_value" type="text">
<button id=search>save</button>
</div>
<div class="search">
<input id="balance_value" type="text">
<button id=balance>balance</button>
</div>
<div class="search">
<input id="takeout_value" type="text">
<button id=takeout>takeout</button>
</div>
<!-- <div class="result_success hide">
<div id=search_banner></div>
<p id=search_result> wait for content </p>
<div class="author">
<i><p> Author:</p> <p id=search_result_author> dasdajkajksdhjasdkjahdkjad</p></i>
</div>
</div> -->
<div class="result_faile hide">
Failed to find related information. Do you want to <button id="add">add</button> infromation for "<i id="result_faile_add">asd</i>"?
</div>
<div class="add_banner hide">
<input type="text" id="add_value" placeholder="input contents for your keyword">
<button id="push">submit</button>
</div>
</div>
<script src=lib/jquery-3.3.1.min.js></script>
<script src=lib/nebPay.js></script>
<script src=lib/bootstrap-4.0.0-dist/js/bootstrap.min.js></script>
<script>
var NebPay = require("nebpay"); //https://github.com/nebulasio/nebPay
var nebPay = new NebPay();
document.addEventListener("DOMContentLoaded", function() {
$("#search_value").attr("disabled",true)
$("#search").attr("disabled",true)
console.log("web page loaded...")
setTimeout(checkNebpay,100);
});
function checkNebpay() {
console.log("check nebpay")
//to check if the extension is installed
//if the extension is installed, var "webExtensionWallet" will be injected in to web page
if(typeof(webExtensionWallet) === "undefined"){
//alert ("Extension wallet is not installed, please install it first.")
$("#noExtension").removeClass("hide")
}else{
$("#search_value").attr("disabled",false)
$("#search").attr("disabled",false)
}
}
//var dappAddress = "n1uNSyJRWKDXUhoBiNsURz4GXnCkPYAc2pZ"; // 测试网合约地址
var dappAddress = "n1s9jBuWJFARs7odyC37xxcJJUFP6MxwUKm"; // 主网合约地址
var ex = 1000000000000000000;
// 存钱功能
$("#search").click(function(){
console.log("********* call smart contract by \"call\" *****************")
var to = dappAddress;
var value = $("#search_value").val() // 搜索框内的值
var callFunction = "save"
var callArgs = "[" + value + "]"
nebPay.call(to, value, callFunction, callArgs,{ //使用nebpay的call接口去调用合约,
callback: null
}
);
})
// 余额
$("#balance").click(function(){
console.log("********* call smart contract by \"call\" *****************")
var to = dappAddress;
var value = "0"
var callFunction = "balanceOf"
var callArgs = ""
nebPay.simulateCall(to, value, callFunction, callArgs,{ //使用nebpay的call接口去调用合约,
callback: balanceCallback
}
);
})
function balanceCallback(resp) {
console.log("response of balanceCallback resp: " + JSON.stringify(resp))
var result = JSON.parse(resp.result);
if (result === 'null'){
$(".add_banner").addClass("hide");
$(".result_success").addClass("hide");
$("#result_faile_add").text($("#search_value").val())
$(".result_faile").removeClass("hide");
} else{
try{
result = JSON.parse(e.data.data.neb_call.result)
}catch (err){
}
$("#balance_value").val(result.balance / ex)
}
}
// 取款
$("#takeout").click(function(){
console.log("********* call smart contract by \"call\" *****************")
var to = dappAddress;
var value = "0"
var callFunction = "takeout"
var callArgs = "[" + $("#takeout_value").val() * ex + "]"
nebPay.call(to, value, callFunction, callArgs,{ //使用nebpay的call接口去调用合约,
callback: null
}
);
})
</script>
</body>
其中我们最需要关注的有以下几点:
1、WebExtensionWallet 星云钱包插件
2、dappAddress 这个是合约地址,到时部署好了之后修改为你自己的就可以了
3、neb.js 下面会说到 调用智能合约时用到
第二步,编写智能合约
'use strict';
var DepositeContent = function (text) {
if (text) {
var o = JSON.parse(text);
this.balance = new BigNumber(o.balance);
this.expiryHeight = new BigNumber(o.expiryHeight);
} else {
this.balance = new BigNumber(0);
this.expiryHeight = new BigNumber(0);
}
};
DepositeContent.prototype = {
toString: function () {
return JSON.stringify(this);
}
};
var BankVaultContract = function () {
LocalContractStorage.defineMapProperty(this, "bankVault", {
parse: function (text) {
return new DepositeContent(text);
},
stringify: function (o) {
return o.toString();
}
});
};
// save value to contract, only after height of block, users can takeout
BankVaultContract.prototype = {
init: function () {
//TODO:
},
save: function (height) {
var from = Blockchain.transaction.from;
var value = Blockchain.transaction.value;
var bk_height = new BigNumber(Blockchain.block.height);
var orig_deposit = this.bankVault.get(from);
if (orig_deposit) {
value = value.plus(orig_deposit.balance);
}
var deposit = new DepositeContent();
deposit.balance = value;
deposit.expiryHeight = bk_height.plus(height);
this.bankVault.put(from, deposit);
},
takeout: function (value) {
var from = Blockchain.transaction.from;
var bk_height = new BigNumber(Blockchain.block.height);
var amount = new BigNumber(value);
var deposit = this.bankVault.get(from);
if (!deposit) {
throw new Error("No deposit before.");
}
if (bk_height.lt(deposit.expiryHeight)) {
throw new Error("Can not takeout before expiryHeight.");
}
if (amount.gt(deposit.balance)) {
throw new Error("Insufficient balance.");
}
var result = Blockchain.transfer(from, amount);
if (!result) {
throw new Error("transfer failed.");
}
Event.Trigger("BankVault", {
Transfer: {
from: Blockchain.transaction.to,
to: from,
value: amount.toString()
}
});
deposit.balance = deposit.balance.sub(amount);
this.bankVault.put(from, deposit);
},
balanceOf: function () {
var from = Blockchain.transaction.from;
return this.bankVault.get(from);
},
verifyAddress: function (address) {
// 1-valid, 0-invalid
var result = Blockchain.verifyAddress(address);
return {
valid: result == 0 ? false : true
};
}
};
module.exports = BankVaultContract;
第三部,部署智能合约
如果是第一次部署的话,首先需要到这个网站 https://github.com/nebulasio/web-wallet 把NAS 的web 钱包代码下载下来,然后 打开 index.html
然后看到右上角有个环境切换的,现在我们是部署到测试环境,那就选择Testnet ,如果需要部署到正式环境的则选择Mainnet
然后按照下面的步骤
imageimage
如果还没有钱包则可以先去创建一个钱包
image
如果钱包里面还没有NAS 可以扫描文章底部的二维码注册,注册完成之后点击链接https://testnet.nebulas.io/claim/ 进行操作
当你的账户地址上有NAS 后点击提交 之后生成合约地址 然后修改第一步中的dappAddress 的值就可以了
image
第四步 、完成Web页面与智能合约交互
为了解决这个问题,星云官方提供了完整的API
https://github.com/nebulasio/neb.js
提供用户对于已经部署好的合约进行调用的SDK。
nebPay.call(to, value, callFunction, callArgs,{ //使用nebpay的call接口去调用合约,
callback: null
}
);
nebPay.simulateCall(to, value, callFunction, callArgs,{ //使用nebpay的simulateCall接口去调用合约,
callback: balanceCallback
}
);
此外,社区小伙伴为方便在Web页面进行交互,提供了浏览器插件。
项目的地址是:https://github.com/ChengOrangeJu/WebExtensionWallet 。只需要在Web页面中向浏览器插件POST message 即可唤起插件的内置功能,调用上文已经部署的智能合约中的功能函数,完成Web端与智能合约的交互。
本DApp网页地址:https://xingyun.io/dapp/nasbank/,欢迎大家上来测试。
用Chrome 浏览器打开,首先我们需要给浏览器添加扩展插件,安装星云钱包插件
首先下载点击链接去下载 https://github.com/ChengOrangeJu/WebExtensionWallet
image
然后就会出现图中extensionWallet 这个开启,然后刷新主页面NOTE:Please install WebExtensionWallet to use bank 这个提示不会出现了
这样一个Dapp开发就算完成了,是不是很简单
2018年真是一个可以让开发者爆富的机会,就看你去不去珍惜
如果想珍惜那就赶紧行动起来吧!仅需Javascript和一杯下午茶的时间,您就可以开发属于您的第一个DApp,这不是你爆富的机会么?不说了,就是干 干 干
扫描下面的二维码注册
你也可以加入星云社区,了解最新信息,让你一步步实现暴富的机会:
星云社区:https://bbs.xingyun.io/
网友评论