6-7 宠物领养开发及相关代码(react+区块链实战)
来到ant-design
https://ant.design/index-cn
https://ant.design/components/layout-cn/
来到布局
选择一个简单的布局即可
会显示出所有的相关界面的代码
根据对应界面的代码在我们的react项目woniu-pet-shop中的App.js中进行更改
如下
刷新页面的效果如下
页面的基本雏形如下
要做宠物的领养,就要将宠物的数组拿出来
在前面下载的petshop改名为truffle中放在了react项目下的src下的petsjson
这是宠物的术语名字图片
在区块链中写图片非常昂贵,大部分情况下在区块链中写id或者一些出生时间关键数据
将宠物的json直接引入
然后在项目中的render中的content直接引入
Pets类似数组,在init初始化时就有加一下东西
将truffle下的src下的狗的图片复制出来
放在react项目下的public下的images中
使用ant中的栅格系统,使用页面整个横向布局
可以将前面引入的Jason数组渲染出来
所有宠物名打印出来了
接下来将其图片也打印出来
在App.css中加入图片的宽度使其看起
现在好看多了
总共16个宠物,看起来和谐多了
重点低下逻辑,显示名字后要有领养按钮,不一定存在的,如刚才第一个,第2个已经领养过了,应显示已被领养
//判断当前宠物是否被领养(是否当前的领养地址为初始地址)
isActive(i){
return this.state.adopters[i] == this.initAddress
}
若未被领养,显示领养的按钮,若已领养就显示被领养的字样
基本功能已经完成再加入按钮的事件即可,以及加入class center使其居中,type样式为蓝色的
如下
在css中加入居中的样式
核心就是如何编写智能合约,测试合约,如何web端和智能合约交互
App.js所有代码如下
import React from 'react'
import Web3 from 'web3'
import TruffleContract from 'truffle-contract'
import AdoptionJson from './truffle/build/contracts/Adoption.json' //引入前面智能合约编译好得到的json文件
import { Button } from 'antd'
import { Layout, Menu, Breadcrumb } from 'antd'
import { Row, Col } from 'antd'
import './App.css'
import pets from "./truffle/src/pets.json"
const { Header, Content, Footer } = Layout;
//1.链接合约
//2.执行一下合约内部函数
//3.添加ant.design ui库支持
//4.完成项目
class App extends React.Component{
constructor(props){
super(props)
this.web3 = null
this.Adoption = null
this.initAddress = '0x'+'0'.repeat(40) //判断地址是否为初始值
this.init()
this.state = {
//所有领养者的数据
adopters:[]
//name:'woniu'
}
}
async init(){
//如果网页中的web3不是undefined
//if(typeof window.web3 != 'undefined'){
// this.web3Provider = window.web3.currentProvider; //metamask内置了web3的实例,实际可以手动链接
//}else{
// alert('please install metamask')
//}
//this.web3 = new Web3(this.web3Provider) //将我们的this.web3Provider装载进来
//this.initAdoption()
/* 新版的方式 */
//var web3Provider;
if (window.ethereum) {
this.web3Provider = window.ethereum;
try {
// 请求用户授权
await window.ethereum.enable();
} catch (error) {
// 用户不授权时
console.error("User denied account access")
}
} else if (window.web3) { // 老版 MetaMask Legacy dapp browsers...
this.web3Provider = window.web3.currentProvider;
} else {
this.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
}
this.web3 = new Web3(this.web3Provider);//web3js就是你需要的web3实例
this.web3.eth.getAccounts(function (error, result) {
if (!error)
console.log(result)//授权成功后result能正常获取到账号了
//this.account = result
});
//this.account =result
//this.account =account
this.initAdoption()
}
initAdoption(){
this.Adoption = TruffleContract(AdoptionJson) //使用TruffleContract传入编译后的合约,然后创建实例,可以调用合约内部函数
this.Adoption.setProvider(this.web3Provider) //设置来源,链接合约
return this.markAdopted()
}
//部署,这个是异步的,使用this.Adoption.deployed().then()也可以,这里用
//this.markAdopted(){
//部署链接一下
// const adoptionInstance = this.Adoption.deployed().then()
//}
async markAdopted(){
//部署链接一下
//await同步方式获取异步数据
const adoptionInstance = await this.Adoption.deployed() //部署,这个是异步的,使用this.Adoption.deployed().then()也可以,这里用
//调用合约内部函数getAdopters
const adopters = await adoptionInstance.getAdopters.call()
this.setState({adopters}) //此时得到所有领养者的信息,方便后续的渲染render
console.log(adopters)
}
async adopt(petId){
//const account = window.web3.eth.defaultAccount //获取metamask中默认的账户
// 授权获取账户
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
const myAccount = accounts[0]; //获取当前metamask的地址
const adoptionInstance = await this.Adoption.deployed() //再次进行部署
await adoptionInstance.adopt(petId,{from:myAccount}) //调用adopt只传递唯一一个参数,以及来源之前获取的地址,进行写入函数
this.markAdopted()
}
//判断当前宠物是否被领养(是否当前的领养地址为初始地址)
isActive(i){
return this.state.adopters[i] == this.initAddress
}
//此处进行界面的渲染
render(){
return (
//布局 //设置间距40
//每个方块Col,以行24个,6,相当于每行4个宠物
<Layout className="layout">
<Header>
</Header>
<Content style={{ padding: '20px 50px' }}>
<Row gutter={40}>
{
pets.map((v,i)=>{
return (
<Col span='6' key={i}>
<img src={v.picture} alt=""/>
<div className = "center">
<p className="name">{v.name}</p>
{
this.isActive(i)
?<Button type='primary' onClick={()=>this.adopt(i)}>领养</Button>
:<span>被领养</span>
}
</div>
</Col>
)
})
}
</Row>
</Content>
<Footer style={{ textAlign: 'center' }}>build by woniu ©2018</Footer>
</Layout>
)
//onclick点击事件,调用领养函数
//return <Button type='primary' onClick={()=>this.adopt(2)}>领养第二个</Button>//hello,{this.state.name}
}
}
export default App
App.css 所有代码如下
@import '~antd/dist/antd.css';
img{
width:100%;
}
.center{
text-align:center;
margin:20px;
}