6-5,web3浏览器链接区块链(react+区块链实战)

6-5,web3浏览器链接区块链(react+区块链实战)

  • [6-5 web3浏览器链接区块链(调用读写合约与metamask联动)](#6-5 web3浏览器链接区块链(调用读写合约与metamask联动))

6-5 web3浏览器链接区块链(调用读写合约与metamask联动)

这里就是浏览器端和智能合约的交互

两个库

Web3

Truffle contract //truffle在链接前端合约简单包了一层,比较好用

来到react项目的根目录下(在第一章进行了创建),

这里重新创建一个react项目

https://blog.csdn.net/u012118993/article/details/87288516

react创建新项目 使用creat-react-app快速新建一个react项目

(1)npm install -g create-react-app 全局安装(安装到整体)

(2)create-react-app reactproject 新建并对react项目进行命名(注:项目名称不能有大写)

(3)cd reactproject 通过命令进入文件夹内部,准备运行项目

(4)npm start 运行项目

E:\truffle\woniu-pet-shop

在truffle目录下创建

在react的项目下安装下面的文件

安装web3(安装到文件夹下面)

npm install web3 --save

再安装truffle-contract

npm install truffle-contract --save

Demo完成

1.链接合约

2.执行一下合约内部函数

3.添加ant.design ui库支持

4.完成项目

注意新的

App.js中的内容

如下

import React from 'react'
import Web3 from 'web3'
import TruffleContract from 'truffle-contract'
import AdoptionJson from './truffle/build/contracts/Adoption.json'	//引入前面智能合约编译好得到的json文件





class App extends React.Component{
	constructor(props){
		super(props)
		this.web3 = null
		this.Adoption = null
		this.init()

		this.state = {
			//name:'woniu'
		}
	}

	init(){
		//如果网页中的web3不是undefined
		if(typeof window.web3 != 'undefined'){
		}
	}

	render(){
		return <button></button>//hello,{this.state.name}
	}
}

export default App

如果浏览器中装入了metamask插件

在浏览器中全局变量就有值

可以手动链接metamask,也可以自动连接

进行脚本启动,之前web3在浏览器控制台undefined是因为空网页,此时

在react项目自建的petshop中启动

Npm start

在浏览器打开

http://localhost:3000/

视频效果

视频安装新的包

自己的有报错,原因init函数没有保存

实际成功后如下效果

新加入

init(){
		//如果网页中的web3不是undefined
		if(typeof window.web3 != 'undefined'){
			this.web3Provider = window.web3.currentProvider;	//metamask内置了web3的实例,实际可以手动链接
		}else{
			alert('请按照metamask')
		}
	}

更改代码保存后,再次访问网络,无需关闭重新npm start

此时刷新一下

当然这时无弹窗,将metamask钱包删掉之后就有弹窗

这时使用chrome没有钱包的浏览器访问

有弹窗出现,但是有些乱码了

又加入代码

所有代码如下

import React from 'react'
import Web3 from 'web3'
import TruffleContract from 'truffle-contract'
import AdoptionJson from './truffle/build/contracts/Adoption.json'	//引入前面智能合约编译好得到的json文件

//1.链接合约
//2.执行一下合约内部函数
//3.添加ant.design ui库支持
//4.完成项目
class App extends React.Component{
	constructor(props){
		super(props)
		this.web3 = null
		this.Adoption = null
		this.init()

		this.state = {
			//name:'woniu'
		}
	}

	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()

	}

	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()
		console.log(adopters)
	}

	render(){
		return <button></button>//hello,{this.state.name}
	}
}

export default App

刷新界面如下

获取到合约的address了

使用上方的变量可以获取本地的地址及metamask的默认账号地址了

https://blog.csdn.net/weixin_41937552/article/details/106990561?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-1\&spm=1001.2101.3001.4242

这里无法获得metamask的地址的原因如上

https://blog.csdn.net/weixin_39421014/article/details/103323245

可以先把metamask的隐私权限关闭

https://www.freesion.com/article/8518937500/

隐私模式的设置与兼容JS代码

https://blog.csdn.net/JackieDYH/article/details/115380677?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0\&spm=1001.2101.3001.4242

获取账户信息

经过代码的修改后在初始化的函数部分修改,

可以使用metamask链接网站了,并且能够打印出当前的metamask地址

接下来进行点击事件的代码更改

此处点击领养会弹出框用来支付的,因为要调用写入函数,写到链上的,此处的领养不用转钱但需要父手续费

本地成功调用需要写入区块链的函数(当点击按钮时如下)

最终成功运行的所有的代码如下:

import React from 'react'
import Web3 from 'web3'
import TruffleContract from 'truffle-contract'
import AdoptionJson from './truffle/build/contracts/Adoption.json'	//引入前面智能合约编译好得到的json文件

//1.链接合约
//2.执行一下合约内部函数
//3.添加ant.design ui库支持
//4.完成项目
class App extends React.Component{
	constructor(props){
		super(props)
		this.web3 = null
		this.Adoption = null
		this.init()

		this.state = {
			//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()
		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()
	}

	render(){
		//onclick点击事件,调用领养函数
		return <button onClick={()=>this.adopt(2)}>领养第二个</button>//hello,{this.state.name}
	}
}

export default App

已经成功执行所有的函数,读取写入函数

此代码还有一些缺陷,若交易失败会报错,页面也会报错,

点击拒绝,或者直接退出时

接下来就是美化ui

相关推荐
奶糖 肥晨2 小时前
react是什么?
前端·react.js·前端框架
yunteng5212 小时前
零知识证明-ZK-SNARKs基础(七)
区块链·零知识证明·zk-snarks·ricp·qap
山师第一深情5 小时前
solidity-19-fallback
区块链
zhuqiyua5 小时前
TVM和EVM的比较
区块链·智能合约·ton
sino_sound5 小时前
伦敦金的交易差价意味着什么?
人工智能·金融·区块链
清 晨5 小时前
开放的数据时代:Web3和个人隐私的未来
web3·去中心化·智能合约·隐私保护
dingzd957 小时前
数字世界的新秩序:探索Web3的前景
web3·去中心化·智能合约
黑色叉腰丶大魔王9 小时前
什么是区块链,以及应用场景
去中心化·区块链·分布式账本
qiquandong11 小时前
场外期权或成暴利工具?!应该怎么做场外期权?
区块链
链科天下17 小时前
全球国家比特币持有量排名!各国政府合谋能否推翻比特币?数字货币的时代已经来临!
区块链