Compartir tecnología

6-5, enlaces del navegador web3 a blockchain (práctica de reacción de blockchain)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

6-5 enlaces del navegador Web3 a la cadena de bloques (llamando al contrato de lectura y escritura para vincularlo con la metamáscara)

Aquí está la interacción entre el navegador y el contrato inteligente.

Dos bibliotecas

Web3
Contrato de trufa //trufa simplemente envuelve el contrato de front-end en el enlace, lo que es más fácil de usar.

venirreaccionar proyectoen el directorio raíz (creado en el Capítulo 1),
Insertar descripción de la imagen aquí

Recrea un proyecto de reacción aquí.
https://blog.csdn.net/u012118993/article/details/87288516
reaccionarCrea un nuevo proyectoUtiliza creat-react-app para crear rápidamente un proyecto de reacción

(1)npm install -g create-react-app Instalación global (instalar al conjunto)

(2)create-react-app reactproject Cree un nuevo proyecto de reacción y asígnele un nombre (nota: el nombre del proyecto no puede tener letras mayúsculas)

(3)cd reactproject Ingrese a la carpeta a través del comando y prepárese para ejecutar el proyecto.

(4)npm start ejecutar el proyecto

E:trufflewoniu-pet-shop
  • 1

Creado en el directorio de trufas.
Insertar descripción de la imagen aquí

Instale los siguientes archivos en el proyecto de reacción.
Instale web3 (instale en la carpeta a continuación)

npm install web3 --save
  • 1

Insertar descripción de la imagen aquí

Luego instale el contrato de trufa

npm install truffle-contract --save
  • 1

Demostración completada

1. Contrato de enlace
2. Ejecutar la función interna del contrato.
3. Agregue soporte para la biblioteca ant.design ui
4. Completa el proyecto

Insertar descripción de la imagen aquí

nota nueva
Insertar descripción de la imagen aquí

Contenidos en App.js
como sigue

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

Insertar descripción de la imagen aquí

Si el complemento metamask está instalado en el navegador

Las variables globales tienen valores en el navegador.
Insertar descripción de la imagen aquí

Metamask se puede vincular manual o automáticamente
Insertar descripción de la imagen aquí

Inicie el script. Anteriormente, web3 no estaba definido en la consola del navegador porque era una página web vacía en este momento.

Comience en la tienda de mascotas construida por el proyecto reaccionar.

Npm start
  • 1

Abierta en el navegador
http://localhost:3000/

efectos de vídeo
Insertar descripción de la imagen aquí

Vídeo para instalar nuevos paquetes.
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí

Se informó mi propio error porque la función de inicio no se guardó.

Insertar descripción de la imagen aquí

El efecto real después del éxito es el siguiente:
Insertar descripción de la imagen aquí

Insertar descripción de la imagen aquí

recién unido

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

Después de guardar el código modificado, acceda a la red nuevamente sin cerrar y vuelva a iniciar npm

Actualizarlo ahora
Por supuesto, no hay ninguna ventana emergente en este momento. Habrá una ventana emergente después de eliminar la billetera metamask.

En este momento, use el navegador Chrome sin billetera para acceder
Insertar descripción de la imagen aquí

Aparece una ventana emergente, pero algunos caracteres están confusos.

Agregar código nuevamente

Insertar descripción de la imagen aquí

Todos los códigos son los siguientes.

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

Actualice la interfaz de la siguiente manera
Insertar descripción de la imagen aquí

Obtuve la dirección del contrato.
Insertar descripción de la imagen aquí

Utilice las variables anteriores para obtener la dirección local y la dirección de cuenta predeterminada de la metamáscara.
Insertar descripción de la imagen aquí

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

La razón por la que no se puede obtener la dirección de la metamáscara aquí es la anterior
https://blog.csdn.net/weixin_39421014/article/details/103323245

Primero puedes desactivar los permisos de privacidad de metamask.
https://www.freesion.com/article/8518937500/
Configuración del modo de privacidad y código JS compatible
Insertar descripción de la imagen aquí

https://blog.csdn.net/JackieDYH/article/details/115380677?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
Obtener información de la cuenta

Después de modificar el código, modifique la parte de la función de inicialización.

Puede utilizar metamask para vincular al sitio web e imprimir la dirección actual de metamask.
Insertar descripción de la imagen aquí

A continuación, realice los cambios de código para el evento de clic.
Insertar descripción de la imagen aquí

Al hacer clic en adopción aquí, aparecerá un cuadro de pago, porque es necesario llamar a la función de escritura y escribirla en la cadena. No es necesario transferir dinero para la adopción aquí, pero se requiere una tarifa de manejo de los padres.

Llame con éxito a la función que debe escribirse en la cadena de bloques localmente (como se muestra a continuación cuando se hace clic en el botón)
Insertar descripción de la imagen aquí

Todo el código que finalmente se ejecutó exitosamente es el siguiente:

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101

Todas las funciones se han ejecutado con éxito, incluidas las funciones de lectura y escritura.

Este código todavía tiene algunos defectos. Si la transacción falla, se informará un error y la página también informará un error.
Cuando haces clic en rechazar o salir directamente
Insertar descripción de la imagen aquí

Insertar descripción de la imagen aquí

El siguiente paso es embellecer la interfaz de usuario.