DAPP:众筹项目 (三) goland+react开发dapp

接上一篇,接着开发我们的前端吧!!

1.创建目录结构:

eth 目录:主要是实现合约交互  提供了操作合约的方法

display 目录:主要显示界面

utils:主要是web3 负责提供引入web3的公共代码

2.初始化Web3实例

      在utils目录下创建InitWeb3.js文件,把web3实例化的代码定义在InitWeb3.js文件中,并导出web3实例

在app.js下创建构造函数来获取web3测试一下

然后打开浏览器,你会报这个错,那为什么呢?因为我们找不到用户的provider

解决办法,在浏览器上安装metamask插件,自动创建一个web3实例

附加组件--扩展程序--metamask插件

好的,hello又回来了。。

.....可是又出现了一个问题,为什么 web3.eth.getAccounts() 获取不到用户账号呢??无法使用呢??

       经过反复的试验,原来安装的版本过高,metaMask已经设置了隐私保护了,你没有权限访问。

      那么如何让高版本的metaMask来调用web3呢?

使用window.ethereum来判断是否新版metamask,如果是的话,就调用ethereum.enable() 方法来请求用户授权,这将在用户网页中弹出一个授权对话框,代码如下:

var web3Provider;
if (window.ethereum) {
    web3Provider = window.ethereum;
    try {
        // 请求用户授权
        // 不用同步的方式
        window.ethereum.enable();
    } catch (error) {
        // 用户不授权时
        console.error("User denied account access")
    }
} else if (window.web3) {   // 老版 MetaMask Legacy dapp browsers...
    web3Provider = window.web3.currentProvider;
} else {
    web3Provider = new Web3.providers.HttpProvider('http://localhost:8545');
}
window.web3 = new Web3(web3Provider);//web3就是你需要的web3实例

     当出现Connected就说明你成功了,那让我们看看获取的账户信息吧     

   

3.实例化合约

第一步:在eth目录下创建instance.js文件。

第二步:复制abi。

第三步:复制合约地址。

node 02-deploy.js 
contract instance address :  0x48f294B386669c069dB01D5b9b38446328AD724d

第四步:在instance.js文件中加入以下代码,创建并导出合约实例。

2.界面搭建

     主界面搭建:

(1)在display目录下创建一个TabCenter.js文件,在该文件中定义一个Tab组件。

找组件,

(2)在App.js文件显示主界面内容

(3)在index.js文件中导入css。

4)创建三个子页面,分别对应着Tab1、Tab2、Tab3的内容。

主界面进行修改:

这样就可以直接改写子界面的代码了。现在让我们看看展示吧!!

(5).显示我发起的合约数组

在componentWillMount方法中获取我发起的众筹,并设置到state中

获取我们的创建的众筹合约

   state ={
        creatorFundings :[],
    }
    //在componentWillMount方法中获取我发起的众筹,并设置到state中。
    async componentWillMount() {
        let creatorFundings = await fundingFactoryInstance.methods.getCreatorFundings().call()
        console.log(creatorFundings)
        this.setState({
            creatorFundings
        })
    }
//在render方法中从state获取数据。
    render(){
        return(
            <p>{this.state.creatorFundings}</p>
        )
    }
}

(6),获取每个合约的详细信息(名称,金额。。)

           接下来我们就要根据合约地址获取合约的详细信息,然后再显示在界面上。

              a,获取合约实例

                              abi,地址

                   修改instance.js文件,定义变量分别保存FundingFactory和Funding的ABI和合约地址。

// ABI接口
let factoryABI = [...]
//地址先不指定,在程序中动态增加,完成实例化
let fundingInstance = new web3.eth.Contract(fundingABI)
// 导出合约实例
export {fundingFactoryInstance,fundingInstance,}

                   创建FundingFactory和Funding的实例。因为一个众筹合约对应一个Funding实例,所以,这里需要创建多次Funding实例。而且创建Funding实例时候不需要传入合约地址,可以动态设置。

              b,使用方法调用fundingInstance.methods.projectName().call()

  let details =creatorFundings.map(async  function(fundingAddress){
            console.log(fundingAddress)
            //1.把funding实例拿过来

            // 2.对实例进行填充地址,可以使用了
            let newInstance=newFundingInstance()
            newInstance.options.address = fundingAddress
            //3.使用方法调用fundingInstance.methods.projectName().call()
            let manager = await newInstance.methods.manager().call()
            let projectName = await newInstance.methods.projectName().call()
            let targetMoney = await newInstance.methods.targetMoney().call()
            let supportMoney = await newInstance.methods.supportMoney().call()
            let leftTime = await newInstance.methods.getLeftTime().call()
            let detail ={manager,projectName,targetMoney,supportMoney,leftTime}
            //console.table(detail)
            return detail
        })
        //4.	把多个promise处理成一个promise
        let detailInfo = Promise.all(details)
        detailInfo.then(detail =>{
            console.table(detail)
        })

            看看结果吧:

           将实现的细节提取到界面:

在display目录下新建common子目录,然后在子目录下新建CardList.js文件。

在文件中定义一个CardList方法,该方法负责把details中的合约信息设置到Card组件中。关于semantic-ui的card组件的具体用法,请自行参考:https://react.semantic-ui.com/views/card/#variations-colored

import React from "react";
import {Card,Image,Icon,List, Progress} from "semantic-ui-react";
const src ='/images/daniel.jpg'
const CardList =(props)=>{
    let details=props.details
    console.log('bbb',details)
    let cards = details.map(detail =>{
        return <CardFunding key={detail.fundingAddress} detail1={detail}/>
    })
    return(
    <Card.Group itemsPerRow={4}>
        {
            cards
        }
    </Card.Group>
)}

const CardFunding = (props) => {
    let detail2 =props.detail1
    console.log('de2:'.detail2)
    let {fundingAddress,manager, projectName, targetMoney, supportMoney, leftTime,balance,investorCount}=detail2
    let percent =parseFloat(balance)/parseFloat(targetMoney)*100
    return(
        <Card>
            <Image src='/images/daniel.jpg'/>
            <Card.Content>
                <Card.Header>{projectName}</Card.Header>
                <Card.Meta>
                    <span className='date'>剩余时间:{leftTime}</span>
                    <Progress percent={percent} progress size='small'/>
                </Card.Meta>
                <Card.Description>参加临港公路比赛</Card.Description>
            </Card.Content>
            <Card.Content extra>
                <List horizontal style={
   
   {display: 'flex', justifyContent: 'space-around'}}>
                    <List.Item>
                        <List.Content>
                            <List.Header>已筹</List.Header>
                            <List.Description>{balance}eth</List.Description>
                        </List.Content>
                    </List.Item>
                    <List.Item>
                        <List.Content>
                            <List.Header>已达</List.Header>
                            <List.Description>{percent}%</List.Description>
                        </List.Content>
                    </List.Item>
                    <List.Item>
                        <List.Content>
                            <List.Header>参与人数</List.Header>
                            <List.Description>{investorCount}人</List.Description>
                        </List.Content>
                    </List.Item>
                </List>
            </Card.Content>
        </Card>
)}

export default CardList

写的有点渣,,改太多代码了。。。。马上写下一篇吧。。。

猜你喜欢

转载自blog.csdn.net/qq_38798147/article/details/109259045
今日推荐