[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很显著还有很多有余的中央,但也算一个不错的开始。大家有想法也欢送和我一起探讨。相互交换,共同进步。