Compartilhamento de tecnologia

6-5, links do navegador web3 para o blockchain (prática de reação ao blockchain)

2024-07-12

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

6-5 O navegador web3 se conecta ao blockchain (chamando o contrato de leitura e gravação para se conectar à metamask)

Aqui está a interação entre o navegador e o contrato inteligente

Duas bibliotecas

Web3
Contrato trufa //trufa simplesmente envolve o contrato front-end no link, o que é mais fácil de usar.

virprojeto de reaçãono diretório raiz (criado no Capítulo 1),
Insira a descrição da imagem aqui

Recrie um projeto de reação aqui
https://blog.csdn.net/u012118993/article/details/87288516
reactCrie um novo projetoUse create-react-app para criar rapidamente um projeto react

(1)npm install -g create-react-app Instalação global (instalar no todo)

(2)create-react-app reactproject Crie um novo projeto react e nomeie-o (nota: o nome do projeto não pode ter letras maiúsculas)

(3)cd reactproject Entre na pasta através do comando e prepare-se para executar o projeto

(4)npm start Execute o projeto

E:trufflewoniu-pet-shop
  • 1

Criado no diretório de trufas
Insira a descrição da imagem aqui

Instale os seguintes arquivos no projeto react
Instale o web3 (instale na pasta abaixo)

npm install web3 --save
  • 1

Insira a descrição da imagem aqui

Em seguida, instale o contrato de trufas

npm install truffle-contract --save
  • 1

Demonstração concluída

1. Contrato de link
2. Executar a função interna do contrato
3. Adicionar suporte à biblioteca de interface do usuário ant.design
4. Conclua o projeto

Insira a descrição da imagem aqui

nota novo
Insira a descrição da imagem aqui

Conteúdo em App.js
do seguinte modo

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

Insira a descrição da imagem aqui

Se o plug-in metamask estiver instalado no navegador

Variáveis ​​globais possuem valores no navegador
Insira a descrição da imagem aqui

Metamask pode ser vinculado manualmente ou automaticamente
Insira a descrição da imagem aqui

Inicie o script. Anteriormente, web3 estava indefinido no console do navegador porque era uma página da web vazia no momento.

Comece no petshop construído pelo projeto react

Npm start
  • 1

Abra no navegador
http://localhost:3000/

efeitos de vídeo
Insira a descrição da imagem aqui

Vídeo para instalar novos pacotes
Insira a descrição da imagem aqui
Insira a descrição da imagem aqui

Recebi um erro porque a função init não foi salva.

Insira a descrição da imagem aqui

O efeito real após o sucesso é o seguinte:
Insira a descrição da imagem aqui

Insira a descrição da imagem aqui

recém-ingressado

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

Após salvar o código alterado, acesse a rede novamente sem fechar e re-npm start

Atualize agora
Claro, não há janela pop-up neste momento. Haverá uma janela pop-up após a exclusão da carteira metamask.

Neste momento, use o navegador Chrome sem carteira para acessar
Insira a descrição da imagem aqui

Uma janela pop-up aparece, mas alguns caracteres estão distorcidos

Adicione o código novamente

Insira a descrição da imagem aqui

Todos os códigos são os seguintes

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

Atualize a interface da seguinte maneira
Insira a descrição da imagem aqui

Obteve o endereço do contrato
Insira a descrição da imagem aqui

Use as variáveis ​​acima para obter o endereço local e o endereço da conta padrão da metamask.
Insira a descrição da imagem aqui

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

A razão pela qual o endereço da metamask não pode ser obtido aqui é a acima
https://blog.csdn.net/weixin_39421014/article/details/103323245

Você pode primeiro desativar as permissões de privacidade da metamask.
https://www.freesion.com/article/8518937500/
Configurações do modo de privacidade e código JS compatível
Insira a descrição da imagem aqui

https://blog.csdn.net/JackieDYH/article/details/115380677?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
Obtenha informações da conta

Após modificar o código, modifique a parte da função de inicialização.

Você pode usar a metamask para vincular ao site e imprimir o endereço atual da metamask.
Insira a descrição da imagem aqui

Em seguida, faça as alterações no código do evento click
Insira a descrição da imagem aqui

Clicar em adoção aqui abrirá uma caixa para pagamento, pois a função de gravação precisa ser chamada e gravada na cadeia. Não há necessidade de transferir dinheiro para adoção aqui, mas é necessária uma taxa de manuseio dos pais.

Chame com sucesso a função que precisa ser escrita no blockchain localmente (como segue quando o botão é clicado)
Insira a descrição da imagem aqui

Todo o código que finalmente foi executado com sucesso é o seguinte:

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 as funções foram executadas com sucesso, incluindo funções de leitura e escrita.

Este código ainda apresenta algumas falhas. Se a transação falhar, um erro será relatado e a página também reportará um erro.
Quando você clica em rejeitar ou sair diretamente
Insira a descrição da imagem aqui

Insira a descrição da imagem aqui

A próxima etapa é embelezar a IU