Cuando la inteligencia artificial se encuentra con blockchain (2)

ce4ec0ce1e2bcc23f9bf62bc3ef22740.gif

Prefacio

Como se mencionó la última vez, Remixes inconveniente depurar en línea. En este artículo, configuraremos una implementación de entorno localizado, utilizaremos el contrato inteligente y los escenarios de uso del artículo anterior y configuraremos el entorno de desarrollo a partir de Truffley .Ganache

Trufa

tuffleEs un entorno de desarrollo de contratos inteligentes localizado, un marco de pruebas y una herramienta en cadena basado en la máquina virtual Ethereum (EVM).

https://trufflesuite.com/truffle/
adf2365ab012ed569f6efd42bc6c4b24.png

Para que sea aplicable tanto a linuxlos sistemas operativos Windowscomo maca, aquí usamos el modo de línea de comando para compilarlo.

Primero instale el entorno nodejs, descargue el paquete de instalación del sitio web oficial (u obtenga todos los paquetes de instalación sin conexión mencionados al final del artículo) y elija la versión estable.16.12.2 LTS

# https://nodejs.org/en/
node -v  # 确认node安装完毕

Instalación globalTruffle

npm install truffle -g
8e1b80b7c09bbc0060dd37b4f66a560d.png

Inicializar hilo

Sería más conveniente utilizarlo yarnpara gestionar proyectos.npm

npm install yarn -g
457bd1b98aff069f7e17f3bcae0667de.png

construir proyecto

yarn init
f2ab5ea5193b6ab5da817246892d7e4a.png

Inicializartrufa

Cree un directorio, por ejemplo main_contract,

truffle init
f87302421ef6a03ab753bd643444d184.png

Instalar openzeppelin

yarn add @openzeppelin/contracts
1d73e0124db4e0d96d465c540787ef70.png

Código VS

Primero copie el contrato inteligente escrito en el artículo anterior en contractsel directorio, vscodeábralo con y verá la estructura de directorio de un proyecto de contrato inteligente típico.

contractsEl directorio contiene el soliditycontrato inteligente, migrationsel directorio contiene archivos de implementación, node_modulesel directorio contiene archivos de biblioteca dependientes y testel directorio contiene archivos de prueba.

266b59406d12a7c423ca9370dd7f4486.png

ganache

TruffleSu función principal es soliditycompilar el código fuente en EVMun archivo ejecutable que se puede ejecutar en él, mientras Ganachesimula la cadena de prueba y proporciona un entorno blockchain localizado para implementar contratos.

InstalarGanache

Aquí puede elegir la versión 6.12 o la última versión 7.0. La nueva versión ha agregado algunas características nuevas. Puede ver las diferencias específicas aquí.

https://trufflesuite.com/blog/introducing-ganache-7/

npm install ganache-cli -g  # 6.12
npm install ganache -g  # 7.0
15eed7599cd482b12a57a44122c9631b.png

Cadena de bloques localizada

Este uso allowUnlimitedContractSizeignora el tamaño del contrato implementado requerido y continúa ganacheejecutándose en segundo plano.

ganache-cli -d --allowUnlimitedContractSize
35c011089c063ed3749e606ec1f72e5d.png

Se generaron 10 billeteras de prueba y el servicio se ejecutó en el puerto 8545. Aquí puede hacer una copia de seguridad de la dirección de la billetera, la clave privada y la frase mnemotécnica.

Vincularse a la billetera Metamask

Primero agregue Ganachela red, complete RPC URLcomo http://127.0.0.1:8545, 链IDpara1337

34955610843856fb0da31d2b9ad86ad6.png

Luego importe las 10 billeteras generadas previamente (con copia de seguridad previa) a través de la clave privada.

673ee7e9a8731b34a6ae5c2987503ecc.png

Si todo va bien, podrás ver los 100 ETH en cada cuenta. (Recuerde encender la red Ganache)

13b90949d179a16bdad1a4d7a1035cfe.png

Contrato de implementación

Archivo de configuración

Modifique el archivo de configuración truffle-config.js, la configuración de red y confirme ipque el número de puerto sea consistente con el anterior ganache.

development: {
     host: "127.0.0.1",     // Localhost (default: none)
     port: 8545,            // Standard Ethereum port (default: none)
     network_id: "*",       // Any network (default: none)
    },

Compilar la configuración, agregar srcdirectorio, habilitar el optimizador, agregarcontracts_build_directory

// Configure your compilers
  contracts_build_directory: "./src/contracts/",
  compilers: {
    solc: {
      version: "0.8.11",    // Fetch exact version from solc-bin (default: truffle's version)
    //   docker: true,        // Use "0.5.1" you've installed locally with docker (default: false)
      settings: {          // See the solidity docs for advice about optimization and evmVersion
       optimizer: {
         enabled: true,
         runs: 200
       },
    //    evmVersion: "byzantium"
      }
    }
  },

compilar contrato

trufflecontractsLos contratos en el directorio se compilarán automáticamente y se enviarán al src/contracts/directorio de acuerdo con la configuración.

truffle compile
2afcae3b58425e3d3265456135afad45.png

Implementar el contrato principal

En migrationsel directorio, haga referencia 1_initial_migration.js, cree 2_initial_maintoken.js.

Pase 3 parámetros de inicialización y la emisión total se fija en 21 millones.

const MainToken = artifacts.require("MainToken");
const SubToken = artifacts.require("SubToken");

module.exports = function (deployer) {
  deployer.deploy(MainToken, "Bluishfish", "BLF", 21000000).then(() =>{
    deployer.deploy(SubToken, MainToken.address)
  });
};

Ejecute todas las migraciones desde cero y ejecute los archivos de migración para implementar el contrato.

truffle migrate --reset
9789be310ecb99b7153fe80f9cd76266.png

Primero use la billetera con el número 0 para MainTokenimplementar el contrato principal en la red y luego implementar el subcontrato una vez completado SubToken.

En consecuencia, Ganachese puede ver información interactiva en.

bcc5adcb6f560d1379f7ad155ea55802.png

Registre la dirección principal del contrato contract addresscomo 0x9561c133dd8580860b6b7e504bc5aa500f0f06a7.

Implementar subcontrato

Al implementar el contrato principal antes, puede implementar los subcontratos juntos (lo que puede ahorrar costos de gas). Sin embargo, en la mayoría de los casos, a medida que se desarrolla el negocio, los subcontratos se implementarán más tarde que el contrato principal. En este caso , debe implementar los subcontratos por separado.

Crear 3_initial_subtoken.js, completar la dirección principal del contrato con parámetros

const SubToken = artifacts.require("SubToken");

module.exports = function (deployer) {
  deployer.deploy(SubToken, "0x9561c133dd8580860b6b7e504bc5aa500f0f06a7");
};

Especificar el despliegue del contrato No. 3 (subcontrato)

truffle migrate --f 3
dd121e85dc709d3db654c17bb46f2c18.png

Contrato de prueba

Introducir contrato

d09aa3c4f6d9a6e99646842a74d0c34a.png

Crea un nuevo archivo en testel directorio.Token.test.js

const MainToken = artifacts.require("./MainToken");
const SubToken = artifacts.require("./SubToken");

Escribir contrato de prueba

Los parámetros predeterminados se pasarán a Ganachelas 10 cuentas de prueba creadas. Generalmente, la primera cuenta se utiliza como implementador del contrato. Si se requieren varias cuentas para interactuar, se pueden nombrar propietario1, propietario2...

contract("TestToken", ([deployer, owner1, owner2]) => {
  console.log('deployer: ', deployer);
  console.log('owner1: ', owner1);
  console.log('owner2: ', owner2);
  ...
}

El entorno de prueba está completamente aislado del entorno de implementación, por lo que cada caso de prueba necesita volver a implementar el contrato, lo que beforeEachse puede lograr fácilmente con .

beforeEach(async () => {
  main_instance = await MainToken.new("Bluishfish","BLF", 21000000);
  sub_instance = await SubToken.new(main_instance.address);
})

Probar la implementación del contrato principal

Se utiliza parait escribir casos de prueba para probar el alias del contrato principal y la cantidad total del token.

it("测试主合约初始化", async()=>{
  // console.log('主合约地址: ', main_instance.address)
  const name = await main_instance.name();
  assert.equal(name, "Bluishfish");

  const symbol = await main_instance.symbol();
  assert.equal(symbol, "BLF");

  const totalSupply = await main_instance.totalSupply();
  assert.equal(totalSupply, web3.utils.toWei('21000000', 'ether'));
})

Implementación de subcontrato de prueba

_mainAddressAquí cambiamos el subcontrato publicpara que sea más fácil verificar la propiedad del contrato.

it("测试子合约初始化", async()=>{
  // console.log('子合约地址: ', sub_instance.address)
  const main_address = await sub_instance._mainAddress();
  assert.equal(main_instance.address, main_address);
})

Función de transferencia de prueba

La función de transferencia sigue el diagrama de flujo anterior:

  • Primero, se encuentra una cantidad total fija de tokens en el contrato principal, y se extraen previamente 21 millones de tokens para la billetera principal (billetera del propietario del contrato);

  • La billetera principal asigna una cantidad inicial de fondos al subcontrato;

  • El subcontrato utiliza el token del contrato principal para realizar negocios específicos;

  • Una vez que el subcontrato complete su actividad, los tokens restantes se devolverán al contrato principal;

  • El contrato principal se retira a la billetera principal.

6ecaf416b4f892840db2dee5d12e011b.png
Transferir dinero de la billetera principal al subcontrato

Transfiera 10,000 tokens de la billetera principal al subcontrato. Esto se utiliza toWeipara calcular la precisión y evitar demasiados ceros en el código.

beforeEach(async () => {
  // 主钱包转账给子合约
  const result = await main_instance.transfer(
    sub_instance.address, 
    web3.utils.toWei('10000', 'ether'), 
    { from: deployer });
  assert.equal(result.receipt.status, true);
})

it("测试主钱包转账给子合约", async()=>{
  // 查询子合约是否到账 10000 代币
  const balance = await main_instance.balanceOf(sub_instance.address);
  assert.equal(balance.toString(), web3.utils.toWei('10000', 'ether'));
});
El subcontrato devuelve los tokens al contrato principal.

Transfiera 5000 tokens del subcontrato, devuélvalos al contrato principal y luego verifique el saldo de la cuenta.

it("测试子合约归还代币给主合约", async()=>{
  // 子合约转 5000 代币到主合约
  const result = await sub_instance.transferWithToken(
    web3.utils.toWei('5000', 'ether'), { from: deployer });
  assert.equal(result.receipt.status, true);

  // 查询子合约余额
  const balance = await main_instance.balanceOf(sub_instance.address);
  assert.equal(balance.toString(), web3.utils.toWei('5000', 'ether'));
});
Retirar del contrato principal a la billetera principal

Primero transfiera 10,000 tokens del subcontrato al contrato principal, luego retire dinero del contrato principal a la billetera principal y verifique si el saldo en cada cuenta es correcto.

it("测试主合约提现到主钱包", async()=>{
  // 转子合约 10000 代币到主合约
  const result = await sub_instance.transferWithToken(
    web3.utils.toWei('10000', 'ether'), { from: deployer });
  assert.equal(result.receipt.status, true);
  // 查询子合约余额是否为 0
  var balance = await main_instance.balanceOf(sub_instance.address);
  assert.equal(balance.toString(), '0');

  // 提现到主钱包
  await main_instance.withdraw({ from: deployer });
  
  // 查询主合约余额是否为 0
  balance = await main_instance.balanceOf(main_instance.address);
  assert.equal(balance.toString(), '0');

  // 查询主钱包余额是否为 2100万
  balance = await main_instance.balanceOf(deployer);
  assert.equal(balance.toString(), web3.utils.toWei('21000000', 'ether'));

});

prueba completa

Después de que todo esté listo, ingrese en la línea de comando

truffle test
6f5cef855928b32f1ee4e2f89dbbecb3.png

Aquí solo se muestran algunos casos de prueba para funciones normales. En proyectos reales, es necesario agregar más casos de error para lograr una cobertura completa de la ruta y verificar completamente varias situaciones inesperadas. Afortunadamente, un caso de uso se puede utilizar varias veces y las llamadas simples posteriores truffle testpueden completar la prueba, lo cual es particularmente útil al actualizar y actualizar nuevos contratos.

geth

También podemos gethusarlo construir un nodo Ethereum completo. Dado que el libro de contabilidad histórico debe sincronizarse, la cantidad de datos a descargar es relativamente grande. Si está interesado, puede configurarlo según el siguiente enlace.

https://github.com/ethereum/go-ethereum

gordo

Para implementar en la cadena principal, además de gethconstruirla usted mismo, también puede utilizar un método más simple infura.

InfuraLa suite proporciona acceso instantáneo APIa Ethereum y IPFSa la red Ethereum . Al usarlo , puede conectarse fácilmente sin tener que iniciar y mantener su propia infraestructura. Su servicio principal es gratuito y puede crear 3 proyectos con hasta 100.000 solicitudes por día.HTTPSWebSocketInfuraWeb 3.0

https://infura.io/

Registrar una cuenta

Primero debe registrar una cuenta en el sitio web oficial, crear un nuevo proyecto, seleccionar la cadena Ethereum y dar un nombre al proyecto.

a660204d9ef20b33c19c0b3fbeec41a8.png

Autentíquese utilizando su PROJECT IDclave y copie de forma segura su clave y elija la adecuada .ROJECT SECRETENDPOINTS

63d70bc5d64f0b7a881f96f18514352f.png

Instalar HDWalletProvider

Por razones de seguridad, Infurasus claves privadas no se administran, lo que significa que Infuralas transacciones no se pueden firmar en su nombre. Sin embargo, las firmas de transacciones y las conexiones a la red Ethereum Trufflese pueden manejar mediante el uso .HDWalletProvider

1a2c20b2caf7e4566956937cc0249e41.png
yarn add @truffle/hdwallet-provider

WindowsSi la instalación falla, puede intentar instalar las herramientas de compilación a continuación npm install -g windows-build-tools.

Configurar el proyecto Truffle

Editar truffle-config.jse importar archivos de biblioteca

const HDWalletProvider = require("@truffle/hdwallet-provider");

Configure la frase mnemotécnica, recuerde usar una pequeña cantidad de billetera de desarrollador y ¡no la filtre! Se recomienda almacenarlo en un archivo y configurarlo gitignorepara excluir archivos clave.

// const mnemonic = "在metamask/设置/安全与隐私/显示账户助记词";
const fs = require('fs');
const mnemonic = fs.readFileSync(".secret").toString().trim();

Agregue una Ropstendefinición de red y completeINFURA_PROJECT_ID

module.exports = {
  networks: {
    ropsten: {
      provider: function() {
        return new HDWalletProvider(mnemonic, "https://ropsten.infura.io/v3/<INFURA_PROJECT_ID>")
      },
      network_id: 3
    }
  }
};

Contrato de implementación

Seleccione la red de prueba, que de forma predeterminada es la primera cuenta de la billetera. Solo asegúrese de que haya monedas de prueba en ella.

truffle migrate --network ropsten

Ganache 7.0Si es el caso anterior, también se puede fork.urlutilizar para infura.

ganache --fork.url wss://ropsten.infura.io/ws/v3/<INFURA_PROJECT_ID>
a4a64076a34aed179b444cd3d0f8405f.png

Comparando la diferencia de velocidad Ganache CLI v6.12.2entre y ganache v7.0.1, aunque no llega a 30 veces, sí es mucho más rápida.

Descarga del código fuente

614e3729f6020b83c752da1114ec99aa.png

Puede encontrar información y documentos relevantes para este problema en la cuenta pública "Deep Awakening" y responda: "chain02" en segundo plano para obtener el enlace de descarga.

Vista previa del artículo siguiente

Este artículo presenta principalmente el desarrollo local de aplicaciones blockchain, las herramientas de soporte utilizadas en el backend y los métodos de prueba. A continuación, configuraremos reactpara escribir el front-end y usaremos web3la conexión metamaskpara acceder al contrato inteligente implementado.

3bf84914ce8a82e41ae4d95a72f00a82.gif

Supongo que te gusta

Origin blog.csdn.net/weixin_47479625/article/details/122757779
Recomendado
Clasificación