Vue+NodeJs+Ganache 本地部署、调用 web3 智能合约
目录
[TOC]
1、基础环境准备
1.1、安装 Vue 和 Vue CLI
1.2、初始化项目 vue-web
1.2.1、测试 vue-web 是否安装成功
1.3、启动 Ganache 客户端
2、代码部分
2.1、创建 MSHK.Vue 页面展示文件
2.2、修改 Vue 路由
2.3、复制合约文件到 Vue 目录
2.4、最终修改 MSHK.Vue 文件
3、验证效果
1、基础环境准备
1.1、安装 Vue 和 Vue CLI
# 最新稳定版
$ npm install vue
added 21 packages in 6s
$ npm i -g @vue/cli-init
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated vue-cli@2.9.6: This package has been deprecated in favour of @vue/cli
npm WARN deprecated coffee-script@1.12.7: CoffeeScript on NPM has moved to "coffeescript" (no hyphen)
added 259 packages in 16s
1.2、初始化项目 vue-web
该命令将安装并执行官方的 Vue
项目脚手架工具create-vue
。您将看到一些可选功能的提示,例如 TypeScript
和测试支持:
$ vue init webpack vue-web
? Project name vue-web
? Project description A Vue Web3 Project(mshk.top)
? Author lion <lion.888@gmail.com>
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) npm
vue-cli · Generated "vue-web".
# Installing project dependencies ...
# ========================
npm WARN deprecated source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated
npm WARN deprecated flatten@1.0.3: flatten is deprecated in favor of utility frameworks such as lodash.
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated eslint-loader@1.9.0: This loader has been deprecated. Please use eslint-webpack-plugin
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated browserslist@1.7.7: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
npm WARN deprecated browserslist@1.7.7: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
npm WARN deprecated browserslist@1.7.7: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
npm WARN deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
npm WARN deprecated browserslist@2.11.3: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
npm WARN deprecated circular-json@0.3.3: CircularJSON is in maintenance only, flatted is its successor.
npm WARN deprecated html-webpack-plugin@2.30.1: out of support
npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
npm WARN deprecated chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies
npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
npm WARN deprecated chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies
npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
npm WARN deprecated extract-text-webpack-plugin@3.0.2: Deprecated. Please use https://github.com/webpack-contrib/mini-css-extract-plugin
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated babel-eslint@8.2.6: babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.
npm WARN deprecated bfj-node4@5.3.1: Switch to the `bfj` package for fixes and new features!
npm WARN deprecated uglify-es@3.3.9: support for ECMAScript is superseded by `uglify-js` as of v3.13.0
npm WARN deprecated svgo@0.7.2: This SVGO version is no longer supported. Upgrade to v2.x.x.
npm WARN deprecated svgo@1.3.2: This SVGO version is no longer supported. Upgrade to v2.x.x.
npm WARN deprecated core-js@2.6.12: core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.
added 1448 packages in 1m
Running eslint --fix to comply with chosen preset rules...
# ========================
> vue-web@1.0.0 lint
> eslint --ext .js,.vue src "--fix"
# Project initialization finished!
# ========================
To get started:
cd vue-web
npm run dev
Documentation can be found at https://vuejs-templates.github.io/webpack
也可以通过
vue ui
命令,打开一个带有 GUI 的浏览器窗口,引导您完成项目创建过程。
创建项目后的目录结构简要说明:
.
|____index.html # 入口页面
|____config # Vue 配置文件目录
...
|____node_modules # 项目依赖包管理目录
...
|____static # 静态资源目录
...
|____build # 构建脚本目录
...
|____src # 项目代码目录
| |____App.vue # 根组件
| |____main.js # 入口 js 文件
| |____components # 公共组件目录
| | |____HelloWorld.vue
| |____assets # 资源目录
| | |____logo.png
| |____router # 路由配置
| | |____index.js
1.2.1、测试 vue-web 是否安装成功
测试项目是否安装成功,运行以下命令
$ npm run dev
如果能够看到下面的页面,说明安装成功
1.3、启动 Ganache 客户端
关于 Ganache
的安装,请参考这篇文章《如何通过Node调用Web3智能合约?》
使用以下命令,启动 Ganache
:
$ ganache --host=localhost
ganache v7.1.0 (@ganache/cli: 0.2.0, @ganache/core: 0.2.0)
Starting RPC server
Available Accounts
==================
(0) 0x7F9c596Dc21B9F00cD3C415d9C78eBF0FDaEe6d4 (1000 ETH)
(1) 0x961Ed5661701bAF698681d602C311E3eF0DB9dD6 (1000 ETH)
(2) 0x3ff9A35cd02f4451f633f9A33E556B49C0918fA3 (1000 ETH)
(3) 0x366bcf665E6F477720C77854A3f9D854CbA72E9c (1000 ETH)
(4) 0x8D1637D0eBa9104af246153eE1d68dF86ac463f0 (1000 ETH)
(5) 0x90c2516Ab57f19dCb48348947B3169fFde761c8e (1000 ETH)
(6) 0xB94316C97Fbe16889F8b13fA8fc3226Ba8e58E4B (1000 ETH)
(7) 0x18F513AD33dDf7Fd30120334940CF7525D518cD7 (1000 ETH)
(8) 0x30268d3977f8a6D44066D0d2Ce193cBe94E9E3AD (1000 ETH)
(9) 0x83FC218602D55A9340e73141A8624Ce862f1B48E (1000 ETH)
Private Keys
==================
(0) 0x52c71540c4e40a920fbfd9a30551c91a6beeb493a3c7cd2c33fc3d45ca1c3c56
(1) 0x543f0aa499237490189adeca4c04b78b3aa706d7617e71b3298212e6dee9ad30
(2) 0x968e7424ac50048037d03edd98cedae2aa5c943d7af0cab858d538f10b3d5280
(3) 0x5cb3639356cdb87132d5b09e037a87d7e60f2687dbf391bddac566bad19aff2a
(4) 0xfa1a3e0fb0361c847183bff00203095a94987dd9e0540888d8e1d23028d90128
(5) 0x4ad4bf3d561b1e70059e1782a42c1b2fe13c29a4ce1ad47caf33ca1cfb03f252
(6) 0x2be1932f5ceaa32c4c441b99287dd8eddf698ca9412a5b053528837736168389
(7) 0x8d1ebed03bb732c2187eb5d53a64750fb82b50c4eeb9b5747c670c744aaf2666
(8) 0xcf9e231c5259daf05a8475201212e2ad5be3519e012b089e0e2aca2dda626d98
(9) 0x668b2842efca67e5802ba8150cf8621c3e83fe76a738c0e52b3beaf94714e4e8
HD Wallet
==================
Mnemonic: trick fantasy adult reopen saddle suggest action wave wonder box gospel country
Base HD Path: m/44'/60'/0'/0/{account_index}
Default Gas Price
==================
2000000000
BlockGas Limit
==================
30000000
Call Gas Limit
==================
50000000
Chain Id
==================
1337
RPC Listening on localhost:8545
2、代码部分
2.1、创建 MSHK.Vue 页面展示文件
在 ./src/components
目录下,创建 MSHK.vue
内容如下:
$ cat ./src/components/MSHK.vue
<script>
export default {
data () {
return {
greeting: 'Hello World! Welcome to mshk.top'
}
}
}
</script>
<template>
<p class="greeting">{{ greeting }}</p>
</template>
<style>
.greeting {
color: red;
font-weight: bold;
}
</style>
修改 ./src/APP.vue
内容,去掉 Logo ,修改后的内容如下:
$ cat ./src/App.vue
<template>
<div id="app">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
2.2、修改 Vue 路由
在路由文件 ./src/router/index.js
中重新挂载刚刚创建的 MSHK.vue
,去掉原来 HelloWorld
的注释,修改后的文件内容如下:
$ cat ./src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
// import HelloWorld from '@/components/HelloWorld'
import MSHK from '@/components/MSHK'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'MSHK',
component: MSHK
}
]
})
此时浏览页面,可以看到我们自定义的组件已经生效,如下图:
2.3、复制合约文件到 Vue 目录
将《如何通过Node调用Web3智能合约?》文章中使用 Truffle
编译后的 MSHK.sol
文件 ./build/contracts/MSHK.json
,复制到当前目录下的 ./static/ABI/
目录中,复制后的目录如下:
$ ll ./static/ABI
total 80
-rw-r--r-- 1 lion staff 40604 May 22 00:42 MSHK.json
2.4、最终修改 MSHK.Vue 文件
$ cat ./src/components/MSHK.vue
<template>
<div>
<span v-html="msg"></span>
<p class="greeting">{{ greeting }}</p>
<button v-on:click="readAccount">读取当前帐号</button>
<button v-on:click="deployContract">部署合约</button>
<button v-on:click="readContract">读取合约</button>
</div>
</template>
<script>
import Web3 from 'web3'
import Contract from 'web3-eth-contract'
import MSHKABIContractABI from '../../static/ABI/MSHK.json' // 引入 Truffle 编译后的合约文件
export default {
name: 'MSHK.TOP',
data () {
return {
ContractABI: MSHKABIContractABI, // 调用 智能合约的 JSON 接口
msg: '',
greeting: 'Hello World! Welcome to mshk.top',
GanacheUrl: 'localhost:8545',
CurrentAccount: null,
NewContract: null
}
},
methods: {
readAccount () {
var obj = this
// 读取帐号列表
this.web3.eth.getAccounts().then(function (accounts) {
obj.CurrentAccount = accounts[0]
obj.msg = '当前读取到的帐号为:' + obj.CurrentAccount // 读取 Ganache 创建的第一个帐号
})
},
readContract () { // 读取合约
var obj = this
// 使用 JSON 接口、合约地址,创建一个新的合约实例,其所有方法和事件都在其json 接口对象中定义。
var contract = new Contract(this.ContractABI.abi, obj.NewContract.options.address)
// 调用合约中的 hello 方法,并赋值到 this.msg 中,输出到页面
contract.methods.hello().call().then(s => {
this.msg = s
})
},
deployContract () { // 部署合约
var obj = this
if (obj.CurrentAccount == null) {
obj.msg = '请先读取帐号'
return
}
var outMsg = []
var contract = new Contract(this.ContractABI.abi, this.ContractAddr)
contract.options.data = this.ContractABI.deployedBytecode
contract.deploy({
data: obj.ContractABI.bytecode // 合约的字节码
})
.send({
from: obj.CurrentAccount, // 交易的发送地址
gas: 1500000, // 交易提供的最大 Gas
gasPrice: '30000000000000' // 用于此交易的以 wei 为单位的 gas 价格
})
.on('error', function (error) { // 如果在发送过程中发生错误,则触发。
obj.msg = 'error:' + error
})
.on('transactionHash', function (transactionHash) { // 当交易哈希可用时触发。
console.log(transactionHash)
})
.on('receipt', function (receipt) { // 当交易收据可用时触发。来自合约的收据将没有属性,而是具有事件名称作为键和事件作为属性的属性。
outMsg.push('Transaction:' + receipt.transactionHash) // 交易哈希
outMsg.push('Contract created:' + receipt.contractAddress) // 合约创建的地址
outMsg.push('Gas usage:' + receipt.gasUsed) // 使用的Gas
outMsg.push('Block number:' + receipt.blockNumber) // 区块
obj.msg = outMsg.join('<br/ >')
}).then(function (newContractInstance) {
obj.NewContract = newContractInstance // instance with the new contract address
})
}
},
mounted () {
if (typeof this.web3 !== 'undefined') {
// web3.currentProvider当前提供者
this.web3 = new Web3(this.web3.currentProvider)
} else {
// set the provider you want from Web3.providers
this.web3 = new Web3('http://' + this.GanacheUrl)
}
// 合约本地 Ganache 的RPC接口
Contract.setProvider('ws://' + this.GanacheUrl)
}
}
</script>
<style>
.greeting {
color: red;
font-weight: bold;
}
</style>
3、验证效果
此时要保证 Ganache
在运行,同时已经通过 npm run dev
启动 Vue
项目,浏览 http://localhost:8080/ 能够看到如下效果:
项目源码:https://github.com/idoall/vue-node-npm-ganache-web3
博文作者:迦壹
博客地址:Vue+NodeJs+Ganache 部署、调用 web3 智能合约
转载声明:可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明,谢谢合作!