其他分享
首页 > 其他分享> > Dapp TokenFarm开发(6)---前端开发

Dapp TokenFarm开发(6)---前端开发

作者:互联网

3 前端页面开发

3.1 配置数据接口

app.tsx

import React, { Component } from 'react'
import Navbar from './Navbar'
import './App.css'

// tsx 数据接口写法
type StateType = {
  account: string,
  daiToken: object,
  dappToken: object,
  tokenFarm: object,
  daiTokenBalance: string,
  dappTokenBalance: string,
  stakingBalance: string,
  loading: boolean,
}

type propType = {
  [propName: string]: any,
}

interface App {
  state: StateType,
  props: propType
}

class App extends Component {

  constructor(props: any) {
    super(props)
    this.state = {
      account: '0x0',
      daiToken: {},
      dappToken: {},
      tokenFarm: {},
      daiTokenBalance: '0',
      dappTokenBalance: '0',
      stakingBalance: '0',
      loading: true,
    }
  }

  render() {
    return (
      <div>
        <Navbar account={this.state.account} />
        <div className="container-fluid mt-5">
          <div className="row">
            <main role="main" className="col-lg-12 ml-auto mr-auto" style={{ maxWidth: '600px' }}>
              <div className="content mr-auto ml-auto">
                <a
                  href="http://www.dappuniversity.com/bootcamp"
                  target="_blank"
                  rel="noopener noreferrer"
                >
                </a>

                <h1>Hello, World!</h1>

              </div>
            </main>
          </div>
        </div>
      </div>
    );
  }
}

export default App;

Navbar.tsx

import React, { Component } from 'react'
import farmer from '../farmer.png'

type StateType={
}

type propType={
  account:string;
  [propName:string]:any; 
}

interface Navbar{
  state : StateType;
  props: propType
}

class Navbar extends Component {

  render() {
    return (
      <nav className="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0 shadow">
        <a
          className="navbar-brand col-sm-3 col-md-2 mr-0"
          href="http://www.dappuniversity.com/bootcamp"
          target="_blank"
          rel="noopener noreferrer"
        >
          <img src={farmer} width="30" height="30" className="d-inline-block align-top" alt="" />
          &nbsp; DApp Token Farm
        </a>

        <ul className="navbar-nav px-3">
          <li className="nav-item text-nowrap d-none d-sm-none d-sm-block">
            <small className="text-secondary">
              <small id="account">{this.props.account}</small>
            </small>
          </li>
        </ul>
      </nav>
    );
  }
}

export default Navbar;

3.2 页面加载数据获取

在定义web3 时出现ts语法错误,尽管编译后仍然有效但红色的波浪线还是很让人不爽。

解决办法声明一个 typing.d.ts文件,内容如下(ts编译器会认为 *.d.ts 文件是类型声明文件)

declare interface Window{
  web3:any
}

3.3 Vite使用web3报错

因为 web3 在 其他 环境中(比如 webpack, @vue/cli)运行,它们本身会下载一些依赖包,而 vite将不需要的包删除了,所以它没有 Buffer global 或者 process.env(xxx is not defined)的错误。

因此在vite中web3 引入要改成如下

import Web3 from 'web3/dist/web3.min.js'

同时在src/types 文件夹中创建一个 index.d.ts中创建一个文件夹用来定义模块和接口。

declare module 'web3/dist/web3.min.js'

declare interface Window{
  web3:any;
  ethereum:any;
}

3.4 abi的any索引错误

如下所示在使用abi数据时产生的

解决方法

只需要在 tsconfig.json 的 "compilerOptions" 中添加如下

...
	"suppressImplicitAnyIndexErrors": true
...

3.5 实现数据展示

App.tsx

import React, { Component } from 'react'
import TF from './TF'
import Navbar from './Navbar'
import './App.css'
import Web3 from 'web3/dist/web3.min.js'
import DaiToken from '../abis/DaiToken.json'
import DappToken from '../abis/DappToken.json'
import TokenFarm from '../abis/TokenFarm.json'

// tsx 数据接口写法
type StateType = {
  account: string;
  daiToken: object;
  dappToken: object;
  tokenFarm: object;
  daiTokenBalance: string;
  dappTokenBalance: string;
  stakingBalance: string;
  loading: boolean;
}

type propType = {
  [propName: string]: any;
}

interface App {
  state: StateType;
  props: propType;
}

interface Window {
  web3: object;
}

class App extends Component {

  constructor(props: any) {
    super(props)
    this.state = {
      account: '0x0',
      daiToken: {},
      dappToken: {},
      tokenFarm: {},
      daiTokenBalance: '0',
      dappTokenBalance: '0',
      stakingBalance: '0',
      loading: true
    }
  }

  async componentDidMount() {
    await this.loadWeb3()
    await this.loadBlockChainData()
  }

  async loadWeb3() {
    if (window.ethereum) {
      window.web3 = new Web3(window.ethereum)
      await window.ethereum.enable()
    }
    else if (window.web3) {
      window.web3 = new Web3(window.web3.currentProvider)
    }
    else {
      window.alert('Non')
    }
  }

  // 加载区块链数据
  async loadBlockChainData() {
    // 获取账户
    const web3 = window.web3
    const accounts = await web3.eth.getAccounts()
    this.setState({ account: accounts[0] })

    const networkId = await web3.eth.net.getId()

    // 获取DaiToken合约数据
    const daiTokenData = DaiToken.networks[networkId]
    if (daiTokenData) {
      const daiToken = new web3.eth.Contract(DaiToken.abi, daiTokenData.address)
      this.setState({ daiToken })
      // 获取用户DaiToken的余额
      let daiTokenBalance = await daiToken.methods.balanceOf(this.state.account).call()
      this.setState({ daiTokenBalance: daiTokenBalance.toString() })
    } else {
      window.alert('DaiToken contract no deployed to detected network')
    }

    // 获取DappToken合约数据
    const dappTokenData = DappToken.networks[networkId]
    if (dappTokenData) {
      const dappToken = new web3.eth.Contract(DappToken.abi, dappTokenData.address)
      this.setState({ dappToken })
      // 用户DappToken的余额
      let dappTokenBalance = await dappToken.methods.balanceOf(this.state.account).call()
      this.setState({ dappTokenBalance: dappTokenBalance.toString() })
    } else {
      window.alert('DappToken contract no deployed to detected network')
    }

    // 获取TokenFarm合约数据
    const tokenFarmData = TokenFarm.networks[networkId]
    if (tokenFarmData) {
      const tokenFarm = new web3.eth.Contract(TokenFarm.abi, tokenFarmData.address)
      this.setState({ tokenFarm })
      // 获取用户质押数据
      let stakingBalance = await tokenFarm.methods.stakingBalance(this.state.account).call()
      this.setState({ stakingBalance: stakingBalance.toString() })
    } else {
      window.alert('TokenFarm contract no deployed to detected network')
    }

    // 加载完成
    this.setState({ loading: false })
  }

  render() {
    let content
    if (this.state.loading) {
      // 显示正在加载
      content = <p id='loader' className='text-center'></p>
    } else {
      content = <TF
        daiTokenBalance={this.state.daiTokenBalance}
        dappTokenBalance={this.state.dappTokenBalance}
        stakingBalance={this.state.stakingBalance}
      ></TF>
    }
    return (
      <div>
        <Navbar account={this.state.account} />
        <div className="container-fluid mt-5">
          <div className="row">
            <main role="main" className="col-lg-12 ml-auto mr-auto" style={{ maxWidth: '600px' }}>
              <div className="content mr-auto ml-auto">
                <a
                  href="http://www.dappuniversity.com/bootcamp"
                  target="_blank"
                  rel="noopener noreferrer"
                >
                </a>

                {content}

              </div>
            </main>
          </div>
        </div>
      </div>
    );
  }
}

export default App;

TF.tsx

import React, { Component } from 'react'

// tsx 数据接口写法
type StateType = {
}

type propType = {
  daiTokenBalance:string;
  dappTokenBalance:string;
  stakingBalance:string;
}

interface TF {
  state: StateType;
  props: propType;
}

class TF extends Component {
  render() {
    return (
      <div id="content" className='mt-3'>
        <table className='table table-borderless text-muted text-center'>
          <thead>
            <tr>
              <th scope='col'>Staking Balance</th>
              <th scope='col'>Reward Balance</th>
            </tr>
          </thead>
          <tbody>
            {/* 展示余额 */}
            <tr>
              <td>{window.web3.utils.fromWei(this.props.stakingBalance,'Ether')} mDai</td>
              <td>{window.web3.utils.fromWei(this.props.dappTokenBalance,'Ether')} DAPP</td>
            </tr>
          </tbody>
        </table>
      </div>
    )
  }
}

export default TF

标签:string,web3,---,Dapp,window,props,import,TokenFarm,stakingBalance
来源: https://www.cnblogs.com/Jerrvis/p/16331989.html