以太坊 – 智能合约前端页面

简介: 开发智能合约的前端页面,让用户可以通过前端页面与智能合约交互。这个页面的主要功能是:显示当前连接的帐户;读取智能合约中存储的value值;更新智能合约中存储的value值。

1. 智能合约前端页面

2. 配置web服务器

3. 创建前端页面

3.1 index.html

3.2 app.js


1. 智能合约前端页面

开发智能合约的前端页面,让用户可以通过前端页面与智能合约交互。这个页面的主要功能是:

    • 显示当前连接的帐户
    • 读取智能合约中存储的value值
    • 更新智能合约中存储的value值

    页面大概的样子:

    image.gif编辑

    为开发前端页面,需要完成下面几项工作:

      • 配置web服务器,用来部署页面
      • 创建前端的h5、js文件

      2. 配置web服务器

      首先,让我们来配置web服务器。服务器使用lite-server,安装lite-server:

      $ npm install lite-server --save-dev

      image.gif

      项目根目录下,创建lite-server的配置文件bs-config.json,内容如下:

      {
        "server": {
          "baseDir": [
            "./src",
            "./build/contracts"
          ],
          "routes": {
            "/vendor": "./node_modules"
          }
        }
      }

      image.gif

        • baseDir配置告诉lite-server将./src./build/contracts目录作为web服务器的根目录,所有文件都可以被访问
        • routes./node_modules映射为/vendor,在引用文件时,可以使用/vendor

        3. 创建前端页面

        项目根目录下,创建src目录,用于存放前端页面。

        前端页面包含2个文件:

        src/index.html
        src/app.js

        image.gif

        3.1 index.html

        添加index.html页面,内容如下:

        <!DOCTYPE html>
        <html lang="zh-CN">
          <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>以太坊 DApp Demo</title>
            <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
            <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
            <!--[if lt IE 9]>
              <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
              <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
            <![endif]-->
          </head>
          <body>
              <h1>账号: <span id="account"></span></h1>
              <hr>
              <div id="content">
                  <h2>智能合约:MyContract</b></h2>
                  <p>获取智能合约中的value值: <span id="value"></span></p>
                    <h5>设置value值</h5>
                    <form onSubmit="App.set(); return false;" role="form">
                    <div >
                        <input id="newValue" type="text"></input>
                    </div>
                    <button type="submit" >设置</button>
                    </form>
              </div>
              <div id="loader">正在加载...</div>
            </div>
            <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
            <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
            <!-- Include all compiled plugins (below), or include individual files as needed -->
            <script src="https://etherscan.io/jss/web3.min.js"></script>
            <script src="vendor/@truffle/contract/dist/truffle-contract.js"></script>
            <script src="app.js"></script>
          </body>
        </html>

        image.gif

        这个文件的重点是引入了几个js文件:

          • web3.min.js – web3.js库文件,直接从https://etherscan.io/引入
          • truffle-contract.js – truffle提供的处理智能合约的库文件

          安装@truffle/contract

          $ npm install @truffle/contract --save-dev

          image.gif

          3.2 app.js

          添加javascript脚本文件:app.js

          App = {
              web3Provider: null,
              contracts: {},
              account: '0x0',
              loading: false,
              contractInstance: null,
              init: async () => {
                  // 加载web3
                  await App.loadWeb3()
                  // 加载智能合约
                  await App.loadContract()
                  // 网页刷新
                  await App.render()
              },
              // https://medium.com/metamask/https-medium-com-metamask-breaking-change-injecting-web3-7722797916a8
              loadWeb3: async () => {
                  if (typeof web3 !== 'undefined') {
                      App.web3Provider = web3.currentProvider
                      web3 = new Web3(web3.currentProvider)
                  } else {
                      window.alert("Please connect to Metamask.")
                  }
                  // MetaMask新版本…
                  if (window.ethereum) {
                      window.web3 = new Web3(ethereum)
                      try {
                          // 向用户请求帐户访问
                          await ethereum.enable()
                          // 用户允许使用账户
                          web3.eth.sendTransaction({/* ... */ })
                      } catch (error) {
                          // 用户拒绝使用账户
                      }
                  }
                  // MetaMask老版本…
                  else if (window.web3) {
                      App.web3Provider = web3.currentProvider
                      window.web3 = new Web3(web3.currentProvider)
                      // 无需向用户请求,可以直接使用账号
                      web3.eth.sendTransaction({/* ... */ })
                  }
                  // 没有安装以太坊钱包插件(MetaMask)...
                  else {
                      console.log('需要安装以太坊钱包插件(例如MetaMask)才能使用!')
                  }
              },
              loadContract: async () => {
                  const contract = await $.getJSON('MyContract.json')
                  App.contracts.MyContract = TruffleContract(contract)
                  App.contracts.MyContract.setProvider(App.web3Provider)
              },
              render: async () => {
                  // 如果正在加载,直接返回,避免重复操作
                  if (App.loading) {
                      return
                  }
                  // 更新app加载状态
                  App.setLoading(true)
                  // 设置当前区块链帐户
                  const accounts = await ethereum.enable()
                  App.account = accounts[0]
                  $('#account').html(App.account)
                  // 加载智能合约
                  const contract = await App.contracts.MyContract.deployed()
                  App.contractInstance = contract
                  const value = await App.contractInstance.get()
                  $('#value').html(value)
                  App.setLoading(false)
              },
              set: async () => {
                  App.setLoading(true)
                  const newValue = $('#newValue').val()
                  await App.contractInstance.set(newValue, {from: App.account})
                  window.alert('更新成功,页面值不会马上更新,等待几秒后多刷新几次。')
                  App.setLoading(false)
              },
              setLoading: (boolean) => {
                  App.loading = boolean
                  const loader = $('#loader')
                  const content = $('#content')
                  if (boolean) {
                      loader.show()
                      content.hide()
                  } else {
                      loader.hide()
                      content.show()
                  }
              }
          }
          $(document).ready(function () {
              App.init()
          });

          image.gif

          在上面的代码中:

            • loadWeb3()函数添加了用Metamask将web浏览器连接到区块链所需的配置。这是直接从Metamask的配置规范中复制粘贴的,如函数上面代码注释中的url所示。
            • loadContract()函数使用TruffleContract库创建智能合约的javascript对象,可以用于调用智能合约中的函数。
            • render()函数设置页面内容,包括帐户及智能合约的value值。

            现在启动服务器:

            $ npm run dev

            image.gif

            然后使用安装了MetaMask插件的Chrome浏览器,打开网址:http://localhost:3000,就可以查看前端页面,与区块链上的智能合约进行交互。

            目录
            相关文章
            |
            4天前
            |
            前端开发 数据可视化 JavaScript
            前端vite+vue3——可视化页面性能耗时指标(fmp、fp)
            前端vite+vue3——可视化页面性能耗时指标(fmp、fp)
            54 6
            |
            4天前
            |
            缓存 前端开发 JavaScript
            如何优化前端页面性能
            前端性能优化是网站开发中非常重要的一部分,它直接关系到用户体验和网站的流量以及排名。本文将介绍一些优化前端页面性能的方法,包括减少HTTP请求、压缩代码、使用CDN等。
            |
            2天前
            |
            前端开发 JavaScript Java
            Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)五(前端页面
            Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)五(前端页面
            Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)五(前端页面
            |
            4天前
            |
            机器学习/深度学习 前端开发 数据可视化
            数据分析web可视化神器---streamlit框架,无需懂前端也能搭建出精美的web网站页面
            数据分析web可视化神器---streamlit框架,无需懂前端也能搭建出精美的web网站页面
            |
            4天前
            |
            存储 前端开发 API
            对象存储OSS产品常见问题之获取文件结构并在前端页面展示如何解决
            对象存储OSS是基于互联网的数据存储服务模式,让用户可以安全、可靠地存储大量非结构化数据,如图片、音频、视频、文档等任意类型文件,并通过简单的基于HTTP/HTTPS协议的RESTful API接口进行访问和管理。本帖梳理了用户在实际使用中可能遇到的各种常见问题,涵盖了基础操作、性能优化、安全设置、费用管理、数据备份与恢复、跨区域同步、API接口调用等多个方面。
            35 0
            |
            7月前
            |
            缓存 前端开发 JavaScript
            【前端用法】jquery获取当前页面的URL信息
            【前端用法】jquery获取当前页面的URL信息
            55 0
            |
            4天前
            |
            存储 前端开发 JavaScript
            【JavaEE初阶】 博客系统项目--前端页面设计实现
            【JavaEE初阶】 博客系统项目--前端页面设计实现
            |
            7月前
            |
            前端开发 安全 JavaScript
            关于前端页面测试和抵御 clickjacking attack 的一些方法
            关于前端页面测试和抵御 clickjacking attack 的一些方法
            52 0
            |
            4天前
            |
            存储 前端开发 安全
            无限连接:前端跨页面通信的实现与应用
            在前端开发中,有时我们需要在不同的页面之间进行数据传递和交互。这种场景下,前端跨页面通信就显得尤为重要。前端跨页面通信是指在不同的页面之间传递数据、发送消息以及实现页面间的交互操作。本文将详细介绍前端跨页面通信的属性、应用场景以及实现方法,并提供一些代码示例和引用资料,帮助读者深入了解并应用这一重要的技术。
            |
            4天前
            |
            数据采集 前端开发 安全
            禁止别人调试自己的前端页面代码
            禁止别人调试自己的前端页面代码