Saul  Alaniz

Saul Alaniz

1653077280

Cómo Crear Contratos Inteligentes En Solana Y Anchor

¿Qué es Solana?

Solana es una plataforma blockchain descentralizada creada por Anatoly Yakavenko. Solana tiene un tiempo de bloqueo de 400 ms, que es terriblemente rápido.

Esto se debe a su mecanismo de consenso de prueba de historial, que en realidad es una prueba de participación, pero agregó tiempo variable adicional. PoH se utiliza para codificar el paso del tiempo sin confianza en un libro mayor en una estructura de datos de solo anexar.

Las cadenas de bloques deben acordar el tiempo antes de enviar un bloque, los nodos deben conversar de un lado a otro para determinar el tiempo hasta que estén de acuerdo y esto puede llevar mucho tiempo. A Solana se le ocurrió una solución con prueba de historial para guardar marcas de tiempo para que los nodos no tengan que esperar para ponerse de acuerdo a tiempo y también tienen una prueba criptográfica para eso.

Para obtener más información sobre la prueba de la historia, le recomiendo que consulte el documento técnico de Solana.

¿Qué es Ancla?

Anchor es un marco para desarrollar contratos inteligentes de Solana que contiene varias herramientas para desarrolladores. Básicamente, Anchor es un salvavidas y hace que sea muy fácil desarrollar contratos inteligentes.

Descripción del proyecto

En esta guía, nos centraremos en la configuración del proyecto, el funcionamiento básico y las pruebas.

Crearemos una aplicación de contador que incremente el contador en uno cada vez que llamemos al RPC.

Requisito previo

Rust: Rust es un lenguaje de programación de propósito general muy poderoso. Vamos a usar esto para el desarrollo de contratos inteligentes. Hay un muy buen libro disponible para aprender Rust.

Conjunto de herramientas de Solana : incluye la CLI de Solana.

El código para este proyecto se puede encontrar aquí .

Empezando

Para comenzar, cree un nuevo proyecto ancla:

anchor init counterapp

En la estructura del proyecto, verá los siguientes archivos y carpetas.

program— Este es el directorio de programas de Solana (Contratos inteligentes)

test— Aquí es donde vive el código de prueba de javascript

migrations— Este es el script de implementación

app— Aquí es donde se va a construir la interfaz

Miremos nuestro lib.rsarchivo en el directorio del programa.

use anchor_lang::prelude::*;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod counterapp {
    use super::*;
    pub fn initialize(ctx: Context<Initialize>) -> ProgramResult {               Ok(())
    }
}#[derive(Accounts)]
pub struct Initialize {}

Este es el programa más básico escrito por CLI. Hay una función de inicialización cuando se invoca, no hace nada, solo se ejecuta con éxito, la estructura de inicialización define el contexto de la función de inicialización.

Ahora que hemos configurado nuestro proyecto, construyamos nuestra aplicación de contador.

Para hacer eso, necesitamos crear una cuenta para almacenar nuestros datos. Debes estar pensando qué diablos es esta cuenta. Las cuentas son solo la forma de almacenar y acceder a los datos en Solana sealevel. Para más información, recomiendo leer esto .

En el código anterior, hemos definido dos estructuras, la CounterAccountestructura Accountcontiene una variable de conteo que almacenará nuestro conteo.

#[derive(Accounts)]
pub struct Create<'info> {
    
    #[account(init, payer=user, space = 16+16)]
    pub counter_account: Account<'info, CounterAccount>,
    
    #[account(mut)]
    pub user: Signer<'info>,
    
    pub system_program: Program<'info, System>,
}#[account]
pub struct CounterAccount {
    pub count: u64,
}

La Createestructura es nuestra estructura de instrucciones que define nuestro contexto para crear una cuenta, es decir, "Oye, quiero crear una cuenta contador_cuenta con el espacio de 32 bytes".

Los #[account(…)]atributos definen restricciones e instrucciones en el preprocesamiento realizado por Anchor para crear contexto. Ahora vamos a crear nuestra función.

pub fn create(ctx: Context<Create>) -> ProgramResult {
    let counter_account = &mut ctx.accounts.counter_account;
    counter_account.count = 0;
    Ok(())
}

createLa función es nuestro controlador para la solicitud rpc que toma el contexto creado con Createstruct.

Frio. Hemos terminado con este increíble programa. Ahora vamos a crear la función de prueba y desplegar nuestra obra maestra.

import * as anchor from '@project-serum/anchor';
import { Program } from '@project-serum/anchor';
import { Counterapp } from '../target/types/counterapp';describe('counterapp', () => {    const provider = anchor.Provider.env()
    anchor.setProvider(provider);    const program = anchor.workspace.Counterapp as Program<Counterapp>;    const counterAccount = anchor.web3.Keypair.generate();    it('Is initialized!', async () => {
        await program.rpc.create({
            accounts: {
                counterAccount: counterAccount.publicKey,
                user: provider.wallet.publicKey,
                systemProgram: anchor.web3.SystemProgram.programId,
            },
            signers: [counterAccount]
        } as any)
    });    it("Increment counter", async () => {
        await program.rpc.increment({
            accounts: {
                counterAccount: counterAccount.publicKey
            }
        } as any)
    })    it("Fetch account", async () => {
        const account: any = await
        program.account.counterAccount.fetch(counterAccount.publicKey)
        console.log(account.count)
    })
});

Ahora, ejecuta la prueba.

anchor test

Después de que pase la prueba, ahora podemos implementar el programa. Asegúrese de que solana-test-validatorse está ejecutando.

anchor deploy

Gracias por leer.

Fuente: https://betterprogramming.pub/how-to-create-smart-contracts-in-solana-and-anchor-e67ff0747c63

 #smart #contract #solana #anchor 

Cómo Crear Contratos Inteligentes En Solana Y Anchor

ソラナとアンカーでスマートコントラクトを作成する

ソラナとは?

Solanaは、AnatolyYakavenkoによって作成された分散型ブロックチェーンプラットフォームです。ソラナのブロック時間は400ミリ秒で、非常に高速です。

これは、プルーフ・オブ・ヒストリーのコンセンサスメカニズムによるものです。これは、実際にはプルーフオブステークですが、余分な可変時間が追加されています。PoHは、信頼できない時間の経過を追加専用データ構造の元帳にエンコードするために使用されます。

ブロックチェーンは、ブロックを送信する前に時間について合意する必要があります。ノードは、合意するまで時間を決定するためにチャットを行ったり来たりする必要があり、これには多くの時間がかかる場合があります。Solanaは、タイムスタンプを保存するための履歴の証明を備えたソリューションを考案しました。これにより、ノードは時間について合意するのを待つ必要がなくなり、そのための暗号化証明もあります。

歴史の証明の詳細については、ソラナのホワイトペーパーを参照することをお勧めします。

アンカーとは何ですか?

アンカーは、いくつかの開発者ツールを含むSolanaスマートコントラクトを開発するためのフレームワークです。つまり、基本的に、アンカーは命の恩人であり、スマートコントラクトの開発を非常に簡単にします。

プロジェクトの概要

このガイドでは、プロジェクトのセットアップ、基本的な操作、およびテストに焦点を当てます。

RPCを呼び出すたびにカウンターを1つずつインクリメントするカウンターアプリを作成します。

前提条件

Rust —Rustは非常に強力な汎用プログラミング言語です。これをスマートコントラクトの開発に使用します。Rustを学ぶために利用できる非常に良い本があります。

Solanaツールスーツ—これにはSolanaCLIが含まれます。

このプロジェクトのコードはここにあります。

入門

開始するには、新しいアンカープロジェクトを作成します。

anchor init counterapp

プロジェクト構造には、次のファイルとフォルダーが表示されます。

program—これはSolanaプログラム(スマートコントラクト)のディレクトリです

test—これはjavascriptテストコードが存在する場所です

migrations—これはデプロイスクリプトです

app—これはフロントエンドが構築される場所です

lib.rsプログラムディレクトリにあるファイルを見てみましょう。

use anchor_lang::prelude::*;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod counterapp {
    use super::*;
    pub fn initialize(ctx: Context<Initialize>) -> ProgramResult {               Ok(())
    }
}#[derive(Accounts)]
pub struct Initialize {}

これは、CLIによって作成された最も基本的なプログラムです。呼び出されたときに初期化関数があり、正常に実行されるだけで何も実行されません。初期化構造体は、初期化関数のコンテキストを定義します。

プロジェクトを設定したので、カウンターアプリを作成しましょう。

そのためには、データを保存するためのアカウントを作成する必要があります。あなたは一体何がこのアカウントであるかを考えているに違いありません。アカウントは、ソラナ海面のデータを保存してアクセスするための手段にすぎません。詳細については、こちらをお読みになることをお勧めします。

上記のコードでは、2つの構造体を定義しました。CounterAccount構造体はAccount、カウントを格納するカウント変数を含みます。

#[derive(Accounts)]
pub struct Create<'info> {
    
    #[account(init, payer=user, space = 16+16)]
    pub counter_account: Account<'info, CounterAccount>,
    
    #[account(mut)]
    pub user: Signer<'info>,
    
    pub system_program: Program<'info, System>,
}#[account]
pub struct CounterAccount {
    pub count: u64,
}

構造体は、アカウントを作成するためのコンテキストを定義する命令構造体です。Createつまり、「32バイトのスペースでアカウントcounter_accountを作成したい」ということです。

属性は、コンテキストを作成するためにアンカーによって実行される前処理の#[account(…)]制約と命令を定義します。それでは、関数を作成しましょう。

pub fn create(ctx: Context<Create>) -> ProgramResult {
    let counter_account = &mut ctx.accounts.counter_account;
    counter_account.count = 0;
    Ok(())
}

createCreatefunctionは、 structで作成されたコンテキストを取得するrpcリクエストのハンドラーです。

涼しい。この素晴らしいプログラムはこれで終わりです。それでは、テスト関数を作成して、傑作を展開しましょう。

import * as anchor from '@project-serum/anchor';
import { Program } from '@project-serum/anchor';
import { Counterapp } from '../target/types/counterapp';describe('counterapp', () => {    const provider = anchor.Provider.env()
    anchor.setProvider(provider);    const program = anchor.workspace.Counterapp as Program<Counterapp>;    const counterAccount = anchor.web3.Keypair.generate();    it('Is initialized!', async () => {
        await program.rpc.create({
            accounts: {
                counterAccount: counterAccount.publicKey,
                user: provider.wallet.publicKey,
                systemProgram: anchor.web3.SystemProgram.programId,
            },
            signers: [counterAccount]
        } as any)
    });    it("Increment counter", async () => {
        await program.rpc.increment({
            accounts: {
                counterAccount: counterAccount.publicKey
            }
        } as any)
    })    it("Fetch account", async () => {
        const account: any = await
        program.account.counterAccount.fetch(counterAccount.publicKey)
        console.log(account.count)
    })
});

次に、テストを実行します。

anchor test

テストに合格したら、プログラムをデプロイできます。それが実行されていることを確認してくださいsolana-test-validator

anchor deploy

読んでくれてありがとう。

ソース:https ://betterprogramming.pub/how-to-create-smart-contracts-in-solana-and-anchor-e67ff0747c63

#smart #contract #solana #anchor 

ソラナとアンカーでスマートコントラクトを作成する

La Guía Completa Para Las Pruebas De Blockchain

Organizaciones de todo el mundo están recurriendo a la tecnología blockchain para mejorar el almacenamiento, la seguridad y la gestión de datos. Esto ha resultado en la necesidad de garantizar que las aplicaciones creadas en la red blockchain se prueben exhaustivamente.

En este artículo, discutiremos de qué se trata la prueba de blockchain, incluidos los beneficios y los inconvenientes, los tipos de prueba de blockchain, las fases y algunas herramientas útiles. También crearemos y probaremos un contrato inteligente utilizando algunas de las herramientas de prueba recomendadas.

¿Qué son las pruebas de cadena de bloques?

La prueba de blockchain es la evaluación sistemática de los diversos componentes funcionales de blockchain (por ejemplo, contratos inteligentes). A diferencia de las pruebas de software tradicionales, las pruebas de blockchain involucran varios componentes, como bloques, minería, transacciones, billeteras, etc., todos los cuales requieren herramientas especiales para probar.

Las pruebas de blockchain ayudan en el desarrollo de varias etapas de calidad, que van desde el rendimiento del sistema hasta la seguridad de la aplicación de blockchain.

Según Santu Maity, arquitecto empresarial de IBM, el mejor enfoque para las pruebas de blockchain abarca todo el entorno. Esto incluye aplicaciones basadas en blockchain, tanto móviles como web, que interactúan con el componente funcional del sistema blockchain, como una API, contratos inteligentes y nodos.

Beneficios de las pruebas de blockchain

Las pruebas de cadena de bloques garantizan que todas las entidades involucradas en una red de cadena de bloques hayan sido debidamente validadas para su funcionamiento. Como resultado, proporciona a las organizaciones una infraestructura segura y funcional.

Las pruebas de Blockchain ayudan en la entrega de productos de calidad, mejorando así la experiencia del usuario. También elimina fallas en un sistema descentralizado donde el dinero está involucrado para evitar daños financieros.

Desafíos de las pruebas de blockchain

Uno de los desafíos más importantes es la falta de herramientas de prueba. Actualmente, hay pocas herramientas de prueba disponibles para cada marco de blockchain; por lo tanto, usar la herramienta incorrecta puede causar problemas.

Otro problema en el ecosistema blockchain es la falta de experiencia profesional. Debido a que la tecnología blockchain aún es relativamente nueva en el mundo de la tecnología, no ha visto una adopción generalizada entre los desarrolladores de software.

Otro desafío más es probar la estrategia. Las pruebas de blockchain requieren un conocimiento y una comprensión profundos de cómo funciona blockchain.

 

La seguridad de la red blockchain también puede ser difícil. Las aplicaciones de blockchain ahora se utilizan en una variedad de sectores económicos. Como resultado, la seguridad de los datos es fundamental para prevenir actividades nefastas.

La incapacidad de proporcionar un rendimiento adecuado y las pruebas de carga proporcionan poco o ningún conocimiento sobre el rendimiento de las aplicaciones de la cadena de bloques en determinadas condiciones.

Tipos de pruebas de blockchain

La siguiente es una lista completa de los tipos de pruebas que se pueden realizar en una cadena de bloques:

  1. Las pruebas funcionales determinan la efectividad de varios componentes funcionales del sistema blockchain
  2. La prueba de nodos ayuda en la prueba independiente de cada nodo en la red para garantizar una conexión sin problemas
  3. Las pruebas de rendimiento identifican las restricciones de flujo del sistema y recomiendan una solución óptima
  4. Las pruebas de API contribuyen a una interacción clara entre las aplicaciones en la red blockchain al garantizar que las solicitudes y respuestas entre estas aplicaciones se operen correctamente.

Fases de las pruebas de blockchain

Fase de iniciación

La fase de iniciación es la primera etapa de prueba de un sistema de cadena de bloques. Aquí, los evaluadores se familiarizan con el ciclo de vida del sistema mediante el análisis y la comprensión de su funcionalidad, lo que les permite comprender mejor todos los componentes involucrados. Se genera un mapa detallado que incluye todos los componentes y subcomponentes del sistema, así como todas las interfaces, para proporcionar una buena comprensión de cómo funciona el sistema en general.

Fase de diseño

En la fase de diseño, se identifican los componentes clave del sistema que deben probarse y se desarrolla una estrategia de prueba bien detallada adaptada al sistema blockchain. Esta estrategia de prueba describe los casos de prueba del sistema y las especificaciones del entorno de prueba.

Fase de planeamiento

En esta fase se decide cómo se realizará cada tipo de prueba, con una estimación de cuántas pruebas se realizarán en cada nivel y en qué medida.

Si el sistema no está disponible, se deben diseñar estrategias de prueba alternativas. Configurar una cadena de bloques privada para realizar pruebas es una estrategia de prueba alternativa. Las pruebas de API, las pruebas funcionales, las pruebas de rendimiento, las pruebas de seguridad, etc., son ejemplos de estas pruebas.

Fase de resultados

Esta es la fase final, que incluye un informe sobre la prueba general realizada en el sistema. El rendimiento del sistema, la verificación de bajo nivel y la validación de bloques, transacciones y contratos inteligentes son los ejercicios fundamentales que deben ejecutarse durante esta fase.

Herramientas de prueba de cadena de bloques

probador de ethereum

Ethereum Tester es una herramienta de prueba de Ethereum que incluye integración Web3, API y contratos inteligentes. Esto permite a los equipos de desarrollo recrear una cadena de bloques de Ethereum similar a la de producción.

Una biblioteca de prueba de código abierto, es simple de implementar y tiene soporte API manejable para una variedad de requisitos de prueba.

ganache

Esta herramienta se utiliza principalmente para probar localmente los contratos de Ethereum. Genera una simulación de cadena de bloques que permite a cualquier persona probar varias cuentas.

Kit de prueba de exón

Exonum TestKit se especializa en probar la actividad de todo el servicio de la aplicación blockchain. Podemos usar la herramienta para realizar pruebas de API y ejecución de transacciones sin tener que preocuparnos por las operaciones de red o los algoritmos de consenso.

Herramienta de prueba Corda

Corda es una plataforma de contabilidad distribuida de código abierto basada en la tecnología blockchain. Las pruebas de contrato, las pruebas de integración, las pruebas de flujo y las pruebas de carga se simplifican con la herramienta de prueba integrada.

Trufa

Truffle es una herramienta de prueba de blockchain con características que van más allá de las pruebas básicas, como trabajar con Chai y Mocha. Es un nombre muy conocido entre los desarrolladores de Ethereum por identificar características de prueba sorprendentes, como la prueba de contrato automatizada.

populus

El marco Populus incluye la funcionalidad de prueba de Ethereum, que está bien integrada como un conjunto de propiedades enfocadas hacia la prueba de implementación de contratos. Estos marcos se construyen principalmente alrededor del marco pytest , lo que permite una implementación muy simple.

Probando un contrato inteligente

Ahora pasemos a la sección de tutoriales del artículo. Aquí, desarrollaremos y probaremos un contrato inteligente de muestra con Truffle ahora que ha comprendido los conceptos básicos de las pruebas de blockchain.

En este ejemplo, crearemos un sistema de seguimiento de automóviles para un taller mecánico. Cubriremos lo siguiente:

  • Configuración del entorno de desarrollo
  • Creación de un proyecto de trufa
  • Escribiendo el contrato inteligente
  • Compilando el contrato inteligente
  • Migración del contrato inteligente
  • Probando el contrato inteligente

Configuración del entorno

Para trabajar con Truffle, deberá tener instalado el siguiente software en su computadora:

  • Nodo.js
  • npm
  • Git

Ejecute el siguiente comando en su terminal una vez que se hayan instalado correctamente:

npm install -g truffle

El comando anterior instalará Truffle globalmente en su computadora. Escriba "versión truffle" en la terminal para ver si Truffle está instalado correctamente.

Crear un nuevo proyecto de Trufa

Cree un nuevo directorio de proyecto con lo siguiente:

mkdir truffle-project

Migre a su nuevo directorio de proyectos así:

cd truffle-project

Luego, inicializa Truffle:

truffle init

El comando anterior generará la siguiente estructura de directorios para Truffle:

contracts/, que contiene los códigos fuente de los contratos inteligentes, escritos en Solidity. Dentro de este directorio hay un contrato importante llamado Migrations.sol.

migrations/. La implementación de contratos inteligentes se gestiona con el sistema de migración. Se utiliza para monitorear cambios en el contrato inteligente.

test/es donde se guardan los códigos de prueba y los archivos para los contratos inteligentes. Las pruebas pueden escribirse en Solidity o JavaScript.

truffle-config.jses el archivo de configuración de Truffle donde puede definir su red de implementación para implementar sus contratos inteligentes.

Crear un contrato inteligente

En el contracts/directorio, cree un nuevo archivo llamado Auto.soly agregue lo siguiente:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

contract Purchase {
  address[20] public buyers;
}

pragma solidity ^0.8.9;indica la versión mínima de Solidity requerida. El pragmacomando significa "información adicional que solo interesa al compilador", mientras que el símbolo de intercalación (^) significa "la versión indicada o superior".

Al escribir Solidity, se deben declarar tipos de datos como matrices y cadenas. Solidity proporciona un tipo de datos especial llamado dirección, que también es una dirección Ethereum almacenada como valores de 20 bytes. Esta dirección se puede utilizar para enviar y recibir Ether.

Dentro del contract Purchase{alcance, definimos una variable pública llamada borrowercon un addresstipo y una longitud de 20, que es una matriz de direcciones de Ethereum. Recuerde siempre agregar un punto y coma (;) al final de cada declaración, para evitar un error.

Ahora vamos a crear una función que permita a los usuarios realizar una solicitud de préstamo. Debajo de la declaración de la variable, agregue lo siguiente:

// buying a car
function buy (uint carId) public returns (uint) {
    require(carId >= 0 && carId <= 19);

    buyer[carId] = msg.sender;

    return carId;
  }

De acuerdo con el código anterior, la función acepta un uintparámetro de número entero ( ) carIdy se espera que devuelva un número entero como salida. La require()declaración se utiliza para garantizar que carIdestá dentro del rango de la matriz del comprador. Debido a que las matrices en Solidity están indexadas desde cero, el carIdvalor debe estar entre cero y 19.

Si carIdestá dentro del rango, la dirección desde la que se realizó la llamada se agrega a nuestra buyermatriz, que se denota por msg.sender. Luego devolvemos lo carIdque se pasó.

A continuación, escribimos una función que obtenga todos los compradores, así:

// get all buyers
  function getBuyers() public view returns (address[20] memory) {
    return buyers;
  }

Devolvemos buyercomo un tipo address[20] memoryque contiene la ubicación de datos de la variable. viewen la declaración de la función indica que la función no cambiará el estado del contrato.

Compilando el contrato inteligente

A continuación, debemos compilar nuestro código de Solidity para que la máquina virtual de Ethereum (EVM) pueda entenderlo.

Abra la terminal en el directorio raíz de su proyecto y escriba el siguiente comando:

truffle compile

El comando anterior compilará todos los contratos inteligentes en la carpeta de contratos y también creará un builddirectorio que contenga una carpeta de contratos con artifacts.

Los artefactos son .jsonarchivos que sirven como contenedor de JavaScript para interactuar con los contratos inteligentes correspondientes.

Migración del contrato inteligente

Ahora que el contrato se ha compilado con éxito, es hora de migrarlo a la cadena de bloques.

Una migración es un script de implementación que se usa para cambiar el estado de los contratos de su aplicación, moviéndolos de un estado al siguiente.

Para implementar el contrato inteligente sobre blockchain, primero crearemos el archivo de configuración de migración. Este es un archivo JavaScript que maneja la implementación de los contratos inteligentes en la cadena de bloques.

Sin embargo, para implementar los contratos inteligentes con migraciones, primero debemos obtener acceso a sus artefactos, que se generaron como resultado del comando de compilación Truffle. Dentro del migrationdirectorio hay un archivo de migración predeterminado 1_initial_migration.jsque maneja la implementación del Migration.solarchivo.

Vamos a crear nuestro propio archivo de configuración de migración 2_deploy_contract.js, con lo siguiente:

const PurchaseContract = artifacts.require('Purchase');

module.exports = function(deployer) {
  deployer.deploy(PurchaseContract);
};

El artifacts.require()método se utiliza para especificar el contrato inteligente que se utilizará para interactuar con la cadena de bloques. Dado que un archivo de origen puede contener varios contratos, especificamos el nombre de la definición del contrato en lugar del nombre del .solarchivo. En este caso usamos Purchaseen lugar de Auto.

Las migraciones luego se exportan como una función con un parámetro (deployer). El objeto deployeres responsable de organizar las implementaciones. A continuación, implementamos PurchaseContract.

A continuación, usaremos otra herramienta de prueba de blockchain llamada Ganache para proporcionar una interfaz para implementar nuestros contratos inteligentes y realizar pruebas. Puede descargar o utilizar la línea de comandos npm i -g ganache-cli.

Si está utilizando el sistema operativo Ubuntu, es posible que le resulte difícil ejecutar la aplicación Ganache. Simplemente haga clic con el botón derecho en el archivo de la aplicación, vaya a las propiedades, luego a los permisos y marque Permitir la ejecución del archivo como programa. Luego vuelva a ejecutar la aplicación.

Usaré la GUI de Ganache para este tutorial. Ejecute la aplicación y seleccione inicio rápido . En la pantalla se desplegará la siguiente imagen:

Ahora migremos nuestro contrato inteligente:

truffle migrate

Después de una migración exitosa, verá lo siguiente:

Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.



Starting migrations...
======================
> Network name:    'ganache'
> Network id:      5777
> Block gas limit: 6721975 (0x6691b7)


1_initial_migration.js
======================

   Replacing 'Migrations'
   ----------------------
   > transaction hash:    0x7f4ad90e465b3e6501e8a49f3af1692ba39df66cbb6e014061b9e7e592167c02
   > Blocks: 0            Seconds: 0
   > contract address:    0x5A61A1989d92Fb349fAcd409Fdc8A4C640853fD9
   > block number:        1
   > block timestamp:     1636840180
   > account:             0x3309Fa70a44a69eB7b7E87038Afa61a1C9dDB31b
   > balance:             99.99502316
   > gas used:            248842 (0x3cc0a)
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.00497684 ETH


   > Saving migration to chain.
   > Saving artifacts
   -------------------------------------
   > Total cost:          0.00497684 ETH


2_deploy_contract.js
====================

   Replacing 'Purchase'
   --------------------
   > transaction hash:    0x039224bded1eec1272e422d79ea146aa0026d13252fa7c495628829dbf7d5e42
   > Blocks: 0            Seconds: 0
   > contract address:    0xA89fdCd07E195be4555E07025b8613224e312F97
   > block number:        3
   > block timestamp:     1636840182
   > account:             0x3309Fa70a44a69eB7b7E87038Afa61a1C9dDB31b
   > balance:             99.98848808
   > gas used:            284241 (0x45651)
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.00568482 ETH


   > Saving migration to chain.
   > Saving artifacts
   -------------------------------------
   > Total cost:          0.00568482 ETH


Summary
=======
> Total deployments:   2
> Final cost:          0.01066166 ETH

Ahora regrese a su aplicación Ganache:

Notará que el bloque actual, que antes era cero, ahora es cuatro. Además, la primera dirección comenzó con 100 Ether, ahora tiene 99,99 Ether. Esto se debe a los costos de transacción de la migración.

Hemos creado e implementado con éxito nuestro contrato inteligente en nuestra cadena de bloques local. Ahora podemos probar nuestro contrato inteligente para asegurarnos de que hace lo que se supone que debe hacer.

Probando un contrato inteligente

Hay dos métodos para probar contratos inteligentes en Truffle. La primera es usando Solidity y la segunda usando JavaScript. Para este tutorial, usaremos el método JavaScript.

En el testdirectorio, crea un nuevo archivo purchase.test.jsy escribe lo siguiente:

const Purchase = artifacts.require("Purchase");
contract("Purchase", (accounts) => {
 let purchase;
 let expectedBuyer;
 before(async () => {
     purchase = await Purchase.deployed();
 });
 describe("get account addresses for every purchase", async () => {
  before("buy a car using accounts[0]", async () => {
    await purchase.buy(4, { from: accounts[0] });
    expectedBuyer = accounts[0];
  });
  it("can retrieve buyer's address by car id", async () => {
    const buyer = await purchase.buyers(4);
    assert.equal(buyer, expectedBuyer, "Expected to return buyer's account.");
  });
  it("can retrieve addresses of every buyers", async () => {
    const buyers = await purchase.getBuyers();
    assert.equal(buyers[4], expectedBuyer, "Buyer should be included.");
  });
 });
});

Primero, usamos el artifacts.require()método para importar nuestro Purchasecontrato. Luego declaramos un contrato y pasamos nuestra Purchaseinstancia como primer argumento, seguido de una función de devolución de llamada como segundo.

El parámetro para la función de devolución de llamada es accounts. El accountsproporciona las cuentas disponibles de la red. Usamos beforepara asegurarnos de que el auto comprado con ID 4se asigne a la primera cuenta.

Luego realizamos una prueba para ver en qué dirección compró el automóvil con identificación 4. Para comparar el valor real ( buyer) y el valor esperado ( expectedBuyer), usamos el assert.equalmétodo. Si la prueba falla, el mensaje de error se imprime en la consola.

Finalmente, verificamos si devuelve todas las direcciones de los compradores. Luego verificamos si la dirección con UD 4está entre las direcciones devueltas del comprador.

Ahora probamos nuestro contrato ejecutando el siguiente comando:

truffle test

Si pasa la prueba, debería ver un resultado similar a continuación:

Using network 'test'.


Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.



  Contract: Purchase
    get account addresses for every purchase
      ✓ can retrieve buyer's address by car id (102ms)
      ✓ can retrieve addresses of every buyers (429ms)


  2 passing (2s)

Conclusión

A medida que crece la adopción de blockchain, la necesidad de ofrecer productos de alta calidad no puede satisfacerse sin invertir en blockchain y experiencia en pruebas de blockchain.

Las pruebas de blockchain garantizan que todos los componentes del sistema funcionen correctamente y que todas las aplicaciones interactúen con él de manera confiable.

Fuente: https://blog.logrocket.com/complete-guide-blockchain-testing/#creating-smart-contract 

#blockchain #testing #smart 

La Guía Completa Para Las Pruebas De Blockchain

Extensibilidad De Contrato Inteligente Con Tokens Envueltos

La naturaleza inmutable y de código abierto de los contratos inteligentes permite la innovación sin permiso en el espacio. Las personas y las empresas pueden innovar por encima de los protocolos sin preocuparse de que las reglas del juego cambien más adelante . Cualquier desarrollador puede innovar y construir nuevas dApps libremente sin permiso, sin necesidad de la aprobación de nadie.

Cuando se crea una dApp (aplicación descentralizada) a partir de Ethereum Blockchain, generalmente implementa su propio token ERC20. Piense en el token REP de Augur o en el token BNT de Bancor. ERC20 es un estándar de token desarrollado después del lanzamiento de ETH que define cómo se transfieren los tokens y cómo mantener un registro coherente de esas transferencias entre tokens en la red Ethereum.

Los servicios descentralizados se pueden combinar para aprovechar sus fortalezas particulares. La pregunta es: ¿Cómo pueden los desarrolladores ampliar la capacidad de un contrato de token ERC20 existente? En este artículo, examinemos un patrón de diseño en torno a la extensibilidad de contratos inteligentes: tokens envueltos.

Ver más ☞ El uso de Wrapped Tokens

Fichas envueltas

Los tokens envueltos son un patrón de diseño en el que 'envuelves' o 'transformas' un token o activo criptográfico existente (ETH, ERC20, BTC) en un nuevo token envuelto con funcionalidad adicional.

La traducción entre Token y Wrapped Token suele ser reversible; los usuarios pueden cambiar entre las dos versiones en cualquier momento. El proceso de envoltura generalmente implica que los usuarios bloqueen sus tokens en un contrato inteligente, que luego acuña una cantidad equivalente de tokens envueltos para el usuario. Los usuarios pueden intercambiar sus tokens envueltos por el contrato inteligente para recuperar sus tokens originales.

Ahora, veamos algunos ejemplos de este patrón en la naturaleza.

Éter envolvente: WETH

Debido a que las plataformas descentralizadas que se ejecutan en Ethereum utilizan contratos inteligentes para facilitar los intercambios directamente entre usuarios, cada usuario debe tener el mismo formato estandarizado para cada token que intercambia. Este formato es ERC-20.

Ether o ETH es la moneda nativa construida sobre la cadena de bloques Ethereum. ETH no cumple con el estándar ERC-20. Fue construido antes de que existiera el estándar ERC20.

WETH es Ether envuelto que admite la interfaz ERC20. Con WETH, puede intercambiar ETH por otros tokens ERC20 en intercambios y DApps.

Cuando "envuelves" ETH, lo intercambias contra un contrato inteligente por un token igual llamado WETH. Si desea recuperar ETH simple, "desenvuelva" WETH cambiándolo por ETH simple. ETH y WETH siempre se intercambian en una proporción de 1:1. La garantía de Ether está bloqueada de forma segura dentro del contrato inteligente hasta que se intercambie por WETH en algún momento en el futuro.

Puede intentar empaquetar ETH en el portal 0x o en el mercado OpenSea NFT . Tenga en cuenta que envolver y desenvolver son transacciones que cuestan gasolina.

Aquí está la interfaz de un contrato inteligente WETH:

contract IWETH is ERC20 {
  event Deposit(address indexed sender, uint256 amount);
  event Withdrawal(address indexed recipient, uint256 amount);

  function deposit() public payable;

  function withdraw(uint256 amount) public;

  function withdraw(uint256 amount, address user) public;
}

Aquí hay una implementación de WETH de muestra:

contract WETH is IWETH {
  string public name = "Wrapped Ether";
  string public symbol = "WETH";
  uint8  public decimals = 18;

  function deposit() public payable {
    _mint(msg.sender, msg.value);
    emit Deposit(msg.sender, msg.value);
  }

  function withdraw(uint amount) public {
    require(balanceOf(msg.sender) >= amount);
    address payable recipient = msg.sender;
    _burn(msg.sender, amount);
    recipient.transfer(amount);
    emit Withdrawal(recipient, amount);
  }

  function withdraw(uint amount, address payable recipient) public {
    require(balanceOf(msg.sender) >= amount);
    recipient.transfer(amount);
    _burn(msg.sender, amount);
    emit Withdrawal(recipient, amount);
  }
}

Tenga en cuenta lo siguiente:

  • El contrato WETH hereda de ERC20, lo que le otorga funciones ERC20 como balanceOf, transfery transferFrom.
  • La interfaz IWETH define las funciones deposity withdrawpara envolver y desenvolver ETH respectivamente.
  • En la depositfunción, cualquier Ether enviado vía payable _mints una msg.valuecantidad equivalente de WETH.
  • En la withdrawfunción, cualquier WETH quemado a través _burndevuelve un equivalente amounta recipient.

En resumen, envolver Ether permite comercializarlo como cualquier token ERC20 y acceder al resto del ecosistema financiero y de intercambio descentralizado.

Los criptoactivos que se pueden empaquetar no se limitan a Ether. También está Wrapped Bitcoin (WBTC) que estandariza Bitcoin al formato ERC20. En el futuro, espere ver otros criptoactivos nativos de otras cadenas de bloques en Ethereum como un token envuelto.

También está Veil Ether , que es similar a WETH con la capacidad adicional de depositar ETH y aprobar en una sola transacción.

Envolviendo tokens ERC20

El patrón Wrapped Tokens se puede aplicar para agregar funcionalidad personalizada a un token ERC20 existente. Veamos algunos ejemplos de extensión de tokens ERC20 existentes.

Metacontenedor ERC20 de Horizon Games

Horizonte

ERC20 Meta Wrapper de Horizon Games agrega métodos de metatransacción a cualquier token que cumpla con el estándar ERC-20.

Cuando deposita tokens ERC-20 (p. ej., DAI) en el contrato de envoltorio, le devolverá metaTokens (p. ej., MetaDAI) con una proporción de 1:1. Estos metaToken tienen funcionalidades nativas de metatransacción, que le permiten transferir tokens sin realizar una transacción en cadena, simplemente firmando un mensaje y transmitiendo este mensaje a los "ejecutores". También puede "aprobar" direcciones para transferir tokens en su nombre con un mensaje firmado en lugar de llamar a la función de aprobación () de ERC-20.

Normalmente, la transferencia de tokens ERC20 cuesta gasolina pagada en Ether. Con metaTokens, los usuarios pueden pagar directamente en cualquier token ERC20 que deseen. Por lo tanto, en un nivel alto, los usuarios podrían transferir DAI pagando la tarifa de transacción en DAI también, sin necesidad de poseer ETH.

Fichas compuestas

Compuesto

Compound es un protocolo de código abierto para mercados monetarios algorítmicos y eficientes en la cadena de bloques de Ethereum. Permite a los usuarios suministrar activos al protocolo y ganar intereses.

Cada activo compatible con el protocolo Compound se integra a través de un contrato inteligente cToken, que es un token compatible con ERC20 que contiene la representación de los saldos suministrados al protocolo. Este token envuelto es la forma principal de interactuar con el protocolo compuesto.

Cada token ERC20 disponible en Compound tiene un token CErc20 correspondiente. Por ejemplo, BAT tiene un cBAT correspondiente y ZRX tiene un cZRX correspondiente. Cada contrato de cToken crea su propio mercado monetario. Cuando un usuario acuña, canjea, toma prestado, paga un préstamo, liquida un préstamo o transfiere cTokens, lo hará utilizando el contrato de cToken.

Curvas de enlace

Bonding curves utiliza una técnica de 'envoltura' similar para acuñar y quemar fichas continuas. Utiliza una curva para acuñar diferentes cantidades según el suministro del token vinculado a la curva.

Resumen

La naturaleza inmutable y de código abierto de los contratos inteligentes permite la innovación sin permiso. Con el patrón de diseño Wrapped Tokens, los desarrolladores pueden ampliar la capacidad de un criptoactivo existente y hacerlo interoperable con otras aplicaciones descentralizadas.

Enlace: https://yos.io/2019/07/13/smart-contract-extensibility-wrapped-tokens/

#token #smart #contract 

Extensibilidad De Contrato Inteligente Con Tokens Envueltos
藤本  結衣

藤本 結衣

1647300360

インクスマートコントラクトを基板チェーンに展開する

ParityのSubstrateブロックチェーンフレームワークを中心とした開発は順調に進んでおり、初期段階ではありますが、インクベースのスマートコントラクトを展開できるようになりました。この記事では、Polkadot JSクライアントを介してコントラクト関数を呼び出す方法にアクセスする前に、Inkスマートコントラクトのコンパイルとデプロイのプロセスについて説明します。

これは、インストールから展開まで、Substrateブロックチェーンと組み合わせたInkスマートコントラクト作成プロセスを探る3部構成のシリーズの最後の部分です。インク契約書作成プロセスに関する前回の記事は、ここにあります。

インク契約のテスト

Inkスマートコントラクトのテストは、オフチェーンとオンチェーンの両方で実行できます(実行する必要があります)。前者はコントラクト自体のモジュールを介して実行できtests、後者はローカルのSubstrate開発チェーンで実行できます。

私の経験では、契約がコンパイルされてデプロイされると、契約エラーが発生しました。オンチェーンテストの重要性を強調します。これらのエラーは、テストモジュールとコンパイルプロセスをバイパスすることに成功したため、テストモジュールに加えて、テストチェーンでコントラクト全体をテストすることが重要です。さらに下にアクセスするPolkadotJSUIを使用すると、これを簡単に行うことができます。

インクコントラクトをテストする最初の手段は、マクロのtests下のモジュールを使用することです。contract!ボイラープレートは次のようになります。

// test function boilerplate
#[cfg(all(test, feature = "test-env"))]
mod tests {
   
   use super::*;
   use std::convert::TryFrom;
   #[test]
   fn it_works() {
      // test function...
   }
}

テスト関数は別のtestsモジュールにラップされており、親モジュールからすべてをインポートするため、問題のスマートコントラクトに関するすべてを認識しています。cfgトップフラグから始めて、コードのよりあいまいな行のいくつかを分解してみましょう。

// config flag to only compile in a test environment
#[cfg(all(test, feature = "test-env"))]

テストはスマートコントラクトでコンパイルされません—チェーン上で不要なスペースを占有します。モジュールには、次useの2つのステートメントも含まれています。tests

// use everything from super module (the smart contract)
use super::*;
// use the TryFrom trait - allowing safe type conversions
use std::convert::TryFrom;

最初の行super::*は、非常に自明です。モジュールはテストしているスマートコントラクトを認識するtests必要があるため、すべてが*親モジュール(スマートコントラクト自体)からスコープに取り込まれます。2番目の引数は、TryFrom特性をスコープに入れます。

トレイトは、状況によっては制御された方法で失敗する可能性のTryFromある、単純で安全な型変換を実装します。

特性try_from()から派生したメソッドを使用して、テストで使用するアドレスを取得しようとします。これは実際、コントラクトインスタンスを初期化した後、テスト内で最初に行うことです。TryFromAccountIdit_works()

#[test]
fn it_works() {
   // initialise a contract instance to test
   let mut _nftoken = NFToken::deploy_mock(100);
   // try to obtain alice's account
   let alice = AccountId::try_from([0x0; 32]).unwrap();
   ...
}

AccountId基板内は32文字で構成されているため、アリスのアドレスは単純に32個のゼロとして宣言されます。Resultアカウントはラップ解除され、aまたはErrorenumから実際のアドレスを取得します。

注:前回の記事で、アンラップのRustの概念について説明しました。

関数定義の#[test]前にステートメントが存在します。これは、この関数をテスト関数にすることをコンパイラーに知らせるRust構文です。cargo testVS Codeは、この方法でテストとしてラベル付けされた各関数の下にテストボタンを埋め込みますが、インクコントラクトをテストするにはわずかに変更されたテストコマンドが必要なため、このボタンをクリックして呼び出すと失敗します。そのコマンドをさらに下に移動します。

内で、Inkフレームワークによって提供されるモックデプロイメント関数it_works()を使用して、コントラクトの可変インスタンスを初期化します。これで、変数deploy_mock()を介してコントラクトを呼び出して操作できるようになりました。は、引数を期待するコントラクトのメソッドを呼び出すため、の値が提供され、その結果、テストの実行時に100個のトークンが作成されます。_nftokendeploy_mock()deploy()init_value100

テストでのアサーションの使用

ここから、残りの部分it_works()は簡単にたどることができます。Rustのアサーションマクロを利用して、トークンを転送したり、他のアカウントにトークンの送信を承認したりするときに、契約の状態が予想どおりに変化するようにしました。

Rustには、標準ライブラリで使用できる3つのアサーションマクロが含まれています。

// assert! - true or false
assert!(some_expression());
// assert_eq! - asserts that 2 expressions are equal
assert_eq!(a, b, "Testing if {} and {} match", a, b);
// assert_ne! - asserts that 2 expressions are not equal
assert_ne!(a, b, "Testing that a and b are not equal");

アサーションが失敗した場合、テスト機能も失敗し、テストが完了すると失敗として報告されます。インクコントラクトをテストするには、次のコマンドを実行します。

cargo test --features test-env -- --nocapture

を使用すると、モジュール内で使用された--no-capture出力を含め、より詳細な出力が提供されます。この機能により、次のように定義されているように、インク環境のみをテストすることが保証されます。println()teststest-env Cargo.toml

[features]
default = []
test-env = [
    "ink_core/test-env",
    "ink_model/test-env",
    "ink_lang/test-env",
]
...

テストが成功すると、次の出力が得られます。

it_works()が渡され、okの結果が出力されます

契約の編集

テストに合格すると、コントラクトをコンパイルできます。build.shこれを行うには、プロジェクトディレクトリ内で実行します。

./build.sh

結果のファイルはあなたのtarget/フォルダに置かれます:

nftoken.wat
nftoken-fixed.wat
nftoken.wasm
nftoken-opt.wasm
nftoken-pruned.wasm
NFToken.json

インクコントラクトは、Webバイナリ標準のWebAssembly、またはにコンパイルされ.wasmます。Substrateにアップロードする上記のコンパイル済み出力からの2つのファイルに関心があります。

  • nftoken-pruned.wasm.wasm:基板チェーンにアップロードする最適化されたファイル
  • NFToken.json:JSON形式の契約ABIコード

注: WebAssemblyに重点を置いているわけではありませんが、より効率的なランタイムのために、このフォーマットがブロックチェーンスペースで頻繁に使用されていることは言及する価値があります。Ethereum 2.0は、eWasmと呼ばれるWebAssemblyのサブセットに依存します。もちろん、Substrateチェーンもこの標準を採用しています。WebAssemblyは主にWebを対象としていますが、ブラウザに限定されるものではありません。WebAssembly仕様は開発中であり、今後数年間でさらに多くの機能がリリースされると予想されるため、非常に興味深いテクノロジーとして使用できます。

イーサリアムベースのコントラクトからのコントラクトABIに精通している場合があります。これは、フロントエンドDappsにオンチェーンでコントラクトと通信する手段を提供します。これらは基本的に、JSONオブジェクト内の関数と変数を含むコントラクトの構造を記述しているため、Javascriptベースのアプリの統合が特に簡単になります。

ここで、コントラクトをデプロイするために、まだ行っていない場合はローカルのSubstrateチェーンを起動し、PolkadotJSアプリを使用してデプロイを管理しましょう。

# run your local Substrate chain
substrate --dev

インク契約の展開

サブストレートチェーンでのコントラクトのデプロイとインスタンス化には、最初にコントラクトをデプロイしてからインスタンス化することが含まれます。この2段階のプロセスにより、開発者は特定の標準(おそらくトークン標準)をデプロイできます。この標準では、他の関係者が独自のトークンの詳細を使用して同じコントラクトをインスタンス化できます。これにより、本質的に同一の機能と同一のABIコードのために、同じ契約の複製をアップロードする必要がなくなります。

繰り返しになりますが、この2つのステップのプロセスには次のものが含まれます。

  1. 契約を基板チェーンにアップロードする
  2. コントラクトのインスタンス化。これは、その後、対話することができます。

これらのタスクは両方とも、Githubで利用可能なオープンソースのTypescriptおよびReactベースのプロジェクトであるPolkadotJSアプリを介して実行できます。

Polkadot JS

.wasm次に、コンパイル済みの.jsonABIをSubstrate開発チェーンにアップロードします。そのためには、PolkadotJSクライアントが必要です。

プロジェクトのクローンを作成してローカルマシンで実行するか、https://polkadot.js.org/appsにアクセスしてオンラインでアクセスできます。クライアントをロードして、次の展開プロセスを開始します。

ステップ1:クライアントがローカルのSubstrateノードに接続されていることを確認します

まず、クライアントが正しいチェーンに接続されていることを確認する必要があります。Settingsタブに移動し、がに設定されていることを確認しremote node/endpoint to connect toますLocal Node (127.0.0.1:9944)Save and Reload変更が必要な場合はヒットします。

注:他のチェーン、AlexanderおよびEmberic Elmは、Parityによって管理される基板ベースのチェーンです。Polkadotなどの他のSubstrateチェーンでの作業はこの記事の範囲外ですが、Pokakdot JSクライアントは実際には、Substrateベースのブロックチェーンで動作するように設計されているため、アプリ全体で表示される内容が非常に動的です。

ステップ2:コンパイルされたコントラクトをノードにデプロイします

コントラクトをデプロイするにはContracts、サイドバーからページに移動し、Codeタブが表示されていることを確認します。ノードにコントラクトをまだデプロイしていない場合は、Codeタブのみが使用可能になります。UIは次のようになります。

PolkadotJS->契約->コードタブ

[コード]タブ:

  • deployment accountがに設定されていることを確認しALICEます。アリスは、契約を展開、インスタンス化、テストするのに十分なバランスを取ります
  • フィールドにドラッグnftoken-pruned.wasmしますcompiled contract WASM
  • オプション:code bundle nameより人間にわかりやすい名前の値を修正します
  • フィールドにドラッグNFToken.jsonしますcontract ABI
  • maximum gas allowedトランザクションを処理するのに十分なガスを確実に供給するために、を500,000に設定します

構成したら、Deployを押してからもう一度確認します。トランザクションが実行され、契約が展開されます。

ステップ3:契約をインスタンス化する

これで、2つの追加のタブが使用可能にInstanceなりCallます。最初にInstanceタブを使用してコントラクトをインスタンス化し、次にタブを使用しCallて機能をテストします。タブは次のInstanceようなものになります。

PolkadotJS->契約->インスタンスタブ

[インスタンス]タブ内:

  • code for this contract値がデプロイされたコントラクトを指していることを確認してください
  • 作成する初期トークン量をinitValue値として設定します。

注: Polkadot UIは現在、コントラクト構造、特に、予想されるデータ型を含む、コントラクトに対して定義したデプロイ関数に提供する必要のある引数を取得しています。これは、Polkadot UIの動的な性質と、さまざまな種類の契約に対応するように設計された方法の一例です。

  • 値を1,000に設定してendowment、新しい契約アカウントに何らかの値が割り当てられるようにします。これは、公式のInkドキュメントからの推奨値です。イーサリアム契約と同様に、インク契約は独自のAccountIdバランスの取れた別のアドレスに展開されます。
  • 繰り返しになりますmaximum gas allowedが、トランザクションに十分なガスを確実に供給するために、を500,000に設定します
  • ヒットInitiateしてトランザクションを実行することを確認します

トランザクションが成功すると、コントラクトがインスタンス化され、関数を呼び出すことができるようになります。

ステップ4:インスタンス化されたコントラクトから関数を呼び出す

私たちの最後の仕事は、関数が期待どおりに機能していることを確認することです。pub(external)コントラクトで定義したすべての関数が、Callタブ内で呼び出してテストできるようになりました。

PolkadotJS内でコントラクト関数を呼び出す機能

Polkadot JSは、クライアント自体の呼び出しからのフィードバックをまだ提供していませんが、新しいブロックが検証されるときに、ターミナルのノードフィードにトランザクションが反映される必要があります。UXに関して現在私たちが持っているのは、関数呼び出しが処理されるときにブラウザウィンドウの右上にポップアップする成功または失敗のイベント通知です。

注:フィードバックメカニズムは、コマンドラインまたはPolkadot JSクライアントのいずれかで利用可能になったときに、ここに掲載されます。

 

概要

インストールからチェーンでのインスタンス化まで、Inkスマートコントラクトの展開の過程を完了しました。簡単な要約として、プロセスを可能にしたさまざまな部分を見てみましょう。

  • 基盤となるRust言語、Cargoパッケージマネージャー、およびSubstrateフレームワークのインストール
  • 独自のCargocrateからアクセスできるInkのインストールと、Inkをコンパイルするために必要なWebAssemblyツール.wasm
  • 環境構成とファイルを含む、インクボイラープレートを取得するための基本的なFlipperインク契約のブートストラップbuild.sh
  • Rustの概念と規則に準拠した、ミンティング、転送、承認機能、およびイベントの放出を伴うNFTokenコントラクトの作成
  • testsとの契約をコンパイルする前に、モジュールを介してテストするbuild.sh
  • ローカルのSubstrate開発チェーンに接続されたPolkadotJSクライアントを介した関数呼び出しのデプロイ、インスタンス化、テスト

私の考え

個人的には、SubstrateプロジェクトとPolkadotプロジェクトは、最終リリースに至るまでフォローするのが非常に興味深いと思います。彼らは、Rust、WebAssembly、およびSubstrateブロックチェーンを可能にするプロトコルなどの新しいテクノロジーを採用することにより、ブロックチェーン空間の最先端の問題を解決しようとしています。

これらのツールを取り巻く開発は非常に協調的で動的であり、さまざまな開発チームや個人がプロトコルを改善するために独自の視点やアイデアを形成することは間違いありません。

このシリーズが、Substrateのスマートコントラクト開発を取り巻くツールのエコシステムに光を当てることを願っています。 

リンク:https ://medium.com/block-journal/deploying-an-ink-smart-contract-to-a-family-chain-f52a2a36efec 

#ink #smart 

インクスマートコントラクトを基板チェーンに展開する
藤本  結衣

藤本 結衣

1647268620

インクを使用した基板スマートコントラクトの紹介

インク!:基板のスマートコントラクト言語

Polkadotがその上に構築されているParityのSubstrateブロックチェーンフレームワークは活発に開発されており、最終リリースに向けて急速に進歩しています。インク(または名前がドキュメントで一般的に呼ばれているインク! )は、基板ベースのブロックチェーンのスマートコントラクトを作成するためのParityのソリューションです。

Substrateと同様に、InkはRustの上に構築されているため、Rustの言語ルールと構文に準拠しています。この講演では、一般にイーサリアムブロックチェーン上のERC721トークンと呼ばれる、代替不可能なトークンを複製するスマートコントラクトの例について説明します。契約自体はGithubのこちらにあります。

これは、このInkスマートコントラクトの作成と展開のプロセスをカバーするシリーズのパート1です。具体的には、以下をカバーします。

注: Polkadot JSアプリは、Polkadot自体だけでなく、任意の基板チェーンを管理するように設計されています。使用可能な管理オプションは、基板チェーンがサポートする機能に依存するという点で、インターフェイスは動的です。

この記事では、Inkのインストールプロセスとそれに必要な依存関係について説明し、このシリーズに付属する非代替トークンのサンプルコントラクトを紹介し、Inkコントラクトの構造と、Solidityベースのコントラクトとの違いについても説明します。 2つの間の類似点として。

代替不可能なトークンに関する注意

非代替トークン(NFT)は、ERC20スタイルのトークンとは異なり、すべてのトークンが一意です。私たちの契約では、各トークンには、トークンを表すために使用される一意のIDがあります。ここから、各トークンは独自の値、独自のメタデータを持つことができ、アプリケーションまたは値システム内で特定の用途を持つことができます。

トークンを転送または管理するための非所有者アカウントの承認も異なり、非代替トークンを使用してトークンごとに行う必要があります。クリプトキティは、代替不可能なトークンが実装されている最もよく知られた例です。各トークンは、プラットフォーム上の子猫を表しています。

NFTは、標準トークンに対してさまざまな課題を提示するため、インクの構文と機能の観点からさらに調査することができます。次に、スマートコントラクトを作成するために、Substrate、Ink、および必要なパッケージをインストールしましょう。

インストール

インク契約の作成を開始するには、いくつかのパッケージが必要です。それらがインストールされると、ターミナルウィンドウでSubstrateチェーンを実行できます—このチェーンをスマートコントラクトを展開する手段として使用します。

さび

基板とインクはRustに依存しています。次のコマンドを使用してRustをインストールするか、インストールページを参照してください。nightlyRustバージョン(利用可能な最新のRustバージョン)が最新であることを確認するための2つのコマンドと、RustのWebAssemblyビルドサポートが以下に含まれていますnightly。インクコントラクトはファイルにコンパイルされ.wasm、その結果、WebAssemblyとしてSubstrateチェーンにデプロイされます。

# install rust and update environmentcurl https://sh.rustup.rs -sSf | sh
source ~/.cargo/env
# run rust updates and add WebAssembly target supportrustup update nightly
rustup target add wasm32-unknown-unknown --toolchain nightly

注: CargoはRustのパッケージマネージャーであり、そのパッケージはCratesと呼ばれます。パブリックカーゴレジストリはhttps://crates.ioで閲覧できます。

注2:最後のコマンドを参照すると、targetは、プログラムのビルドを含むRustプロジェクトディレクトリ内のターゲットフォルダーを指します。これは、スマートコントラクトファイルが構築される場所です。

基板

次のコマンドを使用してSubstrateをインストールします。

curl https://getsubstrate.io -sSf | bash

Wasmユーティリティ

インクスマートコントラクトは、Substrateチェーンにアップロードされる前にWebAssemblyにコンパイルされます。これを行うには、いくつかのユーティリティをインストールする必要があります。

# We will install:
#
# Binaryen
# Compiler infrastructure and toolchain library for WebAssembly
#
# Wabt
# The WebAssembly Binary Toolkit
#
# Parity Wasm Utils
# Parity specific WebAssemply utilities */
# MacOSbrew install binaryen
brew install wabt
cargo install pwasm-utils-cli --bin wasm-prune# Ubuntuapt install binaryen
apt install wabt
cargo install pwasm-utils-cli --bin wasm-prune

インク

ここから、クレートを介してインクをインストールできます。これを行うには、次を実行します。

cargo install --force --git https://github.com/paritytech/ink cargo-contract

ローカル基板チェーンの実行

私たちのスマートコントラクトは、お使いのマシンで実行されているローカルのSubstrateブロックチェーンでテストされます。Substrateがインストールされたら、以下を実行してチェーンを初期化します。

substrate --dev

フラグは—-dev、マシンに対してのみローカルの開発ブロックチェーンを初期化し、オフからのいくつかのユーザーアカウントを含みます。

この設定は、純粋にテストを目的としています。これは、テスト目的で微調整されたローカルのイーサリアムベースのチェーンを実行するTruffleのGanacheプログラムと同等であると考えることができます。

これで、検証中の新しいブロックで実行されているノードに気付くでしょう。ターミナルウィンドウを押すCTRL+Cか閉じるとノードの実行が停止しますが、次にチェーンを実行するまでチェーンの状態は維持されます。このメモで、新しいチェーンを開始する場合は、次のコマンドを実行してチェーンをパージします。

substrate purge-chain --dev

チェーンを実行し、Inkを使用する準備ができたら、コントラクトのコーディングに取り掛かることができます。その前に、エディターのサポートについても言及する価値があります。個人的には、 Visual Studio Codeが、インク開発だけでなく、Rust開発全般の仕事に最適なエディターであることがわかりました。すばやくセットアップするには:

  • エディターをまだインストールしていない場合は、ここからVSCodeをインストールします
  • RLS(Rust Language Support)拡張機能とWebAssembly拡張機能をインストールします。これは、[拡張機能]タブのエディターで直接実行するか、を押しShift+CMD+Xて直接ジャンプすることができます。

インクプロジェクトの設定

すべての依存関係がインストールされたら、プロジェクトをセットアップしましょう。

現在これを行う最も簡単な方法は、 Flipperという名前のInkの「HelloWorld」コントラクトをインストールすることです。Flipperをインストールすると、すでに含まれているものに基づいて構築でき、構成やコンパイルスクリプトについて心配する必要はありません。これらはFlipperで提供されます。

注: SubstrateとInkはどちらも急速に開発されており、まだ機能が完全ではありません。したがって、Parityがフレームワークの最終リリースに近づくにつれて、スマートコントラクト環境とスマートコントラクトコード自体が変更される可能性があります。

インクプロジェクトをジャンプスタートするには、貨物を使用してフリッパーをフェッチします。

#フリッパーインク契約貨物契約新しいフリッパーをフェッチ

Flipperスマートコントラクトの作成を開始するために必要なプロジェクトの定型文を提供します。含まれています:

  • プロジェクトのフォルダー構造と構成メタデータ
  • のベアボーンフリッパーコントラクトは、メソッド間およびメソッドを介してsrc/lib.rsブール値を単純に「フリップ」し、メソッドを使用してこの値をチェーン上で取得します。このファイルをNFT契約に置き換えますtruefalseflip()get()
  • Cargo.tomlプロジェクトの依存関係とモジュールのメタデータ、.gitignoreファイル、およびファイルの概要を示すRust固有のbuild.shファイル。このbuild.shファイルは、スマートコントラクトをコンパイルするために実行するものであり、コントラクトのコンパイル済み.wasmファイル、コントラクトのJSON抽象化などが生成されます。構築されたコントラクトについては、さらに詳しく説明します。

注:今こそsrc/lib.rs、コントラクト構文の感触をつかむためにチェックアウトする良い機会です。

flipper名前をより適切な名前に変更しましょう: nftoken。以下を修正します。

  • /flipperフォルダ名から/nftoken
  • Cargo.toml:変更[package] name[lib] name nftoken
  • build.sh: 改めるPROJNAME=nftoken

また、実行する権限があることを確認してnftoken/build.shください。

cd nftoken
chmod +x build.sh

最後に、/nftokenフォルダーをVS Code Workspaceに追加すると、書き込みを開始する準備が整います。

インクについて

インクには複数のレベルの抽象化があり、高いレベルが低いレベルを抽象化します。言語レベルまたはレベルと呼ばれる最高レベルを使用しlangます。これらのレベルも、ここで調べることができるモジュールに分けられています。

langモジュールの下には、modelcoreモジュールがあり、それぞれ中間レベルの抽象化とコアユーティリティに焦点を当てています。モジュールの下には、core特にインク契約を作成および管理するためのCLIも期待できます。

執筆時点では、これらのモジュールの使用方法についてはほとんど説明されていませんが、coreモジュールとmodelモジュールの両方について、実際に参照できる生のAPIドキュメントがあります。この記事をフォローしている場合は、これらのドキュメントを参照できますが、以下のコントラクトではlang、非代替トークンコントラクトを介してレベルのコンテキストでどのように使用されるかを示すことを目的としたこれらのAPIの一部を利用します。

これを念頭に置いて、次に、lang派生したコントラクトの構造がどのように見えるかを調べ、Solidityベースのスマートコントラクトに期待するものと比較してみましょう。

注意:完了した契約は、Githubで確認できます

契約構造

インクコントラクトの構造化は、Solidityコントラクトの構造に似ています。ここで、Solidityで期待される主要なコンポーネントは、インクでも一貫しています。コントラクト変数、イベント、パブリック関数、プライベート関数、および呼び出し元を取得するための環境変数です。アドレスなど。

以下は、NFToken契約がどのように構成されているかを抽象化したものです。

// declare modules
use parity::<module>
...//wrap entire contract inside the contract! macro
contract! {   // contract variables as a struct
   struct NFToken {
      owner: storage::Value<AccountId>,
      ...
   }   // compulsory deploy method that is run upon the initial contract instantiation
   impl Deploy for NFToken {
      fn deploy(&mut self, init_value: u64){}
   }   // define events
   event EventMint { owner: AccountId, value: u64 } 
   ...   // public contract methods in an impl{} block
   impl NFToken {
      pub(external) fn total_minted(&self) -> u64 {}
      ...
   }   // private contract methods in a separate impl{} block
   imp NFToken {
      fn is_token_owner(
         &self, 
         of: &AccountId, 
         token_id: u64) -> bool {}
       ...
   }
}// test functions
mod tests {
   fn it_works() {}
   ...
}

これらのセクションを簡単に見て、Solidity契約から期待されるものとどのように異なるかを見てみましょう。インクはRustに基づいて構築されているため、ここでの構文はすべて有効なRust構文です。

  • モジュール宣言セクションは、外部機能をコントラクトに組み込む場所であり、Solidityのusing宣言と本質的に似ています。
// Inkuse ink_core::{
    env::{self, AccountId},
    storage,
};
use ink_lang::contract;

// Solidityinterface ContractName {
   using SafeMath for uint256;
   using AddressUtils for address;
}
  • イベントは!contractマクロ内で宣言されますが、Solidityでは、コントラクトインターフェイス内でイベントを定義し、それぞれをevent:として入力します。
// Inkevent Transfer { from: AccountId, to: AccountId, token_id: u64 }// Solidityevent Transfer(
   address indexed from,
   address indexed to,
   uint256 indexed _tokenId
);
  • Solidityコントラクトがinterfaceブロック内に埋め込まれている場合、Inkコントラクトはcontract!マクロ内に埋め込まれます。イベントはこのマクロ内で宣言されますが、イベントはSolidityインターフェース内で宣言されます。これについては、以下で説明します。

注: Rustのマクロは、ラップされた式が囲まれる構文のブロックを表す宣言です。マクロは構文レベルで抽象化されるため、contract!マクロはその内容をより多くの構文でラップしています。

// Ink
contract! {
   // contract
}// Solidityinterface ContractName {
   // contract
}
  • Inkを使用すると、コントラクト変数はコントラクトの名前の構造体で記述されます。Rustのタイプから派生したハッシュマップHashMapは、Solidityのmappingタイプの代わりになり、リストを提供しkey => valueます。

基板が値を保存する方法

基板チェーンに保持されているデータはすべて外部と呼ばれ、 Inkは、言語storageのモジュール内にあるモジュールを介して外部をチェーン上に格納する手段を提供します。coreつまり、チェーンに永続化する予定のすべてのコントラクト変数は、からの型を使用しstorageます。逆に、このmemoryモジュールは、データ構造がメモリ上で動作するためにも使用できます。

一方、Solidityはこれに対して異なるアプローチを採用しています。Solidity 0.5から、関数の引数または関数変数に参照型が導入されたため、コントラクトはこれらの変数を参照する場所を認識していますstoragememoryただし、これはSolidityのコントラクト変数には必要ありません。

プリミティブ型も利用可能であり、両方の言語で一貫しています。Rustが使用するu64場合、Solidityはより詳細なuint64型宣言を採用します。全体として、2つの言語間で同じコントラクト変数構造を実現するのは非常に簡単です。

// Inkstruct NFToken {
   owner: storage::Value<AccountId>,
   approvals: storage::HashMap<u64, AccountId>,
}
// Solidityaddress owner;
mapping (uint64 => address) approvals;

上記の例では、storageオブジェクトが処理する値の型は、型のジェネリックの代わりに山括弧を介して渡されます。

  • 初期化関数の概念は、さまざまな方法で実装されていますが、InkとSolidityの両方に存在します。Inkを使用して、実装ブロックdeploy()内でメソッドを明示的に定義します。Deploy{}このメソッドに定義するパラメーターは、契約を初期化するときに送信するデータを表しています。たとえば、代替不可能なトークンの場合、ミントされるトークンの初期量を提供します。
// Inks initialisation function, deploy()impl Deploy for NFToken {
   fn deploy(&mut self, init_value: u64) {
      ...
   }
 }
  • パブリックメソッドとプライベートメソッドもimplブロック内で定義され、パブリックメソッドはで明示的に定義されpub(external)ます。繰り返しますが、この構文をSolidityの構文と比較するとinternalexternalプライベートまたはパブリックリソースを定義するために使用されます。

注: Rustでは、関数、モジュール、特性、構造体はデフォルトでプライベートであり、pub外部からアクセスできるようにするには、キーワードで定義する必要があります。ここ(external)への拡張pubはインク固有であり、パブリックインク関数に含める必要があります。

// public functionsimpl NFToken {
   pub(external) fn total_minted(&self) -> u64 {}
}// private functionsimpl NFToken {
   fn mint_impl(
      &mut self, 
      receiver: AccountId, 
      value: u64) -> bool { 
    }
}

ここでも、プライベート関数とパブリック関数を別々のimplブロックに分割し、pub(external)定義されたパブリック関数に含めました。

  • コントラクトの最後の構成要素testsとして、関数のテスト時にさまざまな条件をアサートするモジュールが定義されています。モジュール内ではtests、コントラクトロジックをコンパイルしてSubstrateチェーンにデプロイしなくてもテストできるため、バグを迅速に解決し、コントラクトが期待どおりに機能することを確認できます。 

リンク:https ://medium.com/block-journal/introducing-family-smart-contracts-with-ink-d486289e2b59

#ink  #smart #contract 

インクを使用した基板スマートコントラクトの紹介

Presentamos Contratos inteligentes De Sustrato Con Tinta

¡ink!: El lenguaje de contrato inteligente de Substrate

El marco de blockchain de Substrate de Parity , sobre el cual se está construyendo Polkadot, está en desarrollo activo y avanza rápidamente hacia una versión final. Ink (¡o ink! como se denomina comúnmente el nombre en la documentación) es la solución de Parity para escribir contratos inteligentes para una cadena de bloques basada en Substrate.

Al igual que Substrate, Ink se basa en Rust y, por lo tanto, se adhiere a las reglas y la sintaxis del lenguaje Rust. Esta charla analizará un ejemplo de contrato inteligente que replica un token no fungible, comúnmente conocido como tokens ERC721 en la cadena de bloques de Ethereum. El contrato en sí se puede encontrar en Github aquí .

Esta es la Parte 1 de una serie que cubrirá el proceso de creación e implementación de este contrato inteligente de Ink, específicamente, cubriremos:

  • Cómo instalar Substrate and Ink, con sus dependencias
  • Escribir el contrato básico de token no fungible que admitirá 3 funciones principales: acuñar tokens, transferir tokens y aprobar otra cuenta para enviar tokens en su nombre
  • Cómo construir e implementar el contrato inteligente en una cadena de bloques Substrate y probar las funciones en la cadena usando la aplicación Polkadot JS

Nota: La aplicación Polkadot JS se diseñó para administrar no solo Polkadot en sí, sino también cualquier cadena de Substrate . La interfaz es dinámica en el sentido de que las opciones de administración disponibles dependen de las características que admita una cadena de Substrate.

En este artículo, analizaremos el proceso de instalación de Ink y sus dependencias requeridas, y presentaremos el contrato de ejemplo de token no fungible que acompaña a esta serie, hablando sobre la estructura de un contrato de Ink y cómo se diferencia de un contrato basado en Solidity. como semejanzas entre ambos.

Una nota sobre tokens no fungibles

Los tokens no fungibles, o NFT, difieren de los tokens de estilo ERC20 en los que cada token es único. En nuestro contrato, cada token tendrá una identificación única utilizada para representar el token. A partir de aquí, cada token podría tener su propio valor, sus propios metadatos o tener un uso específico dentro de una aplicación o sistema de valores.

La aprobación de cuentas de no propietarios para transferir o administrar el token también es diferente y debe hacerse token por token con tokens no fungibles. Cryptokitties es el ejemplo más conocido en el que se han implementado tokens no fungibles: cada token representa un gatito en la plataforma.

Los NFT presentan diferentes desafíos para un token estándar y, por lo tanto, nos dan más para explorar en términos de sintaxis y capacidades de Ink. A continuación, instalemos Substrate, Ink y los paquetes necesarios para escribir nuestro contrato inteligente.

Instalación

Se necesitan algunos paquetes para comenzar a escribir contratos de tinta. Una vez que estén instalados, podemos ejecutar una cadena Substrate en una ventana de terminal; usaremos esta cadena como medio para implementar nuestro contrato inteligente.

Oxido

El sustrato y la tinta confían en Rust . Instale Rust con los siguientes comandos, o consulte la página de instalación . A continuación, se incluyen dos comandos adicionales para garantizar que su nightlyversión de Rust (la última versión de Rust disponible) esté actualizada, así como la compatibilidad de compilación de WebAssembly para nightlyRust: los contratos de tinta se compilan en .wasmarchivos y, en consecuencia, se implementan en las cadenas de Substrate como WebAssembly.

# install rust and update environmentcurl https://sh.rustup.rs -sSf | sh
source ~/.cargo/env
# run rust updates and add WebAssembly target supportrustup update nightly
rustup target add wasm32-unknown-unknown --toolchain nightly

Nota: Cargo es el administrador de paquetes de Rust, cuyos paquetes se denominan Crates. El registro de carga pública se puede consultar en https://crates.io .

Nota 2: en referencia al último comando, el destino se refiere a la carpeta de destino en el directorio de su proyecto Rust que contiene compilaciones de sus programas. Aquí es donde se construirán nuestros archivos de contratos inteligentes.

Sustrato

Instale Substrate con el siguiente comando:

curl https://getsubstrate.io -sSf | bash

Utilidades de wasm

Los contratos inteligentes de tinta se compilan en WebAssembly antes de cargarlos en una cadena Substrate. Para poder hacer esto, necesitaremos instalar algunas utilidades:

# We will install:
#
# Binaryen
# Compiler infrastructure and toolchain library for WebAssembly
#
# Wabt
# The WebAssembly Binary Toolkit
#
# Parity Wasm Utils
# Parity specific WebAssemply utilities */
# MacOSbrew install binaryen
brew install wabt
cargo install pwasm-utils-cli --bin wasm-prune# Ubuntuapt install binaryen
apt install wabt
cargo install pwasm-utils-cli --bin wasm-prune

Tinta

Desde aquí ahora podemos instalar Ink a través de su caja. Ejecute lo siguiente para hacerlo:

cargo install --force --git https://github.com/paritytech/ink cargo-contract

Ejecución de una cadena de sustrato local

Nuestro contrato inteligente se probará en una cadena de bloques Substrate local que se ejecuta en su máquina. Con Substrate ahora instalado, ejecute lo siguiente para inicializar la cadena:

substrate --dev

La —-devbandera inicializa una cadena de bloques de desarrollo para usted, local solo para su máquina, e incluye algunas cuentas de usuario desde el principio.

Esta configuración es puramente para fines de prueba; podría pensar en él como el equivalente del programa Ganache de Truffle , que ejecuta una cadena local basada en Ethereum modificada con fines de prueba.

Ahora notará que el nodo se ejecuta con nuevos bloques validados. Presionar CTRL+Co cerrar la ventana Terminal detendrá la ejecución del nodo, aunque el estado de la cadena persiste hasta que vuelva a ejecutar la cadena. En esta nota, si desea comenzar una nueva cadena, ejecute lo siguiente para purgar su cadena:

substrate purge-chain --dev

Con nuestra cadena en funcionamiento y Ink listo para usar, podemos empezar a codificar el contrato. Antes de hacerlo, también vale la pena mencionar el soporte del Editor. Personalmente, he encontrado que Visual Studio Code es el mejor editor para el trabajo, no solo para el desarrollo de Ink, sino también para el desarrollo de Rust en general. Para configurarlo rápidamente:

  • Instale VS Code desde aquí si aún no tiene instalado el editor
  • Instale la extensión RLS (Rust Language Support) y las extensiones WebAssembly . Esto se puede hacer directamente en el editor en la pestaña Extensiones, o presione Shift+CMD+Xpara ir directamente a él.

Configuración del proyecto de tinta

Con todas las dependencias instaladas, ahora configuremos el proyecto.

Actualmente, la forma más fácil de hacer esto es instalar el contrato "Hello World" de Ink, llamado Flipper . Con Flipper instalado, podemos aprovechar lo que ya está incluido y no tener que preocuparnos por la configuración y los scripts de compilación; estos se proporcionan en Flipper.

Nota: Tanto Substrate como Ink están en rápido desarrollo y aún no tienen todas las características, por lo tanto, el entorno de contrato inteligente y el código de contrato inteligente en sí probablemente cambiarán a medida que Parity se acerque a la versión final del marco.

Para poner en marcha nuestro proyecto Ink busca Flipper usando cargo:

# buscar el contrato de carga del contrato Flipper Ink nuevo flipper

Flippernos proporciona un modelo de proyecto necesario para comenzar a escribir el contrato inteligente. Se incluye:

  • La estructura de carpetas y los metadatos de configuración del proyecto.
  • Un contrato de Flipper básico en src/lib.rs, que simplemente "cambia" un valor booleano entre trueya falsetravés de un flip()método, y obtiene este valor en cadena usando el get()método. Reemplazaremos este archivo con el contrato NFT
  • El archivo específico de Rust Cargo.toml, que describe las dependencias del proyecto y los metadatos del módulo, un .gitignorearchivo y un build.sharchivo. El build.sharchivo es lo que ejecutamos para compilar nuestro contrato inteligente, lo que da como resultado un .wasmarchivo compilado del contrato, una abstracción JSON del contrato y más. Exploraremos el contrato construido más abajo.

Nota: ahora es un buen momento para revisar src/lib.rsy tener una idea de la sintaxis del contrato.

Cambiemos el nombre flippera un nombre más adecuado: nftoken. Modificar lo siguiente:

  • /flippernombre de la carpeta a/nftoken
  • Cargo.toml: Cambiar [package] namey [lib] name anftoken
  • build.sh: enmendarPROJNAME=nftoken

Además, asegúrese de que tengamos permisos para ejecutar nftoken/build.sh:

cd nftoken
chmod +x build.sh

Por último, agregue la /nftokencarpeta a un espacio de trabajo de VS Code y estamos listos para comenzar a escribir.

Acerca de la tinta

Ink tiene múltiples niveles de abstracción, donde los niveles más altos se abstraen sobre los niveles más bajos. Usaremos el nivel más alto, que se denomina nivel de idioma o langnivel. Estos niveles también se han separado en módulos que se pueden explorar aquí .

Debajo del langmódulo están los módulos modely core, que se enfocan en abstracciones de nivel medio y utilidades principales respectivamente. Debajo del coremódulo también podemos esperar una CLI específicamente para crear y administrar contratos de tinta.

Aunque hay poca cobertura sobre cómo usar estos módulos en el momento de escribir este artículo, de hecho tenemos los documentos API sin procesar para navegar, tanto para el coremódulo como para el modelmódulo. Si está siguiendo este artículo, puede navegar por estos documentos ahora, aunque nuestro contrato a continuación utilizará algunas de estas API con la intención de mostrar cómo se usan en el contexto del langnivel a través del contrato de token no fungible.

Con esto en mente, examinemos a continuación cómo se ve la estructura de nuestro langcontrato derivado y comparémoslo con lo que esperamos de un contrato inteligente basado en Solidity.

Recordatorio: el contrato completo se puede encontrar aquí en Github.

Estructura del contrato

La estructuración de un contrato de Ink es similar a la de un contrato de Solidity, donde los componentes principales que esperamos con Solidity también son consistentes en Ink: variables de contrato, eventos, funciones públicas y funciones privadas, así como variables de entorno para capturar a la persona que llama. dirección y más.

A continuación se muestra una abstracción de cómo NFTokense estructura el contrato:

// declare modules
use parity::<module>
...//wrap entire contract inside the contract! macro
contract! {   // contract variables as a struct
   struct NFToken {
      owner: storage::Value<AccountId>,
      ...
   }   // compulsory deploy method that is run upon the initial contract instantiation
   impl Deploy for NFToken {
      fn deploy(&mut self, init_value: u64){}
   }   // define events
   event EventMint { owner: AccountId, value: u64 } 
   ...   // public contract methods in an impl{} block
   impl NFToken {
      pub(external) fn total_minted(&self) -> u64 {}
      ...
   }   // private contract methods in a separate impl{} block
   imp NFToken {
      fn is_token_owner(
         &self, 
         of: &AccountId, 
         token_id: u64) -> bool {}
       ...
   }
}// test functions
mod tests {
   fn it_works() {}
   ...
}

Visitemos brevemente estas secciones y cómo se diferencian de lo que esperamos de un contrato Solidity. Ink se basa en Rust, por lo que toda la sintaxis aquí es una sintaxis válida de Rust.

  • Nuestra sección de declaración de módulo es donde incorporamos funcionalidad externa al contrato, y es de naturaleza similar a las usingdeclaraciones de Solidity.
// Inkuse ink_core::{
    env::{self, AccountId},
    storage,
};
use ink_lang::contract;

// Solidityinterface ContractName {
   using SafeMath for uint256;
   using AddressUtils for address;
}
  • Los eventos se declaran dentro de la !contractmacro, mientras que con Solidity definimos nuestros eventos dentro de una interfaz de contrato, escribiendo cada uno como event:
// Inkevent Transfer { from: AccountId, to: AccountId, token_id: u64 }// Solidityevent Transfer(
   address indexed from,
   address indexed to,
   uint256 indexed _tokenId
);
  • Donde un contrato de Solidity está incrustado dentro de un interfacebloque, un contrato de Ink está incrustado dentro de una contract!macro. Nuestros eventos se declaran dentro de esta macro, mientras que los eventos se declaran dentro de una interfaz de Solidity. Esto se describe a continuación.

Nota: una macro en Rust es una declaración que representa un bloque de sintaxis que rodeará las expresiones envueltas. Las macros se resumen a nivel sintáctico, por lo que la contract!macro envuelve su contenido con más sintaxis.

// Ink
contract! {
   // contract
}// Solidityinterface ContractName {
   // contract
}
  • Con Ink, nuestras variables de contrato se escriben en una estructura del nombre de nuestro contrato. Los mapas hash derivados del HashMaptipo de Rust están en lugar del mappingtipo de Solidity, proporcionando key => valuelistas.

Cómo Substrate almacena valores

Cualquier dato persistente en una cadena Substrate se denomina extrínseco , e Ink nos proporciona los medios para almacenar extrínsecos en la cadena a través del storagemódulo, que vive dentro del coremódulo del lenguaje. En otras palabras, todas las variables de contrato que planee persistir en la cadena usarán un tipo de storage. Por el contrario, el memorymódulo también está disponible para que las estructuras de datos operen en la memoria.

La solidez, por otro lado, adopta un enfoque diferente a esto. A partir de Solidity 0.5, se introdujeron tipos storagede memoryreferencia a argumentos de función o variables de función, por lo que el contrato sabe dónde hacer referencia a esas variables. Sin embargo, esto no es necesario para las variables de contrato en Solidity.

Los tipos primitivos también están disponibles y son consistentes en ambos idiomas; donde Rust usa u64, Solidity adopta una uint64declaración de tipo más detallada. En general, es bastante simple lograr la misma estructura variable de contrato entre los dos idiomas.

// Inkstruct NFToken {
   owner: storage::Value<AccountId>,
   approvals: storage::HashMap<u64, AccountId>,
}
// Solidityaddress owner;
mapping (uint64 => address) approvals;

En el ejemplo anterior, el tipo de valores que storagemanejan los objetos se pasan a través de corchetes angulares en lugar de los genéricos del tipo.

  • El concepto de una función de inicialización está presente tanto en Ink como en Solidity, aunque se implementa de diferentes maneras. Con Ink, definimos explícitamente un deploy()método dentro de un Deploy{}bloque de implementación. Los parámetros que definimos para este método son representativos de los datos que enviamos al inicializar el contrato. Por ejemplo, para nuestro token no fungible, proporcionaremos una cantidad inicial de tokens para acuñar:
// Inks initialisation function, deploy()impl Deploy for NFToken {
   fn deploy(&mut self, init_value: u64) {
      ...
   }
 }
  • Los métodos públicos y privados también se definen dentro de implbloques, donde los métodos públicos se definen explícitamente con pub(external). Nuevamente, al comparar esta sintaxis con la de Solidity, internaly externalse utilizan para definir un recurso público o privado.

Nota: En Rust, las funciones, los módulos, los rasgos y las estructuras son privados de forma predeterminada y deben definirse con la pubpalabra clave para que sean accesibles externamente. La (external)extensión pubaquí es específica de Ink y es obligatorio incluirla con las funciones públicas de Ink.

// public functionsimpl NFToken {
   pub(external) fn total_minted(&self) -> u64 {}
}// private functionsimpl NFToken {
   fn mint_impl(
      &mut self, 
      receiver: AccountId, 
      value: u64) -> bool { 
    }
}

Nuevamente, hemos separado nuestras funciones públicas y privadas en implbloques separados, y hemos incluido pub(external)funciones públicas definidas.

  • Como último bloque de construcción de nuestro contrato, testsse define un módulo que afirma varias condiciones a medida que se prueban nuestras funciones. Dentro del testsmódulo, podemos probar nuestra lógica de contrato sin tener que compilarla e implementarla en una cadena Substrate, lo que permite corregir rápidamente los errores y verificar que el contrato funciona como se esperaba. 

Enlace: https://medium.com/block-journal/introducing-substrate-smart-contracts-with-ink-d486289e2b59 

#ink #smart #substrate 

Presentamos Contratos inteligentes De Sustrato Con Tinta

What is Smart Contract - Guide for Business Owners

https://www.blog.duomly.com/what-is-smart-contract/

When most people think about contracts, they think about the mundane paperwork task that needs to be completed for two or more parties to exchange goods or services. However, what if there was a way to streamline this process and make it more efficient? Thanks to blockchain technology and smart contracts, this is now a possibility.

In this guide, you will learn what smart contracts are and how they can benefit your business. You will also learn about the different types of smart contracts that are available and how to create and execute them. So whether you are just starting out in business or looking for ways to improve your current operations, read on for all the information you need.

#solidity #smart #blockchain #hyperledger #crypto #cryptocurrency #cryptocurrencies #business #businesses #token #tokens 

What is Smart Contract - Guide for Business Owners

5分でブロックチェーンスマートコントラクトを書く方法

この投稿では、 Elrondブロックチェーンを使用して、簡単なスマートコントラクトを5分で作成、デプロイ、テストする方法について説明します。

What is a smart contract?

スマートコントラクトは、ブロックチェーンに保存され、特定の条件が満たされたときに実行されるコードの一部です。

スマートコントラクトのアプリケーションは次のとおりです。

  • 送金
  • プロパティの所有権を記録する
  • 投票
  • 倉庫の棚卸し

従来のデータベースに比べてブロックチェーンを使用する利点は、ブロックチェーンに権限がなく、トランザクションを検証するために中央の信頼できる機関を必要としないことです。

代わりに、仲介なしで2人の個人間で直接契約を結ぶことができます。

ブロックチェーンをピアツーピアの元帳と考え、スマートコントラクトを元帳の状態に適用できる一連のルールと考えてください。

準備

スマートコントラクトを作成する前に、Elrondブロックチェーンにアカウントを作成します。この手順は厳密には必要ありませんが、この手順がないと、コードをテストできません。

ウォレットを作成するには、devnet-wallet.elrond.comにアクセスし、「ウォレットの作成」を選択します。

次に、記録を残す必要のある秘密のフレーズが表示されます。最後に、パスワードを設定し、キーストアファイルをダウンロードする必要があります。

これはdevnet上にあるため、資金を転送する必要がないことに注意してください。代わりに、偽のテスト資金を蛇口から取得できます。

スマートコントラクトの作成

次に、新しく作成したアカウントでElrondPlaygroundにログインする必要があります。

これを行うには、play.elrond.com / unlockにアクセスし、前の手順のキーストアファイルをドラッグして、パスワードを入力します。

認証に成功すると、テンプレートを選択できるElrondPlaygroundに移動します。「加算器」を選択します。

これにより、 Rustで記述されたスマートコントラクトのテンプレートが作成されます。完全なコードは次のとおりです。

 

契約には3つの方法があります。

  • init()加算器の保存された値を初期化します
  • getSum()加算器の現在の値を返します
  • add()指定された整数を現在の値に追加します

このinit()メソッドは、コントラクトが最初にブロックチェーンにデプロイされたときに呼び出され、初期状態を設定します。getSum()契約自体とadd()の取引を通じて呼び出されます。

コンパイルとデプロイ

次に、スマートコントラクトを展開してテストします。

コンパイルするには、UIの緑色の[コンパイル]ボタンをクリックしてから、[デプロイ]をクリックします。加算器の初期値を入力するように求められます。次に、もう一度「デプロイ」をクリックします。

おめでとうございます。これで、ElrondDevnetブロックチェーンにスマートコントラクトがデプロイされました。

確認するために、Elrondチェーンエクスプローラーで契約を表示できます。これを行うには、Playgroundサイドパネルの[Deployments]をクリックし、[Address]フィールドの横にある虫眼鏡をクリックします。

これにより、以下に示すように契約の詳細が表示されます。

Elrondスマートコントラクトの詳細

テスト

スマートコントラクトをテストするには、Elrondウォレットに偽のEGLDトークンを追加する必要があります。これを行うには、 devnet-wallet.elrond.comに再度アクセスし、サインインして、左側のパネルから「蛇口」を選択します。

キャプチャを完了してから、「トークンのリクエスト」を選択します。これにより、ウォレットに10xEGLDが配置されます。

ここで、 play.elrond.comに戻り、右側のパネルで[展開]タブを選択してから、[相互作用]フィールドの横にある三角形をクリックします。これにより、インタラクションパネルが開きます。

ここに、メソッドの現在の結果と、getSum()メソッドを実行するための三角形が表示されadd()ます。これをクリックすると、加算器に追加する値を設定できます。

次に、「送信送信」をクリックします。これにより、ブロックチェーン上のスマートコントラクトにトランザクションが送信add()され、指定された値でメソッドが呼び出されます。

契約の状態を変更し、単に読み取り専用ではないためadd()、Elrond開発ウォレットから料金を支払うように求められます。

トランザクションが実行されると、「インタラクション」パネルに再度アクセスして、コントラクトの状態が更新されgetSum()、加算器の新しい値が返されることを確認できます。

これらのトランザクションは、「展開」パネルに再度アクセスし、「アドレス」フィールドの横にある虫眼鏡をクリックすることによって、ブロックチェーンで確認することもできます。

結論

Elrond Playgroundsを使用すると、スマートコントラクトの作成、変更、展開、およびテストを簡単に行うことができます。ここで調べた単純な加算器は、出発点にすぎません。次のステップとして、読者は他のいくつかの例の遊び場を探索することをお勧めします。 

リンク:https ://betterprogramming.pub/how-to-write-a-blockchain-smart-contract-in-5-minutes-a6bda5e9c1b1

#blockchain  #smart 

5分でブロックチェーンスマートコントラクトを書く方法

Cómo Escribir Un Contrato inteligente Blockchain En 5 Minutos

En esta publicación, explicaré cómo escribir, implementar y probar un contrato inteligente simple en 5 minutos utilizando la cadena de bloques de Elrond .

What is a smart contract?

Un contrato inteligente es un fragmento de código que se almacena en una cadena de bloques y se ejecuta cuando se cumplen ciertas condiciones.

Las aplicaciones de los contratos inteligentes incluyen:

  • Transferencia de fondos
  • Registro de la propiedad de la propiedad
  • Votación
  • Inventario de almacén

La ventaja de usar una cadena de bloques sobre las bases de datos tradicionales es que las cadenas de bloques no requieren permiso y no requieren una autoridad central de confianza para validar las transacciones.

En cambio, un contrato se puede hacer directamente entre dos personas sin un intermediario.

Piense en una cadena de bloques como un libro mayor de igual a igual y en un contrato inteligente como un conjunto de reglas que se pueden aplicar al estado del libro mayor.

Preparación

Antes de escribir nuestro contrato inteligente, vamos a crear una cuenta en la cadena de bloques de Elrond. Este paso no es estrictamente necesario, pero sin él no podremos probar nuestro código.

Para crear una billetera, visite devnet-wallet.elrond.com y seleccione "Crear billetera".

Luego se le presentará una frase secreta, de la que debe mantener un registro. Finalmente, deberá establecer una contraseña y descargar un archivo Keystore.

Tenga en cuenta que, como esto está en la red de desarrollo, no necesitará transferir ningún fondo. En cambio, se pueden adquirir fondos de prueba falsos a través de un faucet .

Creando el contrato inteligente

A continuación, debemos iniciar sesión en Elrond Playground con nuestra cuenta recién creada.

Para hacer esto, visite play.elrond.com/unlock , arrastre su archivo Keystore del paso anterior e ingrese su contraseña.

Una vez que se haya autenticado con éxito, será dirigido a Elrond Playground, donde podrá elegir una plantilla. Seleccione "sumador".

Esto crea una plantilla para un contrato inteligente escrito en Rust . El código completo es el siguiente:

 

El contrato tiene tres modalidades:

  • init()inicializa el valor almacenado del sumador
  • getSum()devuelve el valor actual del sumador
  • add()agrega un entero proporcionado al valor actual

Se init()llama al método cuando el contrato se implementa por primera vez en la cadena de bloques y establece el estado inicial. getSum()y add()se llamará a través de transacciones con el propio contrato.

Compilación y despliegue

A continuación, implementaremos y probaremos el contrato inteligente.

Para compilar, simplemente haga clic en el botón verde "Compilar" en la interfaz de usuario, luego haga clic en "Implementar". Se le pedirá que ingrese un valor inicial para el sumador. Ahora haga clic en "Implementar" nuevamente.

¡Felicitaciones, ahora ha implementado un contrato inteligente en la cadena de bloques de Elrond Devnet!

Para confirmar, puede ver el contrato en el explorador de cadenas de Elrond. Para hacer esto, haga clic en "Implementaciones" en el panel lateral de Playground y haga clic en la lupa junto al campo "Dirección".

Esto mostrará los detalles del contrato como se ve a continuación.

Detalles del contrato inteligente de Elrond

Pruebas

Para probar el contrato inteligente, debemos agregar algunos tokens EGLD falsos a nuestra billetera Elrond. Para hacer esto, vuelva a visitar devnet-wallet.elrond.com , inicie sesión y seleccione "Grifo" en el panel izquierdo.

Complete el Captcha y luego seleccione "Solicitar tokens". Esto colocará 10 xEGLD en su billetera.

Ahora, regrese a play.elrond.com y seleccione la pestaña "Implementaciones" en el panel derecho, luego haga clic en el triángulo junto al campo "Interacción". Esto abrirá el panel de interacción.

Aquí vemos el resultado actual del getSum()método, así como un triángulo para ejecutar el add()método. Hacer clic aquí nos permitirá establecer un valor para agregar a nuestro sumador.

Ahora haga clic en "Enviar tx". Esto enviará una transacción al contrato inteligente en la cadena de bloques, lo que activará la add()llamada al método con el valor proporcionado.

Debido a que add()modifica el estado del contrato, y no es simplemente de solo lectura, se nos pedirá que paguemos una tarifa de nuestra billetera de desarrollo de Elrond.

Una vez ejecutada la transacción, podemos volver a visitar el panel de “Interacción” y ver que el estado del contrato se ha actualizado y que getSum()devuelve el nuevo valor del sumador.

Estas transacciones también se pueden confirmar en la cadena de bloques al volver a visitar el panel "Implementaciones" y hacer clic en la lupa junto al campo "Dirección".

Conclusiones

Elrond Playgrounds facilita la creación, modificación, implementación y prueba de contratos inteligentes. El sumador simple que hemos explorado aquí es solo un punto de partida. Como siguiente paso, se anima a los lectores a explorar algunos de los otros ejemplos de áreas de juego. 

Enlace: https://betterprogramming.pub/how-to-write-a-blockchain-smart-contract-in-5-minutes-a6bda5e9c1b1

#blockchain  #smart 

Cómo Escribir Un Contrato inteligente Blockchain En 5 Minutos
宇野  和也

宇野 和也

1643693340

Solidityスマートコントラクトを複製するためのコントラクトファクトリの作成

ブロックチェーン開発では、データのセットをブロックチェーンにマイニングすることは、次のブロックにマイニングされる新しいデータごとに料金が請求されるため、非常にコストのかかるプロセスです。スマートコントラクトをブロックチェーンにデプロイすると、コントラクトのデータが次のブロックにマイニングされます。これには、Ethereumブロックチェーンにデプロイされた場合にEtherで請求されるガス料金がかかります。

この記事では、ファクトリパターンを使用してスマートコントラクトの複数のインスタンスを正しい方法でデプロイする方法を実際に示します。また、ファクトリパターン、その利点、およびいつ使用するかについても説明します。

前提条件

この記事を続けるには、Solidityを使用したスマートコントラクトの開発に関する予備知識が必要です。

ファクトリデザインパターンは、よく知られているプログラミングパターンです。概念は単純です。オブジェクトのインスタンスを直接作成する代わりに、それを実行する単一のオブジェクト(ファクトリ)があります。

スマートコントラクトはオブジェクトであるため、これはSolidityでも同じです。Solidityでは、ファクトリは他のコントラクトの複数のインスタンスをデプロイするコントラクトです。

さまざまなタイプのオブジェクトを作成する必要がある場合もありますが、実行時にコードが実行されるまで、どの種類のオブジェクトをインスタンス化するかはわかりません。そのような場合、ファクトリーテクニックが役に立ちます。

通常、基本的なファクトリコントラクトは、同じコントラクトの複数のインスタンスをデプロイし、これらの作成されたインスタンスをブロックチェーンに格納し、必要に応じてそれらを取得できる必要があります。コントラクトの特定のインスタンスを取得したり、コントラクトのインスタンスを無効にしたりするなど、デプロイされたコントラクトを管理するための機能を追加することもできます。

Solidityでファクトリパターンを使用する利点

Solidityでファクトリパターンを使用する利点は次のとおりです。

  1. 燃費の良い複数契約の展開
  2. 展開されたすべての契約を追跡する
  3. 複数の契約展開でガスを節約

ファクトリパターンを使用する場合

ファクトリパターンは、次の状況で有効です。

  • 実行時にスマートコントラクトの複数のインスタンスをすばやく作成する必要がある場合
  • すべて同じ機能を持つ多数の契約を扱っている場合

Solidityのファクトリパターンの種類

Solidityスマートコントラクトで一般的に実装される2種類のファクトリパターンについて説明します。これらのパターンは次のとおりです。

  • 通常のファクトリパターン—このファクトリパターンは、各デプロイメントでガスを節約するための最適化なしで、他のコントラクトの複数のインスタンスをデプロイします
  • 複製されたファクトリパターン—このファクトリパターンは、各展開でガスを節約するための最適化に重点を置いて、他のコントラクトの複数のインスタンスを展開します

私たちの最初のSolidityスマートコントラクト

ファクトリコントラクトが複数のインスタンスをデプロイするために使用する単純なスマートコントラクトを作成します。

// SPDX-License-Identifier: MIT
pragma solidity >0.4.23 <0.9.0;

contract Foundation {
    string public name;
    address public _owner;

    constructor(
        string memory _name,
        address _owner
    ) public {
        name = _name;
        _owner = msg.sender;
    }

}

イーサリアムはオープンソースプロジェクトであるため、最初の行は契約のオープンソースライセンスを示しています。2行目は、このコントラクトを実行するために必要なSolidityバージョンを指定します。

その後、Foundation他のオブジェクト指向プログラミング言語のクラスに類似したコントラクトを確立します。ここでのコンストラクター関数は、引数として指定された値を使用してコントラクトの状態変数を初期化します。コントラクトのインスタンスを作成すると、constructor関数が呼び出されます。

私たちの最初の工場契約を書く

財団契約は現在、作成する手段がありません。したがって、通常のファクトリパターンを使用してFoundationコントラクトの個々のインスタンスを作成するファクトリコントラクトを作成します。

以下は、通常の工場契約がどのように見えるかです。

// SPDX-License-Identifier: MIT
pragma solidity >0.4.23 <0.9.0;
import "./Foundation.sol";
contract FoundationFactory {
    Foundation[] private _foundations;
    function createFoundation(
        string memory name
    ) public {
        Foundation foundation = new Foundation(
            name,
            msg.sender
        );
        _foundations.push(foundation);
    }
    function allFoundations(uint256 limit, uint256 offset)
        public
        view
        returns (Foundation[] memory coll)
    {
        return coll;
    }
}

Foundationここで、このコードは、複数のインスタンスを作成するコントラクトをインポートします。_foundations変数は、Foundation作成されたコントラクトのインスタンスを保持します。

関数はコントラクトのインスタンスをデプロイしてブロックチェーンに格納し、関数はブロックcreateFoundationチェーンに格納されているコントラクトのすべてのインスタンスを取得します。FoundationallFoundationsFoundation

通常のファクトリパターンの欠点

CREATEオペコードのガスコストは現在32,000Gweiです。契約のインスタンスFoundationが展開されるたびに、32,000Gweiのガス料金が請求されます。

通常のファクトリパターンの主な欠点は、ガスコストが高いことです。そして、そこでクローン化されたファクトリパターンが役に立ちます。

クローンファクトリパターン:Solidityスマートコントラクトの複数のインスタンスをデプロイするための適切なパターン

なぜクローンファクトリパターンなのか?

同じコントラクトをデプロイしているため、コントラクトの各インスタンスは同じバイトコードを持ちます。したがって、各展開のすべてのバイトコードを繰り返し保存すると、バイトコードのガスコストの浪費が促進されます。

これに対する解決策は、コントラクトの1つのインスタンスのみをデプロイし、Foundationコントラクトの他のすべてのインスタンスをFoundationプロキシとして動作させ、コントラクトの最初のインスタンスへの呼び出しを委任しFoundation、プロキシコントラクトのコンテキストで関数を実行できるようにするメカニズムです。これにより、コントラクトの各インスタンスはFoundation独自の状態を持ちFoundation、ライブラリとして確立されたコントラクトのインスタンスを使用するだけです。

Peter MurrayNate WelchJoe Messermanによって作成されたeip -1167は、このメカニズムを提供します。そのドキュメントによると、「この標準は、既知の固定アドレスへのすべての呼び出しを委任して、コントラクト機能を不変の方法で簡単かつ安価に複製する最小限のバイトコード実装を指定しています。」

クローンファクトリコントラクトは、eip-1167標準のリファレンス実装です。

クローンファクトリパターンの使用

クローンファクトリコントラクトを実装するには、次のようにクローンファクトリパッケージをインストールする必要があります。

npm install @optionality.io/clone-factory

FoundationFactoryこれで、クローンファクトリコントラクトを次のように実装できます。

// SPDX-License-Identifier: MIT
pragma solidity >0.4.23 <0.9.0;
import "./Foundation.sol";
import "@optionality.io/clone-factory/contracts/CloneFactory.sol";
import "zeppelin-solidity/contracts/ownership/Ownable.sol";


contract FoundationFactory is Ownable, CloneFactory {

  address public libraryAddress;

  event FoundationCreated(address newFoundation);

  function FoundationFactory(address _libraryAddress) public {
    libraryAddress = _libraryAddress;
  }

  function setLibraryAddress(address _libraryAddress) public onlyOwner {
    libraryAddress = _libraryAddress;
  }

  function createFoundation(string _name) public onlyOwner {
    address clone = createClone(libraryAddress);
    Foundation(clone).init(_name);
    FoundationCreated(clone);
  }
}

ここではOwnable、OpenZeppelinライブラリからコントラクトをインポートして、onlyOwnerモディファイアを利用します。これは、自分で作成する場合に比べて監査され、安全性が高いためです。

libraryAddress上記のスニペットを使用すると、より低いガスコストですべての呼び出しを契約に委任する契約があります。

これはより優れたメカニズムですが、次の点に注意する必要があります。

  • マスターコントラクトが自己破壊されないようにしてください。これにより、すべてのクローンが機能しなくなり、状態とバランスが凍結されます。
  • マスターコントラクトコンストラクターが呼び出されるのはマスターコントラクトの作成中のみであるため、マスターコントラクトがコンストラクターで事前に初期化されていることを確認してください

クローンファクトリ契約の展開

これで、Truffleを使用して開発している場合は、次の新しい移行ファイルを作成することで、ファクトリコントラクトをデプロイできます。

const FoundationFactoryContract = artifacts.require("FoundationFactory");
module.exports = function(deployer) {
 deployer.deploy(FoundationFactoryContract);
}

Hardhatを使用して開発している場合は、このethers.getContractFactory方法で対応できるため、自分で工場契約を作成する必要はありません。

Foundation次のように、契約を展開して展開できます。

const hre = require("hardhat");
async function main() {
  const Foundation= await hre.ethers.getContractFactory("Foundation");
  const foundation= await NFTMarket.deploy();
  await foundation.deployed();
  console.log("Foundation contract deployed to: ", foundation.address);
}

通常のファクトリパターンとクローンファクトリパターンの比較

と通常の工場のガスコストの違いを調べるために、CloneFactory各コントラクトをテストネットにデプロイし、各コントラクトのcreateFoundation関数を実行してから、エクスプローラーでトランザクションハッシュをチェックして、使用されたガスの量を確認します。createFoundation以下は、機能の実行時に請求されるガス料金です。

クローン工場の
ガス料金:
ベース:12.959896517 Gwei

通常の工場
ガス料金:
ベース:25.529794514 Gwei

結論

この記事では、ファクトリパターン、その利点、そのタイプ、およびスマートコントラクトに最適な場合について説明しました。また、クローン化されたファクトリパターンは、ガスのコスト効率が高いため、Solidityスマートコントラクトの複数のインスタンスを展開するための適切なパターンであることがわかりました。

うまくいけば、この投稿が有益で役立つことがわかりました。 

リンク:https ://blog.logrocket.com/creating-contract-factory-clone-solidity-smart-contracts/

#clone  #smart 

Solidityスマートコントラクトを複製するためのコントラクトファクトリの作成

Desarrollo De Contratos inteligentes Con Solidity

En el desarrollo de cadenas de bloques, la extracción de conjuntos de datos en una cadena de bloques es un proceso bastante costoso porque se cobran tarifas por cada nuevo dato extraído en el siguiente bloque. La implementación de contratos inteligentes en blockchain da como resultado la extracción de datos del contrato en el siguiente bloque, lo que costará algunas tarifas de gas que se cobran en Ether si se implementan en la cadena de bloques Ethereum.

Este artículo demostrará de manera práctica cómo implementar varias instancias de su contrato inteligente de la manera correcta utilizando el patrón de fábrica. Además, discutiremos el patrón de fábrica, sus beneficios y cuándo usarlo.

Requisito previo

Para continuar con este artículo, debe tener conocimiento previo del desarrollo de contratos inteligentes con Solidity.

El patrón de diseño de fábrica es un patrón de programación bien conocido. El concepto es simple: en lugar de crear instancias de objetos directamente, tiene un solo objeto (la fábrica) que lo hace por usted.

Esto es lo mismo con Solidity porque los contratos inteligentes son objetos. En Solidity, una fábrica es un contrato que implementará múltiples instancias de otros contratos.

A veces necesitamos crear diferentes tipos de objetos, pero no sabemos qué tipo de objeto instanciaremos hasta que el código se ejecute en tiempo de ejecución. En tales casos, la técnica de fábrica es útil.

En general, un contrato de fábrica básico debería poder implementar varias instancias del mismo contrato, almacenar estas instancias creadas en la cadena de bloques y recuperarlas cuando sea necesario. Es posible que desee agregar más funciones para administrar los contratos implementados, como recuperar una instancia específica del contrato, deshabilitar una instancia del contrato, etc.

Beneficios de usar el patrón de fábrica en Solidity

Los siguientes son los beneficios de usar el patrón de fábrica en Solidity:

  1. Despliegues de contratos múltiples con alta eficiencia de gas
  2. Realice un seguimiento de todos los contratos desplegados
  3. Ahorre gasolina en múltiples implementaciones de contratos

Cuándo usar el patrón de fábrica

El patrón de fábrica es efectivo en las siguientes situaciones:

  • Cuando necesitamos producir rápidamente múltiples instancias de un contrato inteligente en tiempo de ejecución
  • Cuando se trata de una gran cantidad de contratos que tienen todas las mismas funcionalidades

Tipos de patrones de fábrica en Solidity

Analizaremos dos tipos de patrones de fábrica comúnmente implementados en los contratos inteligentes de Solidity . Estos patrones incluyen:

  • El patrón de fábrica normal: este patrón de fábrica implementa varias instancias de otros contratos sin ninguna optimización para ahorrar combustible en cada implementación
  • El patrón de fábrica clonado: este patrón de fábrica implementa múltiples instancias de otros contratos con énfasis en la optimización para ahorrar gasolina en cada implementación

Nuestro primer contrato inteligente Solidity

Crearemos un contrato inteligente simple que será utilizado por el contrato de fábrica para implementar varias instancias del mismo:

// SPDX-License-Identifier: MIT
pragma solidity >0.4.23 <0.9.0;

contract Foundation {
    string public name;
    address public _owner;

    constructor(
        string memory _name,
        address _owner
    ) public {
        name = _name;
        _owner = msg.sender;
    }

}

Dado que Ethereum es un proyecto de código abierto, la primera línea muestra la licencia de código abierto del contrato. La segunda línea especifica la versión de Solidity necesaria para ejecutar este contrato.

A continuación, establecemos el Foundationcontrato, que es análogo a una clase en otros lenguajes de programación orientados a objetos. La función constructora aquí inicializa las variables de estado del contrato con los valores proporcionados como argumentos. Cuando creamos una instancia del contrato, constructorse llama a la función.

Escribiendo nuestro primer contrato de fábrica

El contrato de la Fundación actualmente no tiene medios para ser creado. Entonces, vamos a hacer un contrato de fábrica que creará las instancias individuales del contrato de la Fundación utilizando el patrón de fábrica normal.

A continuación se muestra cómo debería ser un contrato de fábrica normal:

// SPDX-License-Identifier: MIT
pragma solidity >0.4.23 <0.9.0;
import "./Foundation.sol";
contract FoundationFactory {
    Foundation[] private _foundations;
    function createFoundation(
        string memory name
    ) public {
        Foundation foundation = new Foundation(
            name,
            msg.sender
        );
        _foundations.push(foundation);
    }
    function allFoundations(uint256 limit, uint256 offset)
        public
        view
        returns (Foundation[] memory coll)
    {
        return coll;
    }
}

Aquí, este código importa el Foundationcontrato, del cual queremos crear múltiples instancias. La _foundationsvariable contiene las instancias del Foundationcontrato creado.

La createFoundationfunción implementa una instancia del Foundationcontrato y la almacena en la cadena de bloques mientras que la función allFoundationsrecupera todas las instancias del Foundationcontrato almacenadas en la cadena de bloques.

Un inconveniente del patrón normal de fábrica.

El costo de gas para el código de operación CREAR es actualmente de 32,000 Gwei. Cada vez que se implementa una instancia del Foundationcontrato, se cobra una tarifa de gas de 32,000 Gwei.

El mayor inconveniente del patrón normal de fábrica son los altos costos de la gasolina . Y ahí es donde el patrón de fábrica clonado resulta útil.

El patrón de fábrica de clones: el patrón correcto para implementar múltiples instancias de nuestro contrato inteligente Solidity

¿Por qué el patrón de fábrica de clones?

Dado que estamos implementando el mismo contrato, cada instancia del contrato tendrá un código de bytes idéntico. Por lo tanto, almacenar todo el código de bytes para cada implementación promueve repetidamente el desperdicio de costos de gas para el código de bytes.

La solución a esto es un mecanismo para implementar solo una instancia del Foundationcontrato y hacer que todas las demás instancias del Foundationcontrato se comporten como proxies, delegando llamadas a la primera instancia del Foundationcontrato y permitiendo que las funciones se ejecuten en el contexto de los contratos de proxy. Con esto, cada instancia del Foundationcontrato tendrá su propio estado y simplemente utilizará la instancia del Foundationcontrato establecida por nosotros como una biblioteca.

El eip-1167 creado por Peter Murray , Nate Welch , Joe Messerman proporciona este mecanismo. De acuerdo con su documentación , "Este estándar especifica una implementación mínima de código de bytes que delega todas las llamadas a una dirección fija conocida para clonar de manera simple y económica la funcionalidad del contrato de manera inmutable".

El contrato de fábrica de clones es una implementación de referencia del estándar eip-1167 .

Usando el patrón de fábrica de clones

Para implementar el contrato de fábrica de clones, deberá instalar el paquete de fábrica de clones de la siguiente manera:

npm install @optionality.io/clone-factory

Ahora podemos implementar el contrato de fábrica de clones en nuestro FoundationFactoryde la siguiente manera

// SPDX-License-Identifier: MIT
pragma solidity >0.4.23 <0.9.0;
import "./Foundation.sol";
import "@optionality.io/clone-factory/contracts/CloneFactory.sol";
import "zeppelin-solidity/contracts/ownership/Ownable.sol";


contract FoundationFactory is Ownable, CloneFactory {

  address public libraryAddress;

  event FoundationCreated(address newFoundation);

  function FoundationFactory(address _libraryAddress) public {
    libraryAddress = _libraryAddress;
  }

  function setLibraryAddress(address _libraryAddress) public onlyOwner {
    libraryAddress = _libraryAddress;
  }

  function createFoundation(string _name) public onlyOwner {
    address clone = createClone(libraryAddress);
    Foundation(clone).init(_name);
    FoundationCreated(clone);
  }
}

Aquí, importamos el Ownablecontrato de la biblioteca OpenZeppelin para hacer uso de su onlyOwnermodificador, ya que está auditado y es más seguro en comparación con escribir uno nosotros mismos.

Con el fragmento anterior, tenemos un contrato que delegará todas las llamadas al contrato libraryAddressa un costo de gas más bajo.

Si bien este es un mejor mecanismo, debe tener en cuenta lo siguiente:

  • Asegúrese de que su contrato maestro no se autodestruya, ya que hará que todos los clones dejen de funcionar, congelando así su estado y saldos.
  • Asegúrese de que su contrato maestro esté preinicializado en su constructor porque la única vez que se llama al constructor del contrato maestro es durante la creación del contrato maestro.

Implementación de su contrato de fábrica de clones

Ahora, si está desarrollando con Truffle, puede implementar el contrato de fábrica creando un nuevo archivo de migración con lo siguiente:

const FoundationFactoryContract = artifacts.require("FoundationFactory");
module.exports = function(deployer) {
 deployer.deploy(FoundationFactoryContract);
}

Si está desarrollando con Hardhat, el ethers.getContractFactorymétodo lo tiene cubierto, por lo que no es necesario que cree un contrato de fábrica usted mismo.

Puede continuar e implementar el Foundationcontrato de la siguiente manera:

const hre = require("hardhat");
async function main() {
  const Foundation= await hre.ethers.getContractFactory("Foundation");
  const foundation= await NFTMarket.deploy();
  await foundation.deployed();
  console.log("Foundation contract deployed to: ", foundation.address);
}

Comparación entre la fábrica normal y los patrones de fábrica de clones

Para examinar la diferencia en el costo del gas entre la CloneFactoryfábrica y la normal, implementaremos cada contrato en una red de prueba, luego ejecutaremos la createFoundationfunción de cada contrato, luego verificaremos el hash de la transacción en el explorador para saber cuánto gas se usó. A continuación se muestra la tarifa de gas cobrada al ejecutar la createFoundationfunción:


Tarifas de gas de fábrica de clones :
Base: 12.959896517 Gwei


Tarifas normales de gas de fábrica :
Base: 25.529794514 Gwei

Conclusión

En este artículo, hemos explorado el patrón de fábrica, sus beneficios, sus tipos y cuándo se adapta mejor a nuestros contratos inteligentes. Además, hemos establecido que el patrón de fábrica clonada es el patrón correcto para implementar múltiples instancias de nuestro contrato inteligente Solidity debido a su eficiencia de costos de gas.

Esperamos que haya encontrado esta publicación informativa y útil. 

Enlace: https://blog.logrocket.com/creating-contract-factory-clone-solidity-smart-contracts/

#clone #smart #solidity 

Desarrollo De Contratos inteligentes Con Solidity

スマートコントラクトを開発し、Terraブロックチェーンネットワークに展開します

独自のスマートコントラクトを構築することは、Web 3の開始以来存在しており、人々がブロックチェーンに展開するプログラムを構築できるようにしています。

スマートコントラクトを展開するブロックチェーンは、イーサリアムからビットコイン、さらにはそれ以上の範囲です。さらに、スマートコントラクトは連携して分散型アプリケーションを構成します。分散型アプリケーションは、Truffle、Hardhat、Embarkなどのフレームワークで開発できます。

この記事では、スマートコントラクトを開発し、それらをイーサリアムに似たTerraブロックチェーンネットワークにデプロイする方法を見ていきます。

Terraの基本的な概要

読む前にTerraについて注意すべき点がいくつかあります。

また、Terraのコンセンサスは、TendermintBFTを使用したプルーフオブステークアルゴリズムであることに注意してください。これにより、保有者は取引を検証するための担保としてトークンを賭けることができます。その後、賭けたトークンの量に応じて報酬が与えられます。

LUNAはTerraの暗号通貨であり、プルーフオブステークブロックチェーンを強化するために使用されることを知っておくことも重要です。このブロックチェーンは、アルゴリズムを拡張して供給を減らすことにより、価格の安定性を提供します。

詳細については、こちらのドキュメントを読みになることをお勧めします。この記事の主な焦点は、スマートコントラクトをこのブロックチェーンプロトコルにデプロイする方法です。

そして最後に、Terraブロックチェーンは、ビットコインやイーサリアムよりも高速に、トランザクションのバッチを数秒で完了する強力で強力なコンセンサスメカニズムを誇っています。

要件と開発の基本

Terraプロトコルを使用してスマートコントラクトを構築および展開するために必要な要件を見てみましょう。

  • Rustプログラミング言語の知識
  • Terraエコシステムに精通している
  • コンピューターにインストールされているDocker
  • テラコア
  • LocalTerra

ただし、上記の要件がなくても心配する必要はありません。すべてをカバーします。ただし、Terraチームによると、最後の要件の1つは、従来の金融を混乱させる/混乱させることを望んでいることです。

環境設定

始める前にインストールする必要があるものがいくつかあります。このインストールは、契約書を作成するときにTerraのローカルテストネットに接続し、の最新バージョンを提供するのに役立ちますterradTerraコアでterrad動作します。

Rustをまだインストールしていない場合は、インストールする必要があります。

まず、Terra Coreをインストールしましょう。これには、最初にGoをインストールする必要があります。これを行うには、このリンク使用してGoをダウンロードし、以下を確認します。

➜  ~ go version
go version go1.17 darwin/amd64

TerraCoreを使用するために必要なバージョンv1.17 +に移行します。

TerraCoreのインストール

GitHubからリポジトリのクローンを作成して、TerraCoreをインストールします。次に、最新リリースのメインブランチを確認します。

$ git clone https://github.com/terra-money/core terra-core
$ cd terra-core
$ git checkout main

次に、Terra Coreをインストールして取得しますterrad。これは、Terraノードと対話するための実行可能ファイルとして機能します。

$ make install

次に、正常にインストールされたことを確認します。

$ terrad version --long

出力は次のようになります。

name: terra
server_name: terrad
version: 0.5.12-1-gd411ae7
commit: d411ae7a276e7eaada72973a640dcab69825163f
build_tags: netgo,ledger
go: go version go1.17 darwin/amd64

LocalTerraのインストール

LocalTerraは、開発中にスマートコントラクトをテストするためのテストネットになります。ローカルテストネットは、WebAssembly統合で構成されています。 LocalTerraはコンテナ化されているため、LocalTerraを起動するには、Dockerを使用してdocker-composeセットアップする必要があります。

$ git clone --depth 1 https://www.github.com/terra-money/LocalTerra
$ cd LocalTerra

Dockerをバックグラウンドで実行している状態で、次のコマンドを実行します。

$ docker-構成する

以下の応答が表示されます。これはログです。

 11:25PM INF Timed out dur=4955.7669 height=5 module=consensus round=0 step=1
terrad_1         | 11:25PM INF received proposal module=consensus proposal={"Type":32,"block_id":{"hash":"54D9C757E9AA84E0F5AAA736E6EED3D83F364A3A62FDC625970539CA81DFA86E","parts":{"hash":"2517579A126AC2BF6EB9EB6274FAE6748D14115C91FC59FE3A2AF5F061A12740","total":1}},"height":5,"pol_round":-1,"round":0,"signature":"AMxXngubsUHyterTZuZsiLgY0olPDpdpgjMIRZ9L59UR9+JngC93xO63yTxwE0kQLp2HdZ99G8M4ATchS7d1CA==","timestamp":"2021-12-16T23:25:00.8000592Z"}
terrad_1         | 11:25PM INF received complete proposal block hash=54D9C757E9AA84E0F5AAA736E6EED3D83F364A3A62FDC625970539CA81DFA86E height=5 module=consensus
terrad_1         | 11:25PM INF finalizing commit of block hash=54D9C757E9AA84E0F5AAA736E6EED3D83F364A3A62FDC625970539CA81DFA86E height=5 module=consensus num_txs=0 root=84C2F2EF6B7FC8B3ACED8B2B0D2921D649F13CE54C5AB5B032DE988D1392E0FD
terrad_1         | 11:25PM INF minted coins from module account amount=226569846uluna from=mint module=x/bank
terrad_1         | 11:25PM INF executed block height=5 module=state num_invalid_txs=0 num_valid_txs=0
terrad_1         | 11:25PM INF commit synced commit=436F6D6D697449447B5B32382031303020373220323137203234312038352031363320313520313530203137382031353820323235203133312032343620313538203235322031333420313238203134392031383220323033203131372039382031333420312035382032333720323120333620313534203136203134335D3A357D
terrad_1         | 11:25PM INF committed state app_hash=1C6448D9F155A30F96B29EE183F69EFC868095B6CB756286013AED15249A108F height=5 module=state num_txs=0
terrad_1         | 11:25PM INF indexed block height=5 module=txindex
terrad_1         | 11:25PM INF Ensure peers module=pex numDialing=0 numInPeers=0 numOutPeers=0 numToDial=10
terrad_1         | 11:25PM INF No addresses to dial. Falling back to seeds module=pex
terrad_1         | 11:25PM INF Timed out dur=4975.4085 height=6 module=consensus round=0 step=1
terrad_1         | 11:25PM INF received proposal module=consensus proposal={"Type":32,"block_id":{"hash":"5FE8526C43C0B32BEF011299D67FDA44DBD625E0B69836D175C25C1F914DD06E","parts":{"hash":"BE583EC25B30F52E652FA28DEAB869D98602B3FB82CD0D9C80ADF96A210CC8D4","total":1}},"height":6,"pol_round":-1,"round":0,"signature":"Bx3WaDl3hhR9IkDjXRa+dXkSIK0Tezl07gZhDm4RXyJyHq0oriAkQD23Q9+ly1+cFhGIdKF3hyvH3GcjCNLvAQ==","timestamp":"2021-12-16T23:25:05.823444Z"}

これで、LocalTerraネットワークに接続されました。接続するポート番号は次のとおりです。

Rustのインストール

RustはTerraがスマートコントラクトを使用および作成するために選択したものです。RustはWebAssemblyにコンパイルでき、WebAssemblyツールはTerra用に十分に成熟して構築されているためです。

MacOSまたはLinuxのようなOSにRustをインストールするには、次のコマンドを実行します。

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Windowsを使用している場合は、このリンクを使用してください

正常にインストールされたらwasm32-unknown-unknown、コンパイルのターゲットを追加する必要があります。

$ rustup target add wasm32-unknown-unknown

最後に、cargo-generateCosmWasmスマートコントラクトテンプレートをスキャフォールディングし、スマートコントラクトcargo-run-scriptを最適化するためにインストールしましょう。

$ cargo install cargo-generate --features vendored-openssl
$ cargo install cargo-run-script

ついにインストールが完了しました🙂

Terraでスマートコントラクトを作成して探索する

LocalTerraネットワークが実行され、私たちを待っているので、私たちは少しスマートコントラクトを作成し、それらを展開する準備ができています、そして私たちはその日のために終わりました!

インストールしたのでcargo-generate、作業プロジェクトをすばやく足場にすることができます。これは、コントラクトを作成するためのフォルダー構造に役立ちます。これを行うには、次のコマンドを使用します。

$ cargo generate --git https://github.com/CosmWasm/cw-template.git --name PROJECT_NAME

の場合PROJECT_NAME、プロジェクトの名前を付ける必要があります。以下は、前のコマンドを実行した後に取得する必要があるものです。

Vectormikes-MacBook-Pro:Projects macbookpro$ cargo generate --git https://github.com/CosmWasm/cw-template.git --name terra-demo
   Generating template ...
[ 1/34]   Done: .cargo/config
[ 2/34]   Done: .cargo
[ 3/34]   Skipped: .circleci/config.yml
[ 4/34]   Done: .circleci
[ 1/34]   Done: .cargo/config
[ 2/34]   Done: .cargo
[ 3/34]   Skipped: .circleci/config.yml
[ 4/34]   Done: .circleci
[ 5/34]   Done: .editorconfig
[ 6/34]   Done: .github/workflows/Basic.yml
[ 7/34]   Done: .github/workflows
[ 8/34]   Done: .github
[ 9/34]   Done: .gitignore
[10/34]   Done: .gitpod.Dockerfile
[11/34]   Done: .gitpod.yml
[ 1/34]   Done: .cargo/config
[ 2/34]   Done: .cargo
[ 3/34]   Skipped: .circleci/config.yml
[ 4/34]   Done: .circleci
[ 5/34]   Done: .editorconfig
[ 6/34]   Done: .github/workflows/Basic.yml
[ 7/34]   Done: .github/workflows
[ 8/34]   Done: .github
[ 9/34]   Done: .gitignore
[10/34]   Done: .gitpod.Dockerfile
[11/34]   Done: .gitpod.yml
[12/34]   Done: Cargo.lock
[13/34]   Done: Cargo.toml
[14/34]   Done: Developing.md
[15/34]   Done: Importing.md
[16/34]   Done: LICENSE
[17/34]   Done: NOTICE
[18/34]   Done: Publishing.md
[19/34]   Done: README.md
[20/34]   Done: examples/schema.rs
[21/34]   Done: examples
[22/34]   Done: rustfmt.toml
[23/34]   Done: schema/count_response.json
[24/34]   Done: schema/execute_msg.json
[25/34]   Done: schema/instantiate_msg.json
[26/34]   Done: schema/query_msg.json
[27/34]   Done: schema/state.json
[28/34]   Done: schema
[29/34]   Done: src/contract.rs
[30/34]   Done: src/error.rs
[31/34]   Done: src/lib.rs
[32/34]   Done: src/msg.rs
[33/34]   Done: src/state.rs
[34/34]   Done: src
   Moving generated files into: `/Users/macbookpro/Desktop/Projects/terra-demo`...
   Done! New project created /Users/macbookpro/Desktop/Projects/terra-demo

見るとsrc/msg.rs、ファイル、我々は我々のスマート契約に送信できるメッセージの3種類を見ることができます。まず、これにはInstantiateMsg、スマートコントラクトの状態を設定するが含まれます。つまり、スマートコントラクトがスピンアップされたときに初期状態を指定する必要があります。

2つ目ExecuteMsgは、ブロックチェーンへのメッセージの投稿など、状態変化に対するアクションを実行するメッセージです。そして最後に、それQueryMsgはそれが聞こえる通りです:それはチェーンへのクエリとして機能し、そこからデータを取得します。

これらがコード内で使用されている方法を見てみましょう。

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct InstantiateMsg {
    pub count: i32,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ExecuteMsg {
    Increment {},
    Reset { count: i32 },
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum QueryMsg {
    // GetCount returns the current count as a json-encoded number
    GetCount {},
}
// We define a custom struct for each query response
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct CountResponse {
    pub count: i32,
}

契約に移る前にStatesrc/state.rsファイル内にあるインターフェースを見てみましょう。

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use cosmwasm_std::Addr;
use cw_storage_plus::Item;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct State {
    pub count: i32,
    pub owner: Addr,
}
pub const STATE: Item<State> = Item::new("state");

私たちの構造体は、State含んでいなければならないcounti32ownerのをAddr。Terraによると、Key-ValueストレージであるTerraのアクティブなLevelDBのために、私たちの状態は永続的です。

それを念頭に置いて、私たちの契約はsrc/contract.rsファイルにあります:

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
    deps: DepsMut,
    _env: Env,
    info: MessageInfo,
    msg: InstantiateMsg,
) -> Result<Response, ContractError> {
    let state = State {
        count: msg.count,
        owner: info.sender.clone(),
    };
    set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
    STATE.save(deps.storage, &state)?;
    Ok(Response::new()
        .add_attribute("method", "instantiate")
        .add_attribute("owner", info.sender)
        .add_attribute("count", msg.count.to_string()))
}

このinstantiateメソッドは、サポートするインターフェースとともに、4つの引数、deps_ 、、、およびを想定しています。次に、期待される結果または期待される結果を期待します。envinfomsgResponseContractError

ここではContractErrorsrc/error.rsファイルで定義しました。

use cosmwasm_std::StdError;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ContractError {
    #[error("{0}")]
    Std(#[from] StdError),
    #[error("Unauthorized")]
    Unauthorized {},
    // Add any other custom errors you like here.
    // Look at https://docs.rs/thiserror/1.0.21/thiserror/ for details.
}

のような他のいくつかのインターフェースResponseもからインポートされましたcosmwasm_std

#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult};
use cw2::set_contract_version;

次に、メソッドのために、我々はまた、持っているexecutequery私たちの契約で:

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
    deps: DepsMut,
    _env: Env,
    info: MessageInfo,
    msg: ExecuteMsg,
) -> Result<Response, ContractError> {
    match msg {
        ExecuteMsg::Increment {} => try_increment(deps),
        ExecuteMsg::Reset { count } => try_reset(deps, info, count),
    }
}

pub fn try_increment(deps: DepsMut) -> Result<Response, ContractError> {
    STATE.update(deps.storage, |mut state| -> Result<_, ContractError> {
        state.count += 1;
        Ok(state)
    })?;
    Ok(Response::new().add_attribute("method", "try_increment"))
}
pub fn try_reset(deps: DepsMut, info: MessageInfo, count: i32) -> Result<Response, ContractError> {
    STATE.update(deps.storage, |mut state| -> Result<_, ContractError> {
        if info.sender != state.owner {
            return Err(ContractError::Unauthorized {});
        }
        state.count = count;
        Ok(state)
    })?;
    Ok(Response::new().add_attribute("method", "reset"))
}

ここで、try_incrementでカウント状態を増大させる1、及びtry_resetカウント状態をリセットする、に使用される関数であるexecute関数。

最後に、queryストレージから状態または情報を取得するカウントは、以下で実行されます。

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
    match msg {
        QueryMsg::GetCount {} => to_binary(&query_count(deps)?),
    }
}
fn query_count(deps: Deps) -> StdResult<CountResponse> {
    let state = STATE.load(deps.storage)?;
    Ok(CountResponse { count: state.count })
}

スマートコントラクトをLocalTerraにアップロードする

これで、コンパイル中にエラーをチェックするスマートコントラクトを構築して、修正できるようになりました。そのために、次のコマンドを実行します。

$ cargo wasm

そしてcargo-run-script、ビルドの最適化を支援するためにインストールしたのと同じように、今はそれを使用する必要があります。

$カーゴラン-スクリプト最適化

プロジェクトディレクトリに、のコードがartifacts/terra_demo.wasm表示されます。これはまもなくLocalTerraにアップロードされます。これで、ローカルテストネット名とノードモニカを作成できます。

$ terrad init --chain-id=<testnet_name> <node_moniker>

これにより、ニーモニックを入力するように求められます。

 $ terrad keys add <account_name>

Terraによると、以下のニーモニックを持つアカウントがネットワーク上の唯一のバリデーターです。

満足する調整材高購入授業料スツール信仰あなたが気づいていないフィードドメインライセンスが上司に課す人間の熱心な帽子の家賃は夜明けを楽しむ

次に、コードをTerraネットワークにアップロードできます。

terrad tx wasm store artifacts/terra_demo.wasm --from demo --chain-id=localterra --gas=auto --fees=100000uluna --broadcast-mode=block

これにより、LocalTerraにプッシュできるように「yes」と入力する必要がある許可が求められます。成功すると、契約はLocalTerraネットワークにブロードキャストされます。

結論

Terraのスマートコントラクトの表面をかじり始めたばかりです。これは、TerraプロトコルでdAppを構築する方法の概要のみを示しているはずです。

このプロトコルに基づいて構築することを強くお勧めします。これは、その活発に成長しているユーザーベースと、LUNAを含むTerraステーブルコインが支払いソリューションに追加されているためです。これは朗報です。

また、高速で効率的なコンセンサスがあり、将来のリリースでより効率的になります。

リン:https//blog.logrocket.com/developing-terra-smart-contracts/

#terra  #smart 

スマートコントラクトを開発し、Terraブロックチェーンネットワークに展開します

Implementar Contratos Inteligentes En La Red Terra Blockchain

La creación de sus propios contratos inteligentes ha existido desde el inicio de Web 3, lo que permite a las personas crear programas para implementar en una cadena de bloques.

Las cadenas de bloques que implementan contratos inteligentes van desde Ethereum hasta Bitcoin y más. Además, los contratos inteligentes funcionan en conjunto para crear aplicaciones descentralizadas, que se pueden desarrollar en marcos como Truffle, Hardhat y Embark.

En este artículo, veremos cómo podemos desarrollar contratos inteligentes e implementarlos en la red Terra blockchain, que es similar a Ethereum.

Una descripción básica de Terra

Algunas cosas a tener en cuenta sobre Terra antes de seguir leyendo:

  • Los contratos inteligentes implementados en la cadena de bloques Terra están escritos en Rust
  • nuestra red de prueba local es LocalTerra
  • Terra.js y Terra SDK son las dos bibliotecas disponibles que se utilizan para interactuar con la cadena de bloques Terra.
  • Terra fue creado por Terraform Labs

Además, tenga en cuenta que el consenso de Terra es el algoritmo de prueba de participación que utiliza el Tendermint BFT. Esto permite a los titulares apostar sus tokens como garantía para validar transacciones. Las recompensas se otorgan posteriormente de acuerdo con la cantidad de tokens apostados.

También es importante saber que LUNA es la criptomoneda de Terra y se utiliza para impulsar la cadena de bloques de prueba de participación. Esta cadena de bloques ofrece estabilidad de precios al expandirse algorítmicamente y reducir la oferta.

Para comprender más, le sugiero que lea la documentación aquí . Nuestro enfoque principal para este artículo es cómo podemos implementar nuestro contrato inteligente en este protocolo blockchain.

Y finalmente, la cadena de bloques Terra se jacta de un mecanismo de consenso fuerte y vigoroso que finaliza lotes de transacciones en segundos, más rápido que Bitcoin y Ethereum .

Requisitos y conceptos básicos de desarrollo

Veamos los requisitos necesarios para construir e implementar contratos inteligentes utilizando el protocolo Terra:

  • Conocimiento del lenguaje de programación Rust
  • Familiaridad con el ecosistema Terra
  • Docker instalado en su computadora
  • Núcleo de la tierra
  • LocalTerra

Sin embargo, no se preocupe por los requisitos anteriores si no los tiene, los cubriremos todos. Sin embargo, un último requisito, según el equipo de Terra, es tener el deseo de interrumpir / perturbar las finanzas tradicionales.

 

Configuración del entorno

Hay algunas cosas que debemos instalar antes de comenzar. Esta instalación nos ayudará a conectarnos a la red de prueba local de Terra cuando redactemos contratos y proporcionemos la última versión de terrad. terradfunciona con el núcleo Terra .

También necesitará instalar Rust si aún no lo tiene.

Para comenzar, instalemos Terra Core, que requiere que instalemos Go primero. Para hacer esto, descargue Go usando este enlace y verifique:

➜ ~ versión go
go versión go1.17 darwin / amd64

Vaya a la versión v1.17 +, que es necesaria para usar Terra Core.

Instalación de Terra Core

Instale Terra Core clonando el repositorio de GitHub. Luego, consulte la rama principal que tiene la última versión:

$ git clone https://github.com/terra-money/core terra-core
$ cd terra-core
$ git checkout main

A continuación, instale Terra Core para obtener terrad, que servirá como ejecutable para interactuar con el nodo Terra:

$ make install

Luego, verifique que lo haya instalado correctamente:

$ terrad version --long

Su salida debe verse similar a la siguiente:

name: terra
server_name: terrad
version: 0.5.12-1-gd411ae7
commit: d411ae7a276e7eaada72973a640dcab69825163f
build_tags: netgo,ledger
go: go version go1.17 darwin/amd64

Instalación de LocalTerra

LocalTerra será nuestra red de prueba para probar nuestros contratos inteligentes durante el desarrollo. Nuestra red de prueba local consiste en la integración de WebAssembly . Para activar LocalTerra, debe tener Docker ydocker-compose  configurarlo porque LocalTerra está en contenedores:

$ git clone --depth 1 https://www.github.com/terra-money/LocalTerra
$ cd LocalTerra

Con Docker ejecutándose en segundo plano, ejecute el siguiente comando:

$ docker-compose up

Debería obtener la respuesta a continuación, que son registros:

 11:25PM INF Timed out dur=4955.7669 height=5 module=consensus round=0 step=1
terrad_1         | 11:25PM INF received proposal module=consensus proposal={"Type":32,"block_id":{"hash":"54D9C757E9AA84E0F5AAA736E6EED3D83F364A3A62FDC625970539CA81DFA86E","parts":{"hash":"2517579A126AC2BF6EB9EB6274FAE6748D14115C91FC59FE3A2AF5F061A12740","total":1}},"height":5,"pol_round":-1,"round":0,"signature":"AMxXngubsUHyterTZuZsiLgY0olPDpdpgjMIRZ9L59UR9+JngC93xO63yTxwE0kQLp2HdZ99G8M4ATchS7d1CA==","timestamp":"2021-12-16T23:25:00.8000592Z"}
terrad_1         | 11:25PM INF received complete proposal block hash=54D9C757E9AA84E0F5AAA736E6EED3D83F364A3A62FDC625970539CA81DFA86E height=5 module=consensus
terrad_1         | 11:25PM INF finalizing commit of block hash=54D9C757E9AA84E0F5AAA736E6EED3D83F364A3A62FDC625970539CA81DFA86E height=5 module=consensus num_txs=0 root=84C2F2EF6B7FC8B3ACED8B2B0D2921D649F13CE54C5AB5B032DE988D1392E0FD
terrad_1         | 11:25PM INF minted coins from module account amount=226569846uluna from=mint module=x/bank
terrad_1         | 11:25PM INF executed block height=5 module=state num_invalid_txs=0 num_valid_txs=0
terrad_1         | 11:25PM INF commit synced commit=436F6D6D697449447B5B32382031303020373220323137203234312038352031363320313520313530203137382031353820323235203133312032343620313538203235322031333420313238203134392031383220323033203131372039382031333420312035382032333720323120333620313534203136203134335D3A357D
terrad_1         | 11:25PM INF committed state app_hash=1C6448D9F155A30F96B29EE183F69EFC868095B6CB756286013AED15249A108F height=5 module=state num_txs=0
terrad_1         | 11:25PM INF indexed block height=5 module=txindex
terrad_1         | 11:25PM INF Ensure peers module=pex numDialing=0 numInPeers=0 numOutPeers=0 numToDial=10
terrad_1         | 11:25PM INF No addresses to dial. Falling back to seeds module=pex
terrad_1         | 11:25PM INF Timed out dur=4975.4085 height=6 module=consensus round=0 step=1
terrad_1         | 11:25PM INF received proposal module=consensus proposal={"Type":32,"block_id":{"hash":"5FE8526C43C0B32BEF011299D67FDA44DBD625E0B69836D175C25C1F914DD06E","parts":{"hash":"BE583EC25B30F52E652FA28DEAB869D98602B3FB82CD0D9C80ADF96A210CC8D4","total":1}},"height":6,"pol_round":-1,"round":0,"signature":"Bx3WaDl3hhR9IkDjXRa+dXkSIK0Tezl07gZhDm4RXyJyHq0oriAkQD23Q9+ly1+cFhGIdKF3hyvH3GcjCNLvAQ==","timestamp":"2021-12-16T23:25:05.823444Z"}

Ahora, estamos conectados a la red LocalTerra. Los siguientes son los números de puerto con los que conectarse:

Instalación de Rust

Rust es lo que Terra eligió usar y escribir contratos inteligentes porque Rust puede compilar en WebAssembly y las herramientas de WebAssembly están bien desarrolladas y construidas para Terra.

Para instalar Rust en MacOS o cualquier sistema operativo similar a Linux, ejecute el siguiente comando:

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Si usa Windows, use este enlace .

Una vez instalado con éxito, debemos agregar el wasm32-unknown-unknowndestino para la compilación:

$ rustup target add wasm32-unknown-unknown

Por último, cargo-generateinstalemos para montar una plantilla de contrato inteligente de CosmWasm y cargo-run-scriptoptimizar nuestros contratos inteligentes:

$ cargo install cargo-generate --features vendored-openssl
$ cargo install cargo-run-script

¡Finalmente hemos terminado con las instalaciones🙂!

Escribir y explorar un contrato inteligente en Terra

Con nuestra red LocalTerra en funcionamiento y esperándonos, estamos listos para escribir un pequeño contrato inteligente, implementarlos y ¡terminamos por hoy!

Desde que lo instalamos cargo-generate, podemos montar rápidamente un proyecto de trabajo. Esto nos ayudará con la estructura de carpetas para escribir nuestros contratos. Para hacer esto, use el siguiente comando:

$ cargo generate --git https://github.com/CosmWasm/cw-template.git --name PROJECT_NAME

Pues PROJECT_NAME, debes nombrarlo con el nombre de tu proyecto. A continuación se muestra lo que debería obtener después de ejecutar el comando anterior:

Vectormikes-MacBook-Pro:Projects macbookpro$ cargo generate --git https://github.com/CosmWasm/cw-template.git --name terra-demo
   Generating template ...
[ 1/34]   Done: .cargo/config
[ 2/34]   Done: .cargo
[ 3/34]   Skipped: .circleci/config.yml
[ 4/34]   Done: .circleci
[ 1/34]   Done: .cargo/config
[ 2/34]   Done: .cargo
[ 3/34]   Skipped: .circleci/config.yml
[ 4/34]   Done: .circleci
[ 5/34]   Done: .editorconfig
[ 6/34]   Done: .github/workflows/Basic.yml
[ 7/34]   Done: .github/workflows
[ 8/34]   Done: .github
[ 9/34]   Done: .gitignore
[10/34]   Done: .gitpod.Dockerfile
[11/34]   Done: .gitpod.yml
[ 1/34]   Done: .cargo/config
[ 2/34]   Done: .cargo
[ 3/34]   Skipped: .circleci/config.yml
[ 4/34]   Done: .circleci
[ 5/34]   Done: .editorconfig
[ 6/34]   Done: .github/workflows/Basic.yml
[ 7/34]   Done: .github/workflows
[ 8/34]   Done: .github
[ 9/34]   Done: .gitignore
[10/34]   Done: .gitpod.Dockerfile
[11/34]   Done: .gitpod.yml
[12/34]   Done: Cargo.lock
[13/34]   Done: Cargo.toml
[14/34]   Done: Developing.md
[15/34]   Done: Importing.md
[16/34]   Done: LICENSE
[17/34]   Done: NOTICE
[18/34]   Done: Publishing.md
[19/34]   Done: README.md
[20/34]   Done: examples/schema.rs
[21/34]   Done: examples
[22/34]   Done: rustfmt.toml
[23/34]   Done: schema/count_response.json
[24/34]   Done: schema/execute_msg.json
[25/34]   Done: schema/instantiate_msg.json
[26/34]   Done: schema/query_msg.json
[27/34]   Done: schema/state.json
[28/34]   Done: schema
[29/34]   Done: src/contract.rs
[30/34]   Done: src/error.rs
[31/34]   Done: src/lib.rs
[32/34]   Done: src/msg.rs
[33/34]   Done: src/state.rs
[34/34]   Done: src
   Moving generated files into: `/Users/macbookpro/Desktop/Projects/terra-demo`...
   Done! New project created /Users/macbookpro/Desktop/Projects/terra-demo

Al mirar el src/msg.rsarchivo, podemos ver tres tipos de mensajes que podemos enviar a nuestro contrato inteligente. Primero, esto incluye InstantiateMsg, que establece el estado en el contrato inteligente, lo que significa que se debe otorgar un estado inicial al contrato inteligente cuando se activa.

En segundo lugar, ExecuteMsges un mensaje que ejecuta una acción para el cambio de estado, como publicar un mensaje en la cadena de bloques. Y finalmente, QueryMsges como suena: funciona como una consulta a la cadena, obteniendo datos de ella.

Veamos cómo se usan estos dentro del código:

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct InstantiateMsg {
    pub count: i32,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum ExecuteMsg {
    Increment {},
    Reset { count: i32 },
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum QueryMsg {
    // GetCount returns the current count as a json-encoded number
    GetCount {},
}
// We define a custom struct for each query response
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct CountResponse {
    pub count: i32,
}

Antes de continuar con el contrato, vamos a ver qué interfaz que tenemos en nuestra Statedentro del src/state.rsarchivo:

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use cosmwasm_std::Addr;
use cw_storage_plus::Item;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct State {
    pub count: i32,
    pub owner: Addr,
}
pub const STATE: Item<State> = Item::new("state");

Nuestra estructura,, Statedebe contener un countde i32y el ownerde Addr. Según Terra, nuestro estado es persistente debido al LevelDB activo de Terra , que es un almacenamiento de valor clave .

Con eso en mente, nuestro contrato se encuentra en el src/contract.rsarchivo:

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
    deps: DepsMut,
    _env: Env,
    info: MessageInfo,
    msg: InstantiateMsg,
) -> Result<Response, ContractError> {
    let state = State {
        count: msg.count,
        owner: info.sender.clone(),
    };
    set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
    STATE.save(deps.storage, &state)?;
    Ok(Response::new()
        .add_attribute("method", "instantiate")
        .add_attribute("owner", info.sender)
        .add_attribute("count", msg.count.to_string()))
}

El instantiatemétodo espera cuatro argumentos, deps, _ env, infoy msg, con sus interfaces de apoyo. Entonces esperamos un resultado que será nuestro esperado Responseo ContractError.

Aquí, definimos nuestro ContractErroren el src/error.rsarchivo:

use cosmwasm_std::StdError;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ContractError {
    #[error("{0}")]
    Std(#[from] StdError),
    #[error("Unauthorized")]
    Unauthorized {},
    // Add any other custom errors you like here.
    // Look at https://docs.rs/thiserror/1.0.21/thiserror/ for details.
}

Algunas otras interfaces como Responsetambién se importaron desde cosmwasm_std:

#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult};
use cw2::set_contract_version;

A continuación, para los métodos, también tenemos executey queryen nuestro contrato:

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
    deps: DepsMut,
    _env: Env,
    info: MessageInfo,
    msg: ExecuteMsg,
) -> Result<Response, ContractError> {
    match msg {
        ExecuteMsg::Increment {} => try_increment(deps),
        ExecuteMsg::Reset { count } => try_reset(deps, info, count),
    }
}

pub fn try_increment(deps: DepsMut) -> Result<Response, ContractError> {
    STATE.update(deps.storage, |mut state| -> Result<_, ContractError> {
        state.count += 1;
        Ok(state)
    })?;
    Ok(Response::new().add_attribute("method", "try_increment"))
}
pub fn try_reset(deps: DepsMut, info: MessageInfo, count: i32) -> Result<Response, ContractError> {
    STATE.update(deps.storage, |mut state| -> Result<_, ContractError> {
        if info.sender != state.owner {
            return Err(ContractError::Unauthorized {});
        }
        state.count = count;
        Ok(state)
    })?;
    Ok(Response::new().add_attribute("method", "reset"))
}

Aquí,, lo try_incrementque aumenta el estado de conteo en 1, y try_reset, lo que restablece el estado de conteo, son funciones utilizadas en la executefunción.

Por último, el queryrecuento, que obtiene el estado o la información del almacenamiento para nosotros, se puede ver ejecutado a continuación:

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
    match msg {
        QueryMsg::GetCount {} => to_binary(&query_count(deps)?),
    }
}
fn query_count(deps: Deps) -> StdResult<CountResponse> {
    let state = STATE.load(deps.storage)?;
    Ok(CountResponse { count: state.count })
}

Subiendo el contrato inteligente a LocalTerra

Ahora podemos crear nuestro contrato inteligente para comprobar si hay errores durante la compilación para poder solucionarlo. Para hacer eso, ejecutamos lo siguiente:

$ cargo wasm

Y tal como lo instalamos cargo-run-scriptpara ayudar a optimizar nuestras compilaciones, ahora debemos usarlo:

$ cargo run-script optimizar

En el directorio del proyecto, deberíamos ver el código en artifacts/terra_demo.wasm, que subiremos a LocalTerra en breve. Ahora podemos crear un nombre de testnet local y un nombre de nodo:

$ terrad init --chain-id=<testnet_name> <node_moniker>

Esto le pedirá que ingrese su mnemotécnico:

 $ terrad keys add <account_name>

Según Terra, la cuenta con el siguiente mnemónico es el único validador en la red:

satisfacer ajustar madera alta compra matrícula taburete fe multa instalar que desconoces alimentar dominio licencia imponer jefe humano ansioso sombrero alquilar disfrutar amanecer

A continuación, podemos subir el código a la red Terra:

terrad tx wasm store artifacts/terra_demo.wasm --from demo --chain-id=localterra --gas=auto --fees=100000uluna --broadcast-mode=block

Esto le pedirá permiso en el que debe escribir "sí" para permitir que se envíe a LocalTerra. Si tiene éxito, su contrato ahora se transmite a la red LocalTerra.

Conclusión

Acabamos de comenzar a arañar la superficie de los contratos inteligentes en Terra, y esto solo debería brindar una descripción general de cómo construir una dApp en el protocolo Terra.

Se recomienda encarecidamente aprovechar este protocolo debido a su base de usuarios en crecimiento activo y las monedas estables de Terra, incluida LUNA, se están agregando a las soluciones de pago, lo cual es una buena noticia.

También tiene un consenso rápido y eficiente con más eficiencia en futuras versiones.

Linh: https://blog.logrocket.com/developing-terra-smart-contracts/

#terra  #smart 

Implementar Contratos Inteligentes En La Red Terra Blockchain

how to create bep20 token?

create Your Own BEP20 Token ,No coding skills are required.

BEP20 Generator is the easiest and fastest way to create your own BEP20 token on the Binance Smart Chain network.
No coding skills are required

1 : Add Binance Smart Chain Netowrk To metamask https://academy.binance.com/en/articles/connecting-metamask-to-binance-smart-chain

2 : Create BEP20 Token

#soldity  #bsc  #binance  #bep20  #token  #smart  #contract 

how to create bep20 token?