以太坊彩票DAPP实战(二)

一、项目介绍

彩票项目使用React技术来进行开发。该项目需要部署到一个Web服务器上运行。后台通过Web3与以太网区块链上读取数据。

(1)项目模块划分

项目核心模块主要分为:web3(负责提供引入web3的公共代码)、合约相关(提供了操作合约的方法)、界面相关。

(2)模块交互图示

App.js作为控制器,负责不同模块之间的调度。

二、环境准备

(1)下载create-react-app包,然后执行create-react-app命令创建一个空的项目。

>> npm install -g create-react-app
>> create-react-app lottery

创建成功后,在命令窗口中进入项目所在路径,执行npm run start命令启动项目。启动成功后,在浏览器上访问http://localhost:3000,如果看到如下界面代表React安装成功。

(2)安装相关模块

第一步:在package.json文件中加入依赖。

"solc": "^0.4.25",
"truffle-hdwallet-provider": "0.0.3",
"web3": "^1.0.0-beta.36"

第二步:执行npm install命令下载依赖包。

(3)清理工程

第一步:进入src目录,除了App.js和index.js文件以外,删除其他文件;

第二步:删除App.js和index.js对删除文件依赖的代码。

删除后的App.js文件:

import React from 'react';

function App() {
  return (
    <h1>Hello world</h1>
  );
}

export default App;

删除后的index.js文件:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

 

三、部署合约

(1)编译合约

在项目根路径下创建01_compile.js文件,代码如下所示:

let solc = require('solc') // 0.5.8
let fs = require('fs')

// 1.读取合约代码
let contractCode = fs.readFileSync('./contracts/lottery.sol', 'utf-8')

// 2.编译合约代码
let output = solc.compile(contractCode, 1)
// console.log(output)

// 3.执行导出操作
module.exports = output['contracts'][':Lottery']

(2)部署合约

在项目根路径下创建02_deploy.js文件,代码如下所示:

let {bytecode, interface} = require('./01_compile')
let hdWalletProvider = require('truffle-hdwallet-provider')
let Web3 = require('web3')

// 2.创建web3实例
let web3 = new Web3()

// 提供商地址
let mnemonic = 'letter debris ready dog window mountain front truth project bottom merit valley'

// 提供商地址,从infura.io网站复制过来
let providerUrl = 'https://ropsten.infura.io/v3/3d30b778a38b41df8f502d8b8e3ee37b'

// 创建HDWalletProvider对象
let provider = new hdWalletProvider(mnemonic, providerUrl)

// 指定服务提供商
web3.setProvider(provider)

// 4.通过abi接口创建合约实例
let contract = new web3.eth.Contract(JSON.parse(interface))

// 5.部署合约
let deploy = async () => {
    // 获取账户,调用该方法每次只会返回一个帐号
    let accounts = await web3.eth.getAccounts()
    // 创建合约实例
    let contractInstance = await contract.deploy({
        data : bytecode,
    }).send({
        from : accounts[0],
        gas : '3000000',
    })
    console.log("contract instance address : ", contractInstance.options.address)
}

deploy()

(3)测试合约部署是否成功

第一步:打开infura.io,修改网络为Ropsten测试网络。

第二步:在命令行项目所在路径下执行命令。

>> node 02_deploy.js

如果看到合约地址,代表部署成功。

 

四、使用用户的Provider实例化合约

(1)按照下图创建相应的目录和文件。

image-20180913063630463

(2)把web3实例化的代码定义在InitWeb3.js文件中,并导出web3的实例。

// 导包
let Web3 = require('web3')

// 创建web3实例
let web3 = new Web3()

// 使用用户自己的Provider来设置Web3实例
let provider = window.web3.currentProvider

// 设置Provider
web3.setProvider(provider)

// 导出web3
module.exports = web3

值得注意的是,web3实例应该使用用户的服务提供商Provider。如果浏览器上安装了metamask插件,那么metamask就会自动创建一个web3实例,实例中就已经包含了用户的Provider。我们可以通过window.web3.currentProvider获取浏览器用户的Provider,然后再设置到应用的web3实例中。

(3)实例化合约

第一步:abi接口可以从remix中进行复制。

第二步:复制合约地址。

第三步:创建并导出合约实例。

let web3 = require('../utils/InitWeb3')

// ABI接口
let abi = [ { "constant": false, "inputs": [], "name": "tuiJiang", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "getPlays", "outputs": [ { "name": "", "type": "address[]" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "getWinner", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [], "name": "play", "outputs": [], "payable": true, "stateMutability": "payable", "type": "function" }, { "constant": true, "inputs": [], "name": "getRound", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "getManagerAddress", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "getAmount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [], "name": "kaiJIang", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "payable": false, "stateMutability": "nonpayable", "type": "constructor" } ]

// 合约地址
let address = '0x3be4aef4d73f53981f8d69469f84055f97ecee6f'

// 获取合约实例
let contractInstance = new web3.eth.Contract(abi, address)
console.log("contract address : ", contractInstance.options.address)

// 导出合约实例
module.exports = contractInstance

(4)测试代码

第一步:在App.js文件导入导入lottery.js。

import './eth/lottery'

第二步:启动React。

>> npm run start

第三步:在浏览器上访问localhost:3000,然后在页面上右击鼠标 -> 检查 -> Console,如果看到合约地址,代表实例化成功。

猜你喜欢

转载自blog.csdn.net/zhongliwen1981/article/details/90039754