区块链研究实验室-基于以太坊猜数字游戏并在IPFS上部署(下)

创建前端应用

1- 创建主入口代码

打开src/js/index.js文件,加入以下代码:

importReactfrom'react'

importReactDOMfrom'react-dom'

importWeb3from'web3'

import'./../css/index.css'

classAppextendsReact.Component{

constructor(props){

super(props)

this.state = {

lastWinner:0,

timer:0

}

}

voteNumber(number){

console.log(number)

}

render(){

return(

Bet for your best number and win huge amounts of Ether

Timer:

{this.state.timer}

Last winner:

{this.state.lastWinner}


Vote for the next number

    {this.voteNumber(1)}}>1

    {this.voteNumber(2)}}>2

    {this.voteNumber(3)}}>3

    {this.voteNumber(4)}}>4

    {this.voteNumber(5)}}>5

    {this.voteNumber(6)}}>6

    {this.voteNumber(7)}}>7

    {this.voteNumber(8)}}>8

    {this.voteNumber(9)}}>9

    {this.voteNumber(10)}}>10

    )

    }

    }

    ReactDOM.render(

    ,

    document.querySelector('#root')

    )

    2- 创建CSS文件

    打开src/css/index.css文件,加入以下代码:

    body{

    font-family:'open sans';

    margin:0;

    }

    ul{

    list-style-type: none;

    padding-left:0;

    display: flex;

    }

    li{

    padding:40px;

    border:2pxsolidrgb(30, 134, 255);

    margin-right:5px;

    border-radius:10px;

    cursor: pointer;

    }

    li:hover{

    background-color:rgb(30, 134, 255);

    color: white;

    }

    li:active{

    opacity:0.7;

    }

    * {

    color:#444444;

    }

    .main-container{

    padding:20px;

    }

    .block{

    display: flex;

    align-items: center;

    }

    .number-selected{

    background-color:rgb(30, 134, 255);

    color: white;

    }

    .bet-input{

    padding:15px;

    border-radius:10px;

    border:1pxsolid lightgrey;

    font-size:15pt;

    margin:010px;

    }

    3- 用webpack打包应用并运行

    在命令行中,使用命令:webpack或者npm run build编译打包。

    以上命令在package.json文件中配置,查看scripts,如下:

    "scripts": {

    "build":"webpack --log-level=debug",//npmrun build等同于webpack命令

    "start":"webpack-dev-server  --port 3030  --inline --content-base ./build"

    },

    然后运行:npm start启动web服务,默认情况下npm init时会生成8080端口的web服务,如果冲突,可以改为其他端口。如本例改为了3030本地端口。

    接着在浏览器中打开: http://127.0.0.1:3030,可以看到如下网页:

    区块链研究实验室-基于以太坊猜数字游戏并在IPFS上部署(下)_第1张图片

    4- 连接智能合约与javascript前端

    在Remix中部署合约,找到ABI文件,并复制。

    在index.js中添加如下代码:

    if(typeofweb3 !="undefined") {

    //启动Metamask

    console.log("Using web3 detected from external source like Metamask")

    this.web3 =newWeb3(web3.currentProvider)

    }else{

    //启用本地以太坊网络或者Truffle的Ganache

    this.web3 =newWeb3(newWeb3.providers.HttpProvider("http://localhost:8545"))

    }

    constcontractAddress ="0xB2bE09289F9f7103964f57aAF04119fcB79d2149"//本案例部署的合约帐号,可换

    constabi = 合约的ABI数组,一个非常长的数组

    constMyContract = web3.eth.contract(abi)

    this.state.ContractInstance = MyContract.at(contractAddress)

    执行合约中函数的基本方法,以合约中的bet函数为例:

    yourContractInstance.bet(7, {// 7为函数参数,即下注的数字

    gas:300000,// Gas

    from: web3.eth.accounts[0],// 用户帐号,accounts是数组,取第一个元素

    value: web3.toWei(0.1,'ether')// 发送金额,单位wei

    }, (err, result) => {...})

    如果调用不需要Gas的方法或者变量,使用如下代码:

    yourContractInstance.maxAmountOfBets((err, result)=>{

    if(result !=null) {...}

    })

    在index.js继续添加以下代码:

    componentDidMount() {

    this.updateState()

    this.setupListeners()

    setInterval(this.updateState.bind(this),10e3)

    }

    updateState() {

    this.state.ContractInstance.minimumBet((err, result) =>{

    if(result !=null) {

    this.setState({

    minimumBet:parseFloat(web3.fromWei(result,'ether'))

    })

    }

    })

    this.state.ContractInstance.totalBet((err, result) =>{

    if(result !=null) {

    this.setState({

    totalBet:parseFloat(web3.fromWei(result,'ether'))

    })

    }

    })

    this.state.ContractInstance.numberOfBets((err, result) =>{

    if(result !=null) {

    this.setState({

    numberOfBets:parseInt(result)

    })

    }

    })

    this.state.ContractInstance.maxAmountOfBets((err, result) =>{

    if(result !=null) {

    this.setState({

    maxAmountOfBets:parseInt(result)

    })

    }

    })

    }

    // 设置监听器

    setupListeners() {

    letliNodes =this.refs.numbers.querySelectorAll('li')

    liNodes.forEach(number=>{

    number.addEventListener('click', event => {

    event.target.className ='number-selected'

    this.voteNumber(parseInt(event.target.innerHTML), done => {

    // Remove the other number selected

    for(leti =0; i < liNodes.length; i++) {

    liNodes[i].className =''

    }

    })

    })

    })

    }

    // 下注

    voteNumber(number, cb) {

    letbet =this.refs['ether-bet'].value

    if(!bet) bet =0.1//默认下注为0.1ETH

    if(parseFloat(bet) 

    alert('You must bet more than the minimum')

    cb()

    }else{

    this.state.ContractInstance.bet(number, {

    gas:300000,

    from: web3.eth.accounts[0],

    value: web3.toWei(bet,'ether')

    }, (err, result) => {

    cb()

    })

    }

    }

    至此,主要的程序已经完成,webpack打包编译,运行npm start,然后在浏览器中打开:http://127.0.0.1:3030可以试玩。

    四、使用IPFS部署应用

    在本章,我们将看到IPFS的强大,她可以方便的部署一个去中心化的应用。

    启动IPFS网络后,运行以下命令:

    ipfsadd-r dist/

    ipfs name publish 上面生成的Hash值

    之后就可以直接用:http://网关/ipfs/网站Hash 进行访问。

    即可在IPFS网络上访问并运行该分布式应用。

    你可能感兴趣的:(区块链研究实验室-基于以太坊猜数字游戏并在IPFS上部署(下))