[Near Protocol] Near开发Demo浅析-Gamble Game Near
Dapp
接着上一期持续分享
源代码在Github上能够找到,以下是Dapp链接:
https://github.com/Yang94J/Gamble_Game_Near_Front
简介
本我的项目依靠Vue,搭建前端利用,调用near-api-js与部署好的合约进行交互,实现掷骰子性能。
环境搭建
- Prerequisite : 零碎中该当曾经装置好Nodejs,Vue3
我的项目搭建:
vue create gamble_gamble_near_front
最终代码框架如下:
次要对/components/GambleGame.vue、App.vue、config.js、main.js、store.js、.env、package.json及vue.config.js进行介绍。
<h3>代码解析</h3>
package.json
以下是package.json重点局部
"dependencies": { "@rollup/plugin-inject": "^4.0.4", "buffer": "^6.0.3", "core-js": "^3.8.3", "near-api-js": "^0.44.2", "vue": "^3.2.13", "vuex": "^4.0.2" },
此处指明了对buffer、near-api-js、vue、vuex等依赖(尤其是buffer,必须要引入并显式申明,否则工程会呈现相似Can't find variable: Buffer
之类的谬误)
.env
VUE_APP_CONTRACT_NAME=gamble_game1.XXX.testnet
指明dapp所需调用的合约名称(测试网)
main.js
import { createApp } from 'vue'import App from './App.vue'import store from './store'import { Buffer } from "buffer"; global.Buffer = Buffer;createApp(App).use(store).mount('#app')
请留神此处显式申明了global.Buffer
config.js
const CONTRACT_NAME = process.env.VUE_APP_CONTRACT_NAME;
从.env文件中读取合约名称
case 'testnet': return { networkId: 'testnet', nodeUrl: 'https://rpc.testnet.near.org', contractName: CONTRACT_NAME, walletUrl: 'https://wallet.testnet.near.org', helperUrl: 'https://helper.testnet.near.org', explorerUrl: 'https://explorer.testnet.near.org', };
依据用户输出环境,抉择对应的网络配置(此处为测试网)。
store.js
store.js存储数据到本地浏览器,获取缓存等,能够参考该链接
state: { contract: null, currentUser: null, wallet: null, nearConfig: null },
存储状态包含合约、以后用户、钱包和near配置
mutations: { setupNear(state, payload) { state.contract = payload.contract; state.currentUser = payload.currentUser; state.wallet = payload.wallet; state.nearConfig = payload.nearConfig; } }
设置state对象
async initNear({ commit }) { const nearConfig = getConfigurations('testnet'); const near = await nearApi.connect({ deps: { keyStore: new nearApi.keyStores.BrowserLocalStorageKeyStore() }, ...nearConfig }); const wallet = new nearApi.WalletConnection(near); console.log(wallet) let currentUser; if (wallet.getAccountId()) { currentUser = { accountId: wallet.getAccountId(), balance: (await wallet.account().state()).amount, balanceInNear : (await wallet.account().state()).amount / (10 ** 24), } } console.log(currentUser) const contract = await new nearApi.Contract(wallet.account(), process.env.VUE_APP_CONTRACT_NAME || 'gamble_game1.young_cn.testnet', { viewMethods: ['get_maximum_gamble_price'], changeMethods: ['gamble','sponsor'], sender: wallet.getAccountId() }); console.log(contract); // Commit and send to mutation. commit('setupNear', { contract, currentUser, wallet, nearConfig }); } }
此处initNear函数获取测试网配置,生成合约、钱包信息(须要用户登录)、用户信息等。
GambleGame.vue
<div align="center"> <h1 align="center" title="log in and gamble to get 6X the prize">Dice Gamble game</h1> <button align="center" title="This enables your link to near testnet" @click="currentUser ? signOut() : signIn()"> {{ currentUser ? 'Log Out' : 'Log In' }} </button> </div>
依据以后用户状况,生成登入登出按钮
<h3>Hi, {{currentUser.accountId}}, your balance is {{currentUser.balanceInNear}} Near</h3>
显示以后用户id,以后余额(CurrentUser信息参见store.js)
<p class="highlight"> <label for="gamble">Maximum : {{gambleLimit}} Near </label> <button @click="refresh()"> Refresh</button> </p>
显示以后最大投注量,通过refresh函数拜访智能合约刷新最大投注量
<p class="highlight"> <label for="gamble">Gamble:</label> <input autocomplete="off" v-model="gamble" autofocus id="gamble" type="number" required/> <button @click="gamblegame()">Gamble</button> </p>
投注按钮,调用gamblegame办法进行投注
<p class="highlight"> <label for="sponsor">Sponsor:</label> <input autocomplete="off" v-model="sponsor" autofocus id="sponsor" type="number" required/> <button @click="sponsorus()">Sponsor us</button> </p>
资助按钮,调用sponsorus办法进行资助
async created(){ console.log("created") console.log(sessionStorage.getItem('gambleLimit')) if (sessionStorage.getItem('gambleLimit')) { this.gambleLimit = sessionStorage.getItem('gambleLimit') } },
用created钩子函数来主动获取最大投注量(否则数据将失落)
async mounted() { var that = this console.log("Mount") setInterval( () => { console.log("refresh") that.refresh() },3000 ) },
应用mounted钩子函数来设置自动更新最大投注量-思考合约的并发。
signIn() { this.wallet.requestSignIn( this.nearConfig.contractName, 'Near Gamble Game' ); }, signOut() { this.wallet.signOut(); window.location.replace(window.location.origin + window.location.pathname) },
signIn和signOut办法调用near.api.js实现与钱包的交互
async gamblegame(){ try{ await this.contract.gamble( {}, this.gas, Big(this.gamble).times(10**24).toFixed() ); }catch (e) { console.log(e); } }, async sponsorus(){ try{ await this.contract.sponsor( {}, this.gas, Big(this.sponsor).times(10**24).toFixed() ); }catch (e) { console.log(e); alert('Something went wrong! Check the console.'); } }, async refresh(){ this.gambleLimit = await this.contract.get_maximum_gamble_price() this.gambleLimit = this.gambleLimit / (10 ** 24) sessionStorage.setItem('gambleLimit',this.gambleLimit) } }
gambleGame、sponsorus和refresh都是异步办法。具体contract办法信息在store.js里通过以下进行申明:
viewMethods: ['get_maximum_gamble_price'], changeMethods: ['gamble','sponsor'],
部署
- vue.config.js批改其配置如下:
const { defineConfig } = require('@vue/cli-service')module.exports = defineConfig({ transpileDependencies: true, publicPath:'./',})
将门路改为相对路径
- 构建
npm run build
- 运行
npm run serve
成果展现
至此,Dapp局部实现。
诚然,这个demo很显著还有很多有余的中央,但也算一个不错的开始。大家有想法也欢送和我一起探讨。相互交换,共同进步。