接上一篇,接着开发我们的前端吧!!
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(
{this.state.creatorFundings}
)
}
}
(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
})
return(
{
cards
}
)}
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(
{projectName}
剩余时间:{leftTime}
参加临港公路比赛
已筹
{balance}eth
已达
{percent}%
参与人数
{investorCount}人
)}
export default CardList
写的有点渣,,改太多代码了。。。。马上写下一篇吧。。。