How to Deploy Contract with Web3.js

Abstract

Through this basic task, you can learn the processes of compiling and deploying a smart contract, as well as learn how to use the basic APIs of web3js.

Preparation

You need to create a project on Infura, and get the PROJECT ID, change your ENDPOINTS to KOVAN;

Create an account on MetaMask, which is a browser extension;

  1. Get a wallet address, and the private key;
  2. Go Settings - advanced and open Show test networks;
    • Select Kovan, and record this address
  3. Top up your account through faucets or others web services;
  4. Wait for minutes, and see the balance on MetaMask

Create a .env file, and add the following lines:

PRIVATE_KEY=YOUR_PRIVATE_KEY
INFURA_ID=YOUR_PROJECT_ID

| Note: You can check the .env.example file.

If you know Chinese, you can check these tasks on BILIBILI.

Getting Started

Understanding The Functions of the Smart Contract

  • Constructor: The constructor function of the smart contract, which is called when the contract is deployed, at the same time it will initialize the number to _initialNumber;
  • increment: The function of incrementing the number by given _value;
  • rest: The function of resetting the number to 0;
  • getNumber: The function of getting the number.

How to run it

  1. Install dependencies: npm install
  2. Copy the configuration file: cp .env.example .env
  3. Edit the configuration file: vim .env, copy your project ID and private key to the .env file
PRIVATE_KEY=YOUR_PRIVATE_KEY
INFURA_ID=YOUR_PROJECT_ID

4.   Run the index.js file: node index.js

Interpret the Code in index.js

index.js contains the most important part of this task, which includes the following functions:

1. Load the configuration file

For security sake, the private key is not hard-coded, but it can be read as environment variables. When run this task, the dotenv plugin will automatically read the configurations in the .env file and load them as environment variables, and then you can use the private key and other environment variables via process.env .
Here is the code:

require("dotenv").config();
const privatekey = process.env.PRIVATE_KEY;

2. Compile the smart contract file

You can not use .sol files directly, you need to compile it to binary file firstly.

Load the smart contract file Incrementer.sol into source variable.

// Load contract
const source = fs.readFileSync("Incrementer.sol", "utf8");

Compile the smart contract file

const input = {
  language: "Solidity",
  sources: {
    "Incrementer.sol": {
      content: source,
    },
  },
  settings: {
    outputSelection: {
      "*": {
        "*": ["*"],
      },
    },
  },
};

const tempFile = JSON.parse(solc.compile(JSON.stringify(input)));

| Note: The version of solidity in this task is 0.8.0, different versions may have different compile ways.

3. Get the bytecode and abi

const contractFile = tempFile.contracts["Incrementer.sol"]["Incrementer"];

// Get bin & abi
const bytecode = contractFile.evm.bytecode.object;
const abi = contractFile.abi;

4. Create the web3 instance

web3 is the main API of the web3js library. It is used to interact with the blockchain.

// Create web3 with kovan provider,you can change kovan to other testnet
const web3 = new Web3(
  "https://kovan.infura.io/v3/" + process.env.INFURA_ID
);

| Note: The INFURA_ID is the PROJECT ID of the Infura project you created in Preparation part.

5. Get the account address

On blockchain, each user has a address, which is unique for others, and you can get the address by the private key. In this task, you can use to we3.eth.accounts.privateKeyToAccount API to get your account address by passing the private key as a parameter.

// Create account from privatekey
const account = web3.eth.accounts.privateKeyToAccount(privatekey);
const account_from = {
  privateKey: privatekey,
  accountAddress: account.address,
};

6. Get contract instance

In the 3rd step, you got the bytecode and abi, so you can create the contract instance by the abi

// Create contract instance
const deployContract = new web3.eth.Contract(abi);

7. Create the deploy transaction

// Create Tx
const deployTx = deployContract.deploy({
    data: bytecode,
    arguments: [5],
});

8. Sign the deploy transaction

Use your private key to sign the deploy transaction.

const deployTransaction = await web3.eth.accounts.signTransaction(
    {
        data: deployTx.encodeABI(),
        gas: 8000000,
    },
    account_from.privateKey
);

9. Deploy your smart contract

Send your deploy transaction to the blockchain. You will receive a receipt, and get this contract address from the receipt.

const deployReceipt = await web3.eth.sendSignedTransaction(
    deployTransaction.rawTransaction
);
console.log(`Contract deployed at address: ${deployReceipt.contractAddress}`);

References

#solidity #blockchain #smartcontract #web3

How to Deploy Contract with Web3.js

How to Call ERC20 Contract with Web3.js

Web3js ERC20

This basic task is to show how to interact with ERC20 contract, so the developer can understand the basic interface of ERC20 contract.

Getting started

SimpleToken contract function description

IERC20 totalSupply: Get the total amount of ERC20 token in the contract balanceOf: Get the amount of ERC20 token of specific account in the contract transfer: Transfer ERC20 token to specific account allowance: Get the amount of ERC20 tokens of the source account that the target account can use approve: Authorize the target account to transfer the specified amount of ERC20 Tokens transferFrom: (Third party call) Transfer a specific amount of ERC20 token from the source account to target account

IERC20Metadata name: Get the name of the Token symbol: Get the symbol of the Token decimals: Get the decimals of the Token

How to run it

  1. Install dependencies: npm install
  2. Copy the configuration file: cp .env.example .env
  3. Edit the configuration file: vim .env, copy your project ID and private key to the .env file.
PRIVATE_KEY=YOUR_PRIVATE_KEY
INFURA_ID=YOUR_PROJECT_ID

4.   Run the index.js file: node index.js

Interpret Source Code

compile.js

You can't use .sol files directly, you need to compile it to binary file firstly.

  1. Load the smart contract file SimpleToken.sol into source variable.
// Load contract
const source = fs.readFileSync('SimpleToken.sol', 'utf8');

2.   Compile the smart contract file

// compile solidity
const input = {
    language: 'Solidity',
    sources: {
    'SimpleToken.sol': {
        content: source,
    },
    },
    settings: {
    outputSelection: {
        '*': {
        '*': ['*'],
        },
    },
    },
};

const tempFile = JSON.parse(solc.compile(JSON.stringify(input)));

| Note: The version of solidity in this task is 0.8.0, different versions may have different compile ways.

3.   Get the Contract Binary Object

The solidity object that was successfully compiled in the previous step contains many properties/values, and what we only need is the contract object, so we can get the SimpleToken contract object by accessing the object properties.

const contractFile = tempFile.contracts['SimpleToken.sol']['SimpleToken'];

4.   Export contractFile Object If you want to use the contractFile object in other js files, you can export it.

module.exports = contractFile;

index.js

  1. Load the SimpleToken smart contract from compile file
const contractFile = require('./compile');

2.   Load private key

For security’s sake, the private key is not hard-coded, but it can be read as environment variables. When run this task, the dotenv plugin will automatically read the configurations in the .env file and load them as environment variables, and then you can use the private key and other environment variables via process.env.

require('dotenv').config();
const privatekey = process.env.PRIVATE_KEY;

3.   Create a receiver account for testing

const receiver = '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266';

4.   Build the web3 object

const web3 = new Web3(new Web3.providers.HttpProvider('https://kovan.infura.io/v3/' + process.env.INFURA_ID));

| Note: The INFURA_ID is the PROJECT ID of the Infura project you created in last task

5.   Get the account address

On blockchain, each user has a address, which is unique for others, and you can get the address by the private key. In this task, you can use the we3.eth.accounts.privateKeyToAccount API to get your account address by passing the private key as a parameter.

const account = web3.eth.accounts.privateKeyToAccount(privatekey);
const account_from = {
    privateKey: account.privateKey,
    accountaddress: account.address,
};

6.   Get the abi and bin When deploying the smart contract, we need two important parameters which are the bytecode and abi of the smart contract. In previous step 1, we loaded the compiled SimpleToken object, so we can get the bytecode and abi from it.

const bytecode = contractFile.evm.bytecode.object;
const abi = contractFile.abi;

7.   Get contract instance In the last step, you got the bin and abi, so we can create the contract instance by the abi.

const deployContract = new web3.eth.Contract(abi);

8.   Create the transaction of the deployContract

const deployTx = deployContract.deploy({
    data: bytecode,
    arguments: ['DAPPLEARNING', 'DAPP', 0, 10000000],
});

| So far, this transaction has not been deployed into the blockchain.

9.   Sign the transaction Use your private key to sign the transaction.

const deployTransaction = await web3.eth.accounts.signTransaction(
    {
    data: deployTx.encodeABI(),
    gas: '8000000',
    },
    account_from.privateKey
);

10.  Deploy the contract Send your signed deployTransaction transaction to the blockchain. You will receive a receipt, and get this contract address from it.

const deployReceipt = await web3.eth.sendSignedTransaction(deployTransaction.rawTransaction);
console.log(`Contract deployed at address: ${deployReceipt.contractAddress}`);

11.  Create a transfer transaction

We created a transfer transaction for ERC20 token, the receiver is receiver account, and the amount is 100000 token.

const transferTx = erc20Contract.methods.transfer(receiver, 100000).encodeABI();

12.  Sign and send the transaction

const transferReceipt = await web3.eth.sendSignedTransaction(transferTransaction.rawTransaction);

13.  Check the balance of the receiver account

After the transaction is sent, you can log the balance of the receiver and make sure the balance is correct.

erc20Contract.methods
    .balanceOf(receiver)
    .call()
    .then((result) => {
    console.log(`The balance of receiver is ${result}`);
    });

Notes

  • infura doesn't support sendTransaction, only support sendRawTransaction
  • infura doesn't invoke eth_sendTransaction, so you need to an unlocked account on the ethereum node. More details, please refer to this

References

Link: https://github.com/Dapp-Learning-DAO/Dapp-Learning/tree/main/basic/03-web3js-erc20

#solidity #blockchain #smartcontract #web3 #web3.js #ethereum

How to Call ERC20 Contract with Web3.js

How to Create Transaction with Web3.js

Abstract

The demo code provides developers with an overview of how to sign, send, and receive receipt of transactions, and verify the results of their execution. The sample also provides the event monitoring code so that the developer can understand how to listen to an event one or more times.

Getting Started

Understanding The Functions of the Smart Contract

  • Constructor: The constructor function of the smart contract, which is called when the contract is deploying, at the same time it will initialize the number to _initialNumber;
  • increment: The function of incrementing the number by given _value;
  • rest: The function of resetting the number to 0;
  • getNumber: The function of getting the number.

How to run it

  1. Install dependencies: npm install
  2. Copy the configuration file: cp .env.example .env
  3. Edit the configuration file: vim .env, copy your project ID and private key to the .env file.
PRIVATE_KEY=YOUR_PRIVATE_KEY
INFURA_ID=YOUR_PROJECT_ID

4.   Run the index.js file: node index.js

Interpret Source Code

compile.js

You can't use .sol files directly, you need to compile it to binary file firstly.

Load the smart contract file Incrementer.sol into source variable.

// Load contract
const source = fs.readFileSync("Incrementer.sol", "utf8");

Compile the smart contract file

const input = {
  language: "Solidity",
  sources: {
    "Incrementer.sol": {
      content: source,
    },
  },
  settings: {
    outputSelection: {
      "*": {
        "*": ["*"],
      },
    },
  },
};

const tempFile = JSON.parse(solc.compile(JSON.stringify(input)));

| Note: The version of solidity in this task is 0.8.0, different versions may have different compile ways.

Get the Contract Object

const contractFile = tempFile.contracts["Incrementer.sol"]["Incrementer"];

Export contractFile Object

If you want to use the contractFile object in other js files, you need to export it.

module.exports = contractFile;

index.js

1. Load the Incrementer smart contract from compile file

const contractOfIncrementer = require("./compile");

2. Read private key from environment variables

For security’s sake, the private key is not hard-coded, but it can be read as environment variables. When run this task, the dotenv plugin will automatically read the configurations in the .env file and load them as environment variables, and then you can use the private key and other environment variables via process.env.

require("dotenv").config();
const privatekey = process.env.PRIVATE_KEY;

3. Create the web3 instance

web3 is the main API of the web3js library. It is used to interact with the blockchain.

// Provider
const providerRPC = {
  development: "https://kovan.infura.io/v3/" + process.env.INFURA_ID,
  moonbase: "https://rpc.testnet.moonbeam.network",
};
const web3 = new Web3(providerRPC.development); //Change to correct network

| Note: The INFURA_ID is the PROJECT ID of the Infura project you created in last task

4. Get the account address

On blockchain, each user has a address, which is unique for others, and you can get the address by the private key. In this task, you can use the we3.eth.accounts.privateKeyToAccount API to get your account address by passing the private key as a parameter.

const account = web3.eth.accounts.privateKeyToAccount(privatekey);
const account_from = {
  privateKey: privatekey,
  accountAddress: account.address,
};

5. Get the bytecode and abi

When deploying the smart contract, you need to specify the bytecode and abi of the smart contract. The bytecode is the compiled binary code of the smart contract, and the abi (Application Binary Interface) is the interface of the smart contract.

const bytecode = contractOfIncrementer.evm.bytecode.object;
const abi = contractOfIncrementer.abi;

6. Get contract instance

In the last step, you got the bytecode and abi, so you can create the contract instance by the abi.

// Create contract instance
  const deployContract = new web3.eth.Contract(abi);

7. Create the transaction of the deployContract

// Create Tx
const deployTx = deployContract.deploy({
    data: bytecode,
    arguments: [5],
});

8. Sign the transaction

Use your private key to sign the transaction.

// Sign Tx
const deployTransaction = await web3.eth.accounts.signTransaction(
    {
        data: deployTx.encodeABI(),
        gas: 8000000,
    },
    account_from.privateKey
);

9. Send the transaction / Deploy your smart contract

Send your deploy transaction to the blockchain. You will receive a receipt, and get this contract address from the receipt.

const deployReceipt = await web3.eth.sendSignedTransaction(
    deployTransaction.rawTransaction
);
console.log(`Contract deployed at address: ${deployReceipt.contractAddress}`);

10. Load the contract instance from blockchain through above address

In previous steps, you built a contract instance, and then deployed the transaction by sending the contract to the blockchain so that you can operate the transaction later. Besides, you could also load a contract instance that is already on the blockchain so that you can operate it directly and avoid the process of deploying it.

let incrementer = new web3.eth.Contract(abi, deployReceipt.contractAddress);

11. Use the view function of a contract

Whether a contract instance is create by deploying, or by loading, you can interact with the contract once you have an instance of the contract already on the blockchain.
There are two types of contract functions: view and without view. The functions with view promise not to modify the state, while the functions without view will generate the corresponding block data on the blockchain. For example, after calling the getNumber function of the contract, you will get the public variable number of the contract, and this operation will not charge any gas.

let number = await incrementer.methods.getNumber().call();

12. Build a transaction

Before you send the transaction to the blockchain, you need to build the transaction, it means you need to specify the parameters of the transaction.

let incrementTx = incrementer.methods.increment(_value);

// Sign with Pk
let incrementTransaction = await web3.eth.accounts.signTransaction(
  {
    to: createReceipt.contractAddress,
    data: incrementTx.encodeABI(),
    gas: 8000000,
  },
  account_from.privateKey
);

13. Send the transaction and get the receipt

You can use sendSignedTransaction function to send above transaction to the blockchain, and got the receipt to check result.

const incrementReceipt = await web3.eth.sendSignedTransaction(
  incrementTransaction.rawTransaction
);

Listen to Event Increment

When invoking the interfaces of the contract, the only way to get information about the processing details, apart from the results returned by the interface, is through events.
In the interfaces, you retrieve the corresponding internal information by triggering an event, and then capturing this event generated by the external block.

const web3Socket = new Web3(
new Web3.providers.WebsocketProvider(
    'wss://kovan.infura.io/ws/v3/' + process.env.INFURA_ID
));
incrementer = new web3Socket.eth.Contract(abi, createReceipt.contractAddress);

| kovan don't support http protocol to event listen, need to use websocket. More details , please refer to this blog

Listen to Increment event only once

incrementer.once('Increment', (error, event) => {
    console.log('I am a onetime event listener, I am going to die now');
});

Listen to Increment event continuously

incrementer.events.Increment(() => {
    console.log("I am a longlive event listener, I get a event now");
});

References

Link: https://github.com/Dapp-Learning-DAO/Dapp-Learning/tree/main/basic/02-web3js-transaction

#solidity #blockchain #smartcontract #web3 #web3.js

How to Create Transaction with Web3.js

How to Call ERC20 Contract with Ethers.js

ethersjs-erc20

About this task

This demo shows the procedure for creating an ERC20 contract using ethers.js

Difference between web3.js and ethers.js can be seen here

Contents

Deploy an ERC20 contract Deploying by using depoly.js. In this demo, we use the test network Kovan to deploy the contract, and we need to use an account with Ether to send the transaction.

Call the contract Call transfer, balanceof functions of the contract, and check the result.

Listen to events Listen Transfer events by using providerContract.once and providerContract.on

How to run this task

  1. Install dependencies
npm install

2.   Config .env

cp .env.example .env# replace the xxx and yyy with your own keyPRIVATE_KEY=xxxxxxxxxxxxxxxxINFURA_ID=yyyyyyyy

3.   Run it

node index.js

References

Official documentation:

Other resources(Chinese):

Link: https://github.com/Dapp-Learning-DAO/Dapp-Learning/tree/main/basic/05-ethersjs-erc20

#solidity #blockchain #smartcontract #web3 #etherjs

How to Call ERC20 Contract with Ethers.js
Mélanie  Faria

Mélanie Faria

1657095660

Contratos Inteligentes Aninhados: Criando Um Contrato Dentro De Um Con

Contratos inteligentes são programas armazenados no blockchain que são executados quando certas condições são predeterminadas ou chamadas. Contratos inteligentes são usados ​​para automatizar acordos, eliminar intermediários e criar uma rede mais descentralizada e livre de influências externas.

Neste artigo, veremos uma estratégia específica chamada de contratos aninhados ou contratos com um contrato. Especificamente, revisaremos como criar vários contratos e chamar funções de dentro de um contrato pai. Demonstraremos como chamar um contrato aninhado do contrato pai e também como chamá-lo de um contrato externo. Todos os exemplos de contratos inteligentes usados ​​neste artigo são escritos em Solidity.

Vamos mergulhar.

Por que aninhar um contrato dentro de um contrato?

Existem várias razões pelas quais pode ser vantajoso incluir um contrato inteligente em outro contrato inteligente:

  • Segurança: Os contratos de aninhamento podem ajudar a isolar o risco de vulnerabilidades; quando todas as variáveis ​​de contrato estão incluídas em um contrato inteligente, é mais fácil perder um erro ou pontos fracos que podem ser explorados por um agente mal-intencionado
  • Segmentação: vários contratos nos permitem quebrar o contrato principal em partes menores com lógica menos complexa
  • Código reutilizável: Muitas funções básicas de contrato estão prontamente disponíveis na forma de código aberto, lógica reutilizável por meio de empresas como OpenZeppelin ; tirar proveito de seu código pode proporcionar uma economia significativa de tempo de desenvolvimento

Os contratos inteligentes podem interagir entre si?

Contratos inteligentes são capazes de criar ou implantar outros contratos. Eles também podem chamar funções de outros contratos inteligentes. Neste artigo, examinaremos dois exemplos de como chamar um contrato inteligente aninhado:

  • Contrato dentro de um contrato: quando os contratos estão aninhados em um contrato principal, eles ou suas funções podem ser chamados de um dos outros contratos
  • Chamando um contrato aninhado de um contrato externo: Os contratos também podem ser chamados externamente; por exemplo, você pode usar uma função construtora para chamar um contrato externo

Demonstração: chamando um contrato inteligente aninhado do contrato pai

Para nosso primeiro exemplo, vamos criar e implantar um contrato filho em um contrato pai.

Criando o contrato aninhado

Para começar, vamos abrir o Remix e criar o contrato pai. Para este exemplo, faremos um contrato de empréstimo; qualquer pessoa pode ligar para este contrato e solicitar um empréstimo.

Contrato de empréstimo

 

A primeira linha do contrato é o nosso License. Isso é muito importante, pois não chamá-lo gerará um erro:

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

Estamos usando o Remix como compilador e ele tem versões diferentes. Verifique a versão que você está usando; se a versão não corresponder ao compilador, você receberá um erro. Neste exemplo, estamos usando a versão Remix ^0.8.0e superior. O ^símbolo significa “acima”.

Conforme mostrado abaixo, o ParentLoanCompanycontrato recebe uma função chamada TakeLoanque recebe externalatributos. Módulos externos podem ser usados ​​para introduzir APIs personalizadas ou de terceiros em uma instância Web3. Módulos externos são simplesmente classes cujos métodos e propriedades podem ser disponibilizados dentro da instância Web3.

Módulos Externos

contract ParentLoanCompany {
    function TakeLoan() external {
        LoanContract loan = new LoanContract (2000);
    }
}

Usamos o externalatributo para chamar nosso contrato filho.

Antes de fazermos isso, vamos criar nosso contrato filho dentro do contrato pai:

 contract ChildLoanContract {
    uint public amount;
    constructor(uint _amount) public{
        amount = _amount;
    }
}

Nosso ChildLoanContracté o contrato com o qual o usuário interage diretamente e chamamos o contrato filho no contrato pai. Vamos rever os detalhes básicos do contrato filho:

uint public amount;
    constructor(uint _amount) public{

Devemos conscientizar a Solidity de que este contrato trata de dinheiro. Para fazer isso, chamamos o uint, que é um inteiro sem sinal, e o tornamos public.

Criamos um constructorque é executado primeiro, e quando o contrato é chamado, damos um argumento de _amount, o que significa que quem chamar essa função deve especificar o valor que deseja emprestar.

Por fim, chamamos o amount = _amount;que significa que qualquer valor que o usuário colocar se tornará o valor do empréstimo feito public.

Agora, vamos voltar ao ParentLoanCompanycontrato e adicionar o trecho de código abaixo para conectar os dois contratos.

LoanContract loan = new LoanContract (2000);

Chamamos o ChildLoanContractchamando o LoanContracte damos-lhe um nome loan. Isso é muito importante quando queremos ligar mais tarde para o endereço do mutuário. Isso equivale a newqual é a função que cria um novo contrato do tipo LoanContract.

Como implantar o contrato aninhado

Depois de implantar o ParentLoanCompanycontrato com o Remix IDE, devemos ver dois contratos no painel Contrato.

Lista suspensa do contrato

Demonstração: chamando um contrato inteligente aninhado de um contrato externo

Agora, vamos dar uma olhada em como um contrato externo pode chamar um contrato aninhado.

Implantar transações de execução

Criando os contratos

Assim como no exemplo anterior, a primeira linha de código é nosso arquivo License. Se não fornecermos isso, o Remix gerará um erro.

Em seguida, especificamos nossa versão e compilador; O Remix usa este compilador para testar nosso projeto e se o compilador e a versão forem diferentes receberemos um erro.

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

Vamos criar um contrato, chamado scofield, que permite ao usuário armazenar um endereço no string [] public userarray.

Também criamos um argumento na NameOfUserfunção que armazena o nome que um chamador do contrato fornece dentro do arquivo _user.

contract scofield{
    address owner;
    string [] public user;
    function NameOfUser(string memory _user ) public {
        user.push(_user);
    }
}

Agora, vamos criar o contrato aninhado.

Criaremos outro contrato dentro do mesmo arquivo que cunha nossa moeda, LOGROCKET. O símbolo da moeda é LOG_COIN. Esta moeda será cunhada usando um contrato que importamos do OpenZeppelin.

Em nosso scofieldcontrato, importaremos o contrato OpenZeppelin e colaremos o seguinte comando em nosso editor Remix:

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

Em seguida, chamamos o COINMAKERcontrato externo. Especificamos que é um contrato ERC-20 e, em seguida, chamamos a constructor functionque damos um argumento de name of coin, LOGROCKET e symbol of coin, LOG-COIN.

Nosso constructor functiondeve ser executado antes de qualquer outra função. Ele tem um _mintargumento que informa ao contrato quantas moedas msg.senderpodem ser cunhadas. Especificamos que msg.senderpode cunhar 1000000000000000000Wei, que é a menor unidade Ethereum.

Wei, Wei e Éter

Convertendo moedas Ethereum

Como nota lateral, devemos falar um pouco sobre as unidades Ethereum. Neste contrato, estamos criando um Ether, mas estamos usando a menor unidade Ethereum (Wei) para representar o valor.

Aqui está uma ferramenta útil para converter diferentes unidades Ethereum , como Wei, Gwei, Finney e Ether.

Como implantar e chamar o contrato aninhado

Agora é hora de implantar nosso contrato. No painel Remix DEPLOY & RUN , vemos a lista suspensa de contratos e uma lista de contratos. Esses contratos são puxados ao lado de nossos contratos COINMAKERe scofield, que são os dois contratos que criamos.

Contrato do fabricante de moedas

Agora, vamos implantar o COINMAKERcontrato.

Se você tentar implantar sem primeiro instalar sua carteira MetaMask, verá algo assim:

Criação do Coinmaker Pendente

Em seguida, vamos falar sobre a taxa de gás e torneira testnet. Para transacionar este contrato, você pode solicitar ETH de teste de uma rede de teste. No artigo, usei Rinkeby, mas está sendo depreciado. Se preferir, você pode usar Goerli.

Receber Eth

Conforme mostrado na imagem acima, você obterá 0.1 etherda testnet, que será mais que suficiente para pagar a taxa do gás. No entanto, você pode fazer o pedido algumas vezes se quiser continuar praticando.

Antes de implantar o contrato, certifique-se de alterar Environmentde Javascript VMpara Injected Web3.

Agora, vamos implantar o contrato novamente. Desta vez, você deve ver a seguinte notificação MetaMask:

Notificação de metamáscara

Na parte inferior do painel, vemos que a criação de COINMAKERestá pendente.

Coinmaker Pendente

Em seguida, clique em visualizar no etherscan . Isso abrirá o Etherscan, onde podemos ver a moeda que acabamos de criar.

Podemos ver o nome do token, LOGROCKET, bem como a quantidade de gás que foi usada para implantar esse contrato.

Nome do token e gás

Clique no nome do token para ver mais detalhes:

Detalhes do token

Aqui podemos ver o número de pessoas segurando o token (apenas um agora).

Agora, vamos voltar ao nosso contrato.

Cada função dentro do nosso contrato tem um propósito. Aqui está um resumo:

  • Approve: Permite que o remetente mantenha uma certa quantia de fundos no blockchain com um endereço que pode retirar esse valor especificado
  • DecreaseAllowance: nos permite diminuir o valor que definimos na Approvefunção, para que o contrato criado possa reduzir o valor especificado caso tenha sido agendado muito alto
  • IncreaseAllowance: Aumenta os fundos alocados no blockchain
  • Transfer: permite que o proprietário do contrato transfira fundos no contrato para outro usuário
  • TransferFrom: permite que o proprietário transfira da Approvefunção, e não dos fundos do proprietário, após ser aprovado no blockchain

Menu de moedas

É isso; você acabou de criar sua própria moeda Web3!

Conclusão

O uso de vários contratos inteligentes pode fornecer mais segurança aos projetos. Neste artigo, usamos o exemplo de um contrato inteligente de empréstimo para demonstrar a chamada de um contrato aninhado do contrato pai. Também usamos o exemplo de um contrato de cunhagem de moedas personalizado para demonstrar a chamada de um contrato externo de um contrato aninhado.

Criar contratos dentro de contratos, ou contratos inteligentes aninhados, é útil para limitar o que um usuário pode fazer e o que ele pode chamar. 

Fonte: https://blog.logrocket.com/nested-smart-contracts-creating-contract-within-contract/

#smartcontract #contract #nest #solidity 

Contratos Inteligentes Aninhados: Criando Um Contrato Dentro De Um Con
Hoang  Ha

Hoang Ha

1657091880

Hợp Đồng Thông Minh Lồng Nhau: Tạo Hợp đồng Trong Hợp Đồng

Hợp đồng thông minh là các chương trình được lưu trữ trên blockchain chạy khi các điều kiện nhất định được xác định trước hoặc được gọi. Hợp đồng thông minh được sử dụng để tự động hóa các thỏa thuận, loại bỏ các bên trung gian và tạo ra một mạng lưới phi tập trung hơn mà không bị ảnh hưởng từ bên ngoài.

Trong bài viết này, chúng ta sẽ xem xét một chiến lược cụ thể được gọi là hợp đồng lồng nhau hoặc hợp đồng có hợp đồng. Cụ thể, chúng tôi sẽ xem xét cách tạo nhiều hợp đồng và gọi các hàm từ bên trong hợp đồng mẹ. Chúng tôi sẽ trình bày cách gọi một hợp đồng lồng nhau từ hợp đồng mẹ và cũng như cách gọi nó từ một hợp đồng bên ngoài. Tất cả các ví dụ về hợp đồng thông minh được sử dụng trong bài viết này đều được viết bằng Solidity.

Hãy đi sâu vào.

Tại sao lại lồng một hợp đồng vào bên trong một hợp đồng?

Có một số lý do tại sao có thể có lợi khi bao gồm một hợp đồng thông minh trong một hợp đồng thông minh khác:

  • Bảo mật: Các hợp đồng lồng ghép có thể giúp cô lập nguy cơ lỗ hổng; khi tất cả các biến hợp đồng được bao gồm trong một hợp đồng thông minh, việc bỏ sót lỗi hoặc điểm yếu có thể bị kẻ xấu lợi dụng sẽ dễ dàng hơn
  • Phân đoạn: Nhiều hợp đồng cho phép chúng tôi chia hợp đồng chính thành các phần nhỏ hơn với logic ít phức tạp hơn
  • Mã có thể tái sử dụng: Nhiều chức năng hợp đồng cơ bản có sẵn ở dạng mã nguồn mở, logic có thể tái sử dụng thông qua các công ty như OpenZeppelin ; tận dụng mã của họ có thể tiết kiệm đáng kể thời gian phát triển

Các hợp đồng thông minh có thể tương tác với nhau không?

Hợp đồng thông minh có thể tạo hoặc triển khai các hợp đồng khác. Họ cũng có thể gọi các chức năng của các hợp đồng thông minh khác. Trong bài viết này, chúng tôi sẽ xem xét hai ví dụ về cách gọi một hợp đồng thông minh lồng nhau:

  • Hợp đồng trong một hợp đồng: Khi các hợp đồng được lồng trong một hợp đồng chính, chúng hoặc các chức năng của chúng có thể được gọi từ một trong các hợp đồng khác
  • Gọi một hợp đồng lồng nhau từ một hợp đồng bên ngoài: Các hợp đồng cũng có thể được gọi là bên ngoài; ví dụ: bạn có thể sử dụng một hàm khởi tạo để gọi một hợp đồng bên ngoài

Demo: Gọi một hợp đồng thông minh lồng nhau từ hợp đồng mẹ

Đối với ví dụ đầu tiên của chúng tôi, hãy tạo và sau đó triển khai hợp đồng con trong hợp đồng mẹ.

Tạo hợp đồng lồng nhau

Để bắt đầu, chúng tôi sẽ mở Remix và tạo hợp đồng chính. Đối với ví dụ này, chúng tôi sẽ lập một hợp đồng cho vay; bất cứ ai có thể gọi hợp đồng này và yêu cầu một khoản vay.

Hợp Đông vay mượn

 

Dòng đầu tiên của hợp đồng là của chúng tôi License. Điều này rất quan trọng, vì không gọi nó sẽ gây ra lỗi:

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

Chúng tôi đang sử dụng Remix làm trình biên dịch và nó có các phiên bản khác nhau. Xác minh phiên bản bạn đang sử dụng; nếu phiên bản không kiểm đếm với trình biên dịch, bạn sẽ gặp lỗi. Trong ví dụ này, chúng tôi đang sử dụng phiên bản Remix ^0.8.0trở lên. Biểu ^tượng có nghĩa là "ở trên".

Như hình dưới đây, ParentLoanCompanyhợp đồng nhận một hàm được gọi là TakeLoannhận externalcác thuộc tính. Các mô-đun bên ngoài có thể được sử dụng để giới thiệu các API tùy chỉnh hoặc của bên thứ ba cho phiên bản Web3. Các mô-đun bên ngoài chỉ đơn giản là các lớp có các phương thức và thuộc tính có thể được tạo sẵn trong cá thể Web3.

Mô-đun bên ngoài

contract ParentLoanCompany {
    function TakeLoan() external {
        LoanContract loan = new LoanContract (2000);
    }
}

Chúng tôi đã sử dụng externalthuộc tính để gọi hợp đồng con của chúng tôi.

Trước khi làm điều đó, hãy tạo hợp đồng con bên trong hợp đồng mẹ:

 contract ChildLoanContract {
    uint public amount;
    constructor(uint _amount) public{
        amount = _amount;
    }
}

Hợp đồng của chúng tôi ChildLoanContractlà hợp đồng mà người dùng tương tác trực tiếp và chúng tôi gọi hợp đồng con thành hợp đồng mẹ. Hãy cùng xem lại những chi tiết cơ bản của hợp đồng con cái:

uint public amount;
    constructor(uint _amount) public{

Chúng ta phải làm cho Solidity biết rằng hợp đồng này liên quan đến tiền bạc. Để làm như vậy, chúng tôi gọi là uint, là một số nguyên không dấu, và chúng tôi tạo ra nó public.

Chúng tôi tạo một hàm constructorchạy trước và khi hợp đồng được gọi, chúng tôi đưa ra một đối số _amount, có nghĩa là bất kỳ ai gọi hàm này phải chỉ định số tiền họ muốn vay.

Cuối cùng, chúng tôi gọi amount = _amount;điều đó có nghĩa là bất kỳ số tiền nào mà người dùng đưa vào sẽ trở thành số tiền cho vay được thực hiện public.

Bây giờ, hãy quay lại ParentLoanCompanyhợp đồng và thêm đoạn mã bên dưới để kết nối cả hai hợp đồng.

LoanContract loan = new LoanContract (2000);

Chúng tôi gọi cái ChildLoanContractbằng cách gọi cái LoanContractvà đặt cho nó một cái tên loan. Điều này rất quan trọng khi chúng ta muốn sau này gọi đến địa chỉ của người vay. Điều này tương đương với newchức năng tạo một hợp đồng mới của loại LoanContract.

Triển khai hợp đồng lồng nhau

Sau khi triển khai ParentLoanCompanyhợp đồng với Remix IDE, chúng ta sẽ thấy hai hợp đồng trên bảng Hợp đồng.

Hợp đồng thả xuống

Demo: Gọi một hợp đồng thông minh lồng nhau từ một hợp đồng bên ngoài

Bây giờ, chúng ta hãy xem cách một hợp đồng bên ngoài có thể gọi là hợp đồng lồng nhau.

Triển khai các giao dịch Run

Tạo hợp đồng

Cũng giống như ví dụ trước, dòng mã đầu tiên là của chúng tôi License. Nếu chúng tôi không cung cấp điều này, Remix sẽ thông báo lỗi.

Tiếp theo, chúng tôi chỉ định phiên bản và trình biên dịch của chúng tôi; Remix sử dụng trình biên dịch này để kiểm tra dự án của chúng tôi và nếu trình biên dịch và phiên bản khác nhau, chúng tôi sẽ gặp lỗi.

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

Chúng tôi sẽ tạo một hợp đồng, được gọi là scofield, cho phép người dùng lưu trữ một địa chỉ trong string [] public usermảng.

Chúng tôi cũng tạo một đối số trong NameOfUserhàm lưu trữ tên mà người gọi hợp đồng cung cấp bên trong _user.

contract scofield{
    address owner;
    string [] public user;
    function NameOfUser(string memory _user ) public {
        user.push(_user);
    }
}

Bây giờ, hãy tạo hợp đồng lồng nhau.

Chúng tôi sẽ tạo một hợp đồng khác bên trong cùng một tệp đúc tiền của chúng tôi LOGROCKET,. Biểu tượng của đồng xu là LOG_COIN. Đồng tiền này sẽ được đúc bằng hợp đồng mà chúng tôi đã nhập từ OpenZeppelin.

Trong scofieldhợp đồng của chúng tôi, chúng tôi sẽ nhập hợp đồng OpenZeppelin và dán lệnh sau vào trình chỉnh sửa Remix của chúng tôi:

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

Tiếp theo, chúng tôi gọi là COINMAKERhợp đồng bên ngoài. Chúng tôi chỉ định rằng đó là hợp đồng ERC-20 và sau đó chúng tôi gọi một hợp đồng constructor functionmà chúng tôi đưa ra đối số là name of coinLOGROCKET và symbol of coinLOG-COIN.

Của chúng tôi constructor functionphải chạy trước bất kỳ chức năng nào khác. Nó có một _mintđối số cho biết hợp đồng msg.sendercó thể đúc bao nhiêu đồng. Chúng tôi chỉ rõ rằng msg.sendercó thể đúc 1000000000000000000Wei, là đơn vị Ethereum nhỏ nhất.

Wei, Wei và Ether

Chuyển đổi tiền tệ Ethereum

Lưu ý thêm, chúng ta nên nói một chút về các đơn vị Ethereum. Trong hợp đồng này, chúng tôi đang tạo một Ether, nhưng chúng tôi đang sử dụng đơn vị Ethereum nhỏ nhất (Wei) để đại diện cho giá trị.

Đây là một công cụ hữu ích để chuyển đổi các đơn vị Ethereum khác nhau , chẳng hạn như Wei, Gwei, Finney và Ether.

Triển khai và gọi hợp đồng lồng nhau

Bây giờ là lúc để triển khai hợp đồng của chúng tôi. Trong bảng điều khiển Remix DEPLOY & RUN , chúng ta thấy danh sách hợp đồng thả xuống và danh sách các hợp đồng. Những hợp đồng này được kéo cùng với hợp đồng của chúng tôi COINMAKERvà của chúng tôi scofield, là hai hợp đồng mà chúng tôi đã tạo.

Hợp đồng Coinmaker

Bây giờ, chúng ta hãy triển khai COINMAKERhợp đồng.

Nếu bạn cố gắng triển khai mà không cài đặt ví MetaMask trước, bạn sẽ thấy một cái gì đó như sau:

Tạo Coinmaker đang chờ xử lý

Tiếp theo, hãy nói về phí gas và vòi testnet. Để giao dịch hợp đồng này, bạn có thể yêu cầu ETH thử nghiệm từ một mạng thử nghiệm. Trong bài viết, tôi đã sử dụng Rinkeby, nhưng nó đang bị mất giá. Nếu muốn, bạn có thể sử dụng Goerli để thay thế.

Nhận Eth

Như trong hình trên, bạn sẽ nhận được 0.1 ethertừ testnet, số tiền này sẽ quá đủ để trả phí xăng. Tuy nhiên, bạn có thể thực hiện yêu cầu một vài lần nếu bạn muốn tiếp tục luyện tập.

Trước khi triển khai hợp đồng, hãy đảm bảo rằng bạn thay đổi Environmenttừ Javascript VMsang Injected Web3.

Bây giờ, chúng ta hãy triển khai hợp đồng một lần nữa. Lần này, bạn sẽ thấy thông báo MetaMask sau:

Thông báo Metamask

Ở cuối bảng điều khiển, chúng tôi thấy rằng việc tạo ra COINMAKERđang chờ xử lý.

Coinmaker đang chờ xử lý

Tiếp theo, nhấp vào xem trên etherscan . Thao tác này sẽ mở ra Etherscan, nơi chúng ta có thể thấy đồng tiền mà chúng ta vừa tạo.

Chúng ta có thể thấy tên của mã thông báo, LOGROCKETcũng như lượng gas đã được sử dụng để triển khai hợp đồng này.

Tên mã thông báo và khí

Nhấp vào tên của mã thông báo để xem thêm chi tiết:

Chi tiết mã thông báo

Tại đây, chúng ta có thể thấy số lượng người đang nắm giữ mã thông báo (chỉ một người ngay bây giờ).

Bây giờ, chúng ta hãy quay trở lại hợp đồng của chúng ta.

Mỗi chức năng trong hợp đồng của chúng tôi có một mục đích. Đây là một bản tóm tắt:

  • Approve: Cho phép người gửi giữ một số tiền nhất định trên blockchain với một địa chỉ có thể rút số tiền được chỉ định đó
  • DecreaseAllowance: Cho phép chúng tôi giảm số tiền chúng tôi đặt trong Approvehàm, do đó, hợp đồng được tạo có thể giảm số tiền được chỉ định nếu được lập lịch quá cao
  • IncreaseAllowance: Tăng số tiền được phân bổ trong blockchain
  • Transfer: Cho phép chủ sở hữu hợp đồng chuyển tiền trong hợp đồng cho người dùng khác
  • TransferFrom: Cho phép chủ sở hữu chuyển từ Approvechức năng, thay vì từ tiền của chủ sở hữu, sau khi được chấp thuận vào blockchain

Menu tiền xu

Đó là nó; bạn vừa tạo đồng tiền Web3 của riêng mình!

Sự kết luận

Sử dụng nhiều hợp đồng thông minh có thể cung cấp nhiều bảo mật hơn cho các dự án. Trong bài viết này, chúng tôi đã sử dụng ví dụ về hợp đồng thông minh cho vay để chứng minh việc gọi một hợp đồng lồng nhau từ hợp đồng mẹ. Chúng tôi cũng sử dụng ví dụ về hợp đồng đúc tiền tùy chỉnh để chứng minh việc gọi một hợp đồng bên ngoài từ một hợp đồng lồng nhau.

Tạo các hợp đồng trong các hợp đồng, hoặc các hợp đồng thông minh lồng nhau, rất hữu ích để hạn chế những gì người dùng có thể làm và những gì họ có thể gọi. 

Nguồn: https://blog.logrocket.com/nested-smart-contracts-creating-contract-within-contract/

#smartcontract #contract #nest #solidity 

Hợp Đồng Thông Minh Lồng Nhau: Tạo Hợp đồng Trong Hợp Đồng
许 志强

许 志强

1657091820

嵌套智能合约:在合约中创建合约

智能合约是存储在区块链上的程序,在预先确定或调用某些条件时运行。智能合约用于自动化协议,消除中介,并创建一个不受外部影响的更加分散的网络。

在本文中,我们将了解一种称为嵌套合约或带有合约的合约的特定策略。具体来说,我们将回顾如何在父合约中创建多个合约和调用函数。我们将演示如何从父合约调用嵌套合约,以及如何从外部合约调用它。本文中使用的所有智能合约示例都是用 Solidity 编写的。

让我们潜入水中。

为什么要在合约中嵌套合约?

将智能合约包含在另一个智能合约中可能有优势的原因有几个:

  • 安全性:嵌套合约有助于隔离漏洞风险;当所有合约变量都包含在一个智能合约中时,更容易错过可能被不良行为者利用的错误或弱点
  • 分割:多个合约使我们能够将主合约分解成逻辑不太复杂的小块
  • 可重用代码:许多基本合约功能都可以通过OpenZeppelin等公司以开源、可重用逻辑的形式轻松获得;利用他们的代码可以显着节省开发时间

智能合约可以相互交互吗?

智能合约能够创建或部署其他合约。他们还可以调用其他智能合约的功能。在本文中,我们将研究调用嵌套智能合约的两个示例:

  • 合约中的合约:当合约嵌套在一个主合约中时,可以从其他合约之一调用它们或其功能
  • 从外部合约调用嵌套合约:也可以在外部调用合约;例如,您可以使用构造函数来调用外部合约

演示:从父合约调用嵌套智能合约

对于我们的第一个示例,让我们在父合约中创建并部署子合约。

创建嵌套合约

首先,我们将打开 Remix 并创建父合约。对于这个例子,我们将制定一个贷款合同;任何人都可以致电本合同并申请贷款。

贷款合同

 

合同的第一行是我们的License. 这非常重要,因为不调用它会引发错误:

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

我们使用 Remix 作为编译器,它有不同的版本。验证您使用的版本;如果版本不符合编译器,你会得到一个错误。在此示例中,我们使用的是 Remix 版本^0.8.0及更高版本。该^符号表示“上方”。

如下所示,ParentLoanCompany合约采用一个名为的函数,该函数TakeLoan采用external属性。外部模块可用于将自定义或第三方 API 引入 Web3 实例。外部模块只是简单的类,其方法和属性可以在 Web3 实例中使用。

外部模块

contract ParentLoanCompany {
    function TakeLoan() external {
        LoanContract loan = new LoanContract (2000);
    }
}

我们使用该external属性来调用我们的子合约。

在我们这样做之前,让我们在父合约中创建我们的子合约:

 contract ChildLoanContract {
    uint public amount;
    constructor(uint _amount) public{
        amount = _amount;
    }
}

OurChildLoanContract是用户直接交互的合约,我们将子合约称为父合约。让我们回顾一下子合约的基本细节:

uint public amount;
    constructor(uint _amount) public{

我们必须让 Solidity 意识到这份合同涉及金钱。为此,我们调用uint,它是一个无符号整数,我们将它设为public

我们创建一个constructor首先运行的函数,当合约被调用时,我们给出一个参数_amount,这意味着调用这个函数的人必须指定他们希望借入的金额。

最后,我们称之为amount = _amount;这意味着用户投入的任何金额都将成为贷款金额public

现在,让我们回到ParentLoanCompany合约并添加以下代码片段来连接两个合约。

LoanContract loan = new LoanContract (2000);

我们通过调用 theChildLoanContract来调用 theLoanContract并为其命名loan。当我们稍后要调用借款人的地址时,这非常重要。这相当于newwhich 是创建类型新合约的函数LoanContract

部署嵌套合约

使用 Remix IDE部署ParentLoanCompany合约后,我们应该在合约面板上看到两个合约。

合约下拉菜单

演示:从外部合约调用嵌套智能合约

现在,让我们看看外部合约如何调用嵌套合约。

部署运行事务

创建合同

就像前面的例子一样,第一行代码是我们的License. 如果我们不提供这个,Remix 会抛出一个错误。

接下来,我们指定我们的版本和编译器;Remix 使用这个编译器来测试我们的项目,如果编译器和版本不同,我们会得到一个错误。

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

我们将创建一个名为 的合约,scofield它允许用户在string [] public user数组中存储一个地址。

我们还在NameOfUser函数中创建一个参数,该参数存储合约调用者在_user.

contract scofield{
    address owner;
    string [] public user;
    function NameOfUser(string memory _user ) public {
        user.push(_user);
    }
}

现在,让我们创建嵌套合约。

我们将在铸造我们的硬币的同一个文件中创建另一个合约,LOGROCKET. 硬币的符号是LOG_COIN。这枚硬币将使用我们从 OpenZeppelin 导入的合约来铸造。

在我们的scofield合约中,我们将导入 OpenZeppelin 合约并将以下命令粘贴到我们的 Remix 编辑器中:

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

接下来,我们调用外部COINMAKER合约。我们指定它是一个 ERC-20 合约,然后我们调用constructor function它,我们给出一个参数name of coinLOGROCKET 和symbol of coinLOG-COIN。

我们constructor function必须在任何其他函数之前运行。它有一个_mint参数告诉合约可以铸造多少硬币msg.sender。我们指定msg.sender罐头铸造1000000000000000000Wei,这是最小的以太坊单位。

Wei、Gwei 和以太

兑换以太币

作为旁注,我们应该谈谈以太坊单位。在这个合约中,我们创建了一个以太币,但我们使用最小的以太坊单位(Wei)来表示价值。

这是一个用于转换不同以太坊单位的有用工具,例如 Wei、Gwei、Finney 和 Ether。

部署和调用嵌套合约

现在是时候部署我们的合约了。在 Remix DEPLOY & RUN面板中,我们可以看到合约下拉列表和合约列表。COINMAKER这些合同与我们的和合同一起被拉进来scofield,这是我们创建的两个合同。

造币者合约

现在,让我们部署COINMAKER合约。

如果您尝试在未安装 MetaMask 钱包的情况下进行部署,您将看到如下内容:

创建 Coinmaker 待定

接下来,我们来谈谈gas费和testnet水龙头。要交易此合约,您可以从测试网请求测试 ETH。在文章中,我使用了 Rinkeby,但它正在被贬值。如果您愿意,也可以使用 Goerli。

接收 Eth

如上图所示,您将从测试网获得0.1 ether,足以支付gas费用。但是,如果您想继续练习,可以多次提出请求。

在部署合约之前,请确保将Environmentfrom更改Javascript VMInjected Web3.

现在,让我们再次部署合约。这次您应该看到以下 MetaMask 通知:

元掩码通知

在面板的底部,我们看到创建COINMAKER待定。

造币者待定

接下来,单击etherscan 上的视图。这将打开 Etherscan,我们可以在其中看到我们刚刚创建的硬币。

我们可以看到代币的名称,LOGROCKET以及用于部署此合约的 gas 量。

代币名称和气体

单击令牌名称以查看更多详细信息:

代币详情

在这里我们可以看到持有代币的人数(现在只有一个)。

现在,让我们回到我们的合同。

我们合约中的每个功能都有一个目的。这是一个摘要:

  • Approve:允许发送方在区块链上保留一定数量的资金,地址可以提取该指定数量
  • DecreaseAllowance:允许我们减少我们在Approve函数中设置的金额,因此如果计划太高,创建的合约可能会减少指定的金额
  • IncreaseAllowance: 增加区块链中的分配资金
  • Transfer:允许合约所有者将合约中的资金转移给另一个用户
  • TransferFrom: 允许所有者Approve在被批准进入区块链后从功能中转移,而不是从所有者资金中转移

硬币菜单

而已; 您刚刚创建了自己的 Web3 硬币!

结论

使用多个智能合约可以为项目提供更多安全性。在本文中,我们使用贷款智能合约的示例来演示从父合约调用嵌套合约。我们还使用自定义铸币合约的示例来演示从嵌套合约调用外部合约。

在合约中创建合约或嵌套智能合约对于限制用户可以做什么以及他们可以调用什么很有用。 

来源:https ://blog.logrocket.com/nested-smart-contracts-creating-contract-within-contract/

#smartcontract #contract #nest #solidity 

嵌套智能合约:在合约中创建合约

Contratos Inteligentes Anidados: Creación De Un Contrato Dentro De Un

Los contratos inteligentes son programas almacenados en la cadena de bloques que se ejecutan cuando ciertas condiciones están predeterminadas o llamadas. Los contratos inteligentes se utilizan para automatizar acuerdos, eliminar intermediarios y crear una red más descentralizada libre de influencias externas.

En este artículo, veremos una estrategia específica denominada contratos anidados o contratos con un contrato. Específicamente, revisaremos cómo crear varios contratos y llamar a funciones desde un contrato principal. Demostraremos cómo llamar a un contrato anidado desde el contrato principal y también cómo llamarlo desde un contrato externo. Todos los ejemplos de contratos inteligentes utilizados en este artículo están escritos en Solidity.

Sumerjámonos.

¿Por qué anidar un contrato dentro de un contrato?

Hay varias razones por las que puede ser ventajoso incluir un contrato inteligente dentro de otro contrato inteligente:

  • Seguridad: los contratos anidados pueden ayudar a aislar el riesgo de vulnerabilidades; cuando todas las variables del contrato se incluyen dentro de un contrato inteligente, es más fácil pasar por alto un error o una debilidad que podría ser explotada por un mal actor
  • Segmentación: los contratos múltiples nos permiten dividir el contrato principal en partes más pequeñas con una lógica menos compleja
  • Código reutilizable: muchas funciones básicas de contrato están disponibles en forma de lógica reutilizable de código abierto a través de empresas como OpenZeppelin ; aprovechar su código puede proporcionar importantes ahorros de tiempo de desarrollo

¿Pueden los contratos inteligentes interactuar entre sí?

Los contratos inteligentes pueden crear o implementar otros contratos. También pueden llamar funciones de otros contratos inteligentes. En este artículo, examinaremos dos ejemplos de llamadas a un contrato inteligente anidado:

  • Contrato dentro de un contrato: cuando los contratos están anidados dentro de un contrato principal, ellos o sus funciones pueden llamarse desde uno de los otros contratos
  • Llamar a un contrato anidado desde un contrato externo: los contratos también se pueden llamar externamente; por ejemplo, podría usar una función constructora para llamar a un contrato externo

Demostración: llamar a un contrato inteligente anidado desde el contrato principal

Para nuestro primer ejemplo, creemos y luego implementemos un contrato secundario dentro de un contrato principal.

Crear el contrato anidado

Para comenzar, abriremos Remix y crearemos el contrato principal. Para este ejemplo, haremos un contrato de préstamo; cualquiera puede llamar a este contrato y solicitar un préstamo.

Contrato de prestamo

 

La primera línea del contrato es nuestro License. Esto es muy importante, ya que no llamarlo generará un error:

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

Estamos usando Remix como compilador y tiene diferentes versiones. Verifique la versión que está usando; si la versión no coincide con el compilador, obtendrá un error. En este ejemplo, estamos usando la versión Remix ^0.8.0y superior. El ^símbolo significa "arriba".

Como se muestra a continuación, el ParentLoanCompanycontrato toma una función llamada TakeLoanque toma externalatributos. Los módulos externos se pueden usar para introducir API personalizadas o de terceros en una instancia de Web3. Los módulos externos son simplemente clases cuyos métodos y propiedades pueden estar disponibles dentro de la instancia de Web3.

Módulos Externos

contract ParentLoanCompany {
    function TakeLoan() external {
        LoanContract loan = new LoanContract (2000);
    }
}

Usamos el externalatributo para llamar a nuestro contrato hijo.

Antes de hacer eso, creemos nuestro contrato secundario dentro del contrato principal:

 contract ChildLoanContract {
    uint public amount;
    constructor(uint _amount) public{
        amount = _amount;
    }
}

Nuestro ChildLoanContractes el contrato con el que el usuario interactúa directamente, y llamamos el contrato secundario al contrato principal. Repasemos los detalles básicos del contrato hijo:

uint public amount;
    constructor(uint _amount) public{

Debemos concienciar a Solidez que este contrato trata de dinero. Para hacerlo, llamamos al uint, que es un entero sin signo, y lo convertimos en public.

Creamos una constructorque se ejecuta primero, y una vez que se llama al contrato, le damos un argumento de _amount, lo que significa que quien llame a esta función debe especificar la cantidad que desea pedir prestada.

Finalmente, llamamos amount = _amount;que significa que cualquier monto que el usuario ingrese se convierte en el monto del préstamo que se realiza public.

Ahora, regresemos al ParentLoanCompanycontrato y agreguemos el siguiente fragmento de código para conectar ambos contratos.

LoanContract loan = new LoanContract (2000);

Llamamos al ChildLoanContractllamando al LoanContracty le damos un nombre loan. Esto es muy importante cuando queremos llamar más tarde a la dirección del prestatario. Esto es equivalente a newcuál es la función que crea un nuevo contrato de tipo LoanContract.

Implementación del contrato anidado

Después de implementar el ParentLoanCompanycontrato con Remix IDE, deberíamos ver dos contratos en el panel Contrato.

Desplegable de contrato

Demostración: llamar a un contrato inteligente anidado desde un contrato externo

Ahora, echemos un vistazo a cómo un contrato externo puede llamar a un contrato anidado.

Implementar transacciones de ejecución

Creando los contratos

Al igual que en el ejemplo anterior, la primera línea de código es nuestro License. Si no proporcionamos esto, Remix arrojará un error.

A continuación, especificamos nuestra versión y compilador; Remix usa este compilador para probar nuestro proyecto y si el compilador y la versión son diferentes obtendremos un error.

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

Crearemos un contrato, llamado scofield, que le permite al usuario almacenar una dirección en la string [] public usermatriz.

También creamos un argumento en la NameOfUserfunción que almacena el nombre que proporciona la persona que llama al contrato dentro del archivo _user.

contract scofield{
    address owner;
    string [] public user;
    function NameOfUser(string memory _user ) public {
        user.push(_user);
    }
}

Ahora, vamos a crear el contrato anidado.

Crearemos otro contrato dentro del mismo archivo que acuña nuestra moneda, LOGROCKET. El símbolo de la moneda es LOG_COIN. Esta moneda se acuñará mediante un contrato que importamos de OpenZeppelin.

En nuestro scofieldcontrato, importaremos el contrato OpenZeppelin y pegaremos el siguiente comando en nuestro editor Remix:

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

A continuación, llamamos al COINMAKERcontrato externo. Especificamos que es un contrato ERC-20, y luego llamamos a al constructor functionque le damos un argumento de name of coin, LOGROCKET, y symbol of coin, LOG-COIN.

Nuestro constructor functiondebe ejecutarse antes que cualquier otra función. Tiene un _mintargumento que le dice al contrato cuántas monedas msg.senderacuñará la lata. Especificamos que la msg.senderlata acuña 1000000000000000000Wei, que es la unidad Ethereum más pequeña.

Wei, Gwei y éter

Conversión de monedas Ethereum

Como nota al margen, deberíamos hablar por un momento sobre las unidades de Ethereum. En este contrato, estamos creando un Ether, pero estamos usando la unidad Ethereum más pequeña (Wei) para representar el valor.

Aquí hay una herramienta útil para convertir diferentes unidades de Ethereum , como Wei, Gwei, Finney y Ether.

Implementación y llamada del contrato anidado

Ahora es el momento de implementar nuestro contrato. En el panel DEPLOY & RUN de Remix , vemos el menú desplegable de contratos y una lista de contratos. Estos contratos se incorporan junto con nuestros contratos COINMAKERy scofield, que son los dos contratos que creamos.

Contrato de fabricante de monedas

Ahora, implementemos el COINMAKERcontrato.

Si intenta implementar sin instalar primero su billetera MetaMask, verá algo como esto:

Creación de Coinmaker Pendiente

A continuación, hablemos de la tarifa de gas y el grifo de testnet. Para tramitar este contrato, puede solicitar ETH de prueba desde una red de prueba. En el artículo, usé Rinkeby, pero se está depreciando. Si lo prefiere, puede usar Goerli en su lugar.

Recibir eth

Como se muestra en la imagen de arriba, obtendrá 0.1 etherde la red de prueba, que será más que suficiente para pagar la tarifa del gas. Sin embargo, puede realizar la solicitud varias veces si desea seguir practicando.

Antes de implementar el contrato, asegúrese de cambiar Environmentde Javascript VMa Injected Web3.

Ahora, implementemos el contrato nuevamente. Esta vez debería ver la siguiente notificación de MetaMask:

Notificación de metamáscara

En la parte inferior del panel, vemos que la creación de COINMAKERestá pendiente.

Coinmaker Pendiente

A continuación, haga clic en ver en etherscan . Esto abrirá Etherscan, donde podemos ver la moneda que acabamos de crear.

Podemos ver el nombre del token, LOGROCKETasí como la cantidad de gas que se utilizó para implementar este contrato.

Nombre del token y gas

Haga clic en el nombre del token para ver más detalles:

Detalles del token

Aquí podemos ver la cantidad de personas que tienen el token (solo uno en este momento).

Ahora, volvamos a nuestro contrato.

Cada función dentro de nuestro contrato tiene un propósito. He aquí un resumen:

  • Approve: permite al remitente mantener una cierta cantidad de fondos en la cadena de bloques con una dirección que puede retirar esa cantidad específica
  • DecreaseAllowance: Nos permite disminuir la cantidad que establecemos en la Approvefunción, por lo que el contrato creado podría reducir la cantidad especificada si se programó demasiado alto
  • IncreaseAllowance: Aumenta los fondos asignados en la cadena de bloques
  • Transfer: permite al propietario del contrato transferir fondos en el contrato a otro usuario
  • TransferFrom: permite al propietario transferir desde la Approvefunción, en lugar de los fondos del propietario, después de ser aprobado en la cadena de bloques

Menú de monedas

Eso es todo; ¡Acabas de crear tu propia moneda Web3!

Conclusión

El uso de múltiples contratos inteligentes puede brindar más seguridad a los proyectos. En este artículo, usamos el ejemplo de un contrato inteligente de préstamo para demostrar cómo llamar a un contrato anidado desde el contrato principal. También usamos el ejemplo de un contrato personalizado de acuñación de monedas para demostrar cómo llamar a un contrato externo desde un contrato anidado.

La creación de contratos dentro de contratos, o contratos inteligentes anidados, es útil para limitar lo que un usuario puede hacer y lo que puede llamar. 

Fuente: https://blog.logrocket.com/nested-smart-contracts-creating-contract-within-contract/ 

#smartcontract #contract #nest #solidity 

Contratos Inteligentes Anidados: Creación De Un Contrato Dentro De Un
坂本  篤司

坂本 篤司

1657087800

ネストされたスマートコントラクト:コントラクト内にコントラクトを作成する

スマートコントラクトは、特定の条件が事前に決定されているか呼び出されたときに実行される、ブロックチェーンに保存されているプログラムです。スマートコントラクトは、契約を自動化し、仲介者を排除し、外部の影響を受けない、より分散化されたネットワークを作成するために使用されます。

この記事では、ネストされたコントラクト、またはコントラクトを使用したコントラクトと呼ばれる特定の戦略について説明します。具体的には、複数のコントラクトを作成し、親コントラクト内から関数を呼び出す方法を確認します。親コントラクトからネストされたコントラクトを呼び出す方法と、外部コントラクトから呼び出す方法を示します。この記事で使用されているスマートコントラクトの例はすべて、Solidityで記述されています。

飛び込みましょう。

なぜコントラクトをコントラクト内にネストするのですか?

スマートコントラクトを別のスマートコントラクトに含めることが有利な理由はいくつかあります。

  • セキュリティ:ネスト契約は、脆弱性のリスクを分離するのに役立ちます。すべてのコントラクト変数が1つのスマートコントラクトに含まれていると、悪意のある攻撃者によって悪用される可能性のあるエラーや弱点を見逃しやすくなります
  • セグメンテーション:複数の契約により、主要な契約をより複雑でないロジックでより小さな部分に分割できます
  • 再利用可能なコード:多くの基本的な契約機能は、OpenZeppelinなどの企業を通じてオープンソースの再利用可能なロジックの形ですぐに利用できます。それらのコードを利用することで、開発時間を大幅に節約できます

スマートコントラクトは相互に作用できますか?

スマートコントラクトは、他のコントラクトを作成または展開できます。また、他のスマートコントラクトの関数を呼び出すこともできます。この記事では、ネストされたスマートコントラクトを呼び出す2つの例を検討します。

  • コントラクト内のコントラクト:コントラクトが1つのメインコントラクト内にネストされている場合、それらまたはその関数は他のコントラクトの1つから呼び出すことができます。
  • 外部コントラクトからネストされたコントラクトを呼び出す:コントラクトは外部から呼び出すこともできます。たとえば、コンストラクター関数を使用して外部コントラクトを呼び出すことができます

デモ:親コントラクトからネストされたスマートコントラクトを呼び出す

最初の例では、親コントラクト内に子コントラクトを作成してデプロイしましょう。

ネストされたコントラクトの作成

まず、Remixを開いて、親コントラクトを作成します。この例では、ローン契約を結びます。誰でもこの契約を呼び出してローンを要求することができます。

ローン契約

 

契約の最初の行は私たちLicenseです。これを呼び出さないとエラーが発生するため、これは非常に重要です。

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

Remixをコンパイラーとして使用しており、バージョンが異なります。使用しているバージョンを確認してください。バージョンがコンパイラと一致しない場合は、エラーが発生します。この例では、Remixバージョン以降を使用しています^0.8.0^記号は「上」を意味します。

以下に示すように、ParentLoanCompanyコントラクトは属性を受け取ると呼ばれる関数TakeLoanを取りexternalます。外部モジュールを使用して、カスタムまたはサードパーティのAPIをWeb3インスタンスに導入できます。外部モジュールは、メソッドとプロパティをWeb3インスタンス内で使用できるようにすることができる単なるクラスです。

外部モジュール

contract ParentLoanCompany {
    function TakeLoan() external {
        LoanContract loan = new LoanContract (2000);
    }
}

external子コントラクトを呼び出すために属性を使用しました。

その前に、親コントラクト内に子コントラクトを作成しましょう。

 contract ChildLoanContract {
    uint public amount;
    constructor(uint _amount) public{
        amount = _amount;
    }
}

私たちChildLoanContractはユーザーが直接対話する契約であり、子契約を親契約と呼びます。子契約の基本的な詳細を確認しましょう。

uint public amount;
    constructor(uint _amount) public{

この契約はお金を扱っていることをSolidityに認識させる必要があります。そのためにuint、符号なし整数であるを呼び出し、それを作成しpublicます。

最初に実行されるを作成しconstructor、コントラクトが呼び出されると、の引数を_amount指定します。これは、この関数を呼び出す人は誰でも借りたい金額を指定する必要があることを意味します。

最後に、これを呼び出しますamount = _amount;。これは、ユーザーが入力した金額が、行われるローン金額になることを意味しますpublic

ParentLoanCompanyそれでは、コントラクトに戻り、以下のコードスニペットを追加して両方のコントラクトを接続しましょう。

LoanContract loan = new LoanContract (2000);

を呼び出すことでをChildLoanContract呼び出しLoanContract、名前を付けloanます。これは、後で借り手の住所に電話をかけたいときに非常に重要です。newこれは、タイプの新しいコントラクトを作成する関数と同等LoanContractです。

ネストされたコントラクトのデプロイ

Remix IDEを使用してコントラクトをデプロイするParentLoanCompanyと、コントラクトパネルに2つのコントラクトが表示されます。

契約ドロップダウン

デモ:外部コントラクトからネストされたスマートコントラクトを呼び出す

次に、外部コントラクトがネストされたコントラクトを呼び出す方法を見てみましょう。

実行トランザクションのデプロイ

契約の作成

前の例と同様に、コードの最初の行はですLicense。これを提供しない場合、Remixはエラーをスローします。

次に、バージョンとコンパイラを指定します。Remixはこのコンパイラを使用してプロジェクトをテストします。コンパイラとバージョンが異なる場合は、エラーが発生します。

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

scofieldユーザーがstring [] public user配列にアドレスを格納できるようにする、と呼ばれるコントラクトを作成します。

NameOfUserまた、コントラクトの呼び出し元が提供する名前を内に格納する引数を関数に作成します_user

contract scofield{
    address owner;
    string [] public user;
    function NameOfUser(string memory _user ) public {
        user.push(_user);
    }
}

それでは、ネストされたコントラクトを作成しましょう。

同じファイル内に、コインを作成する別のコントラクトを作成しますLOGROCKET。コインのシンボルはLOG_COINです。このコインは、OpenZeppelinからインポートした契約を使用して鋳造されます。

コントラクトでは、 OpenZeppelinscofieldコントラクトをインポートし、次のコマンドをRemixエディターに貼り付けます。

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

次に、外部COINMAKER契約と呼びます。それがERC-20コントラクトであることを指定し、次に、LOGROCKETとLOG-COINconstructor functionの引数を与えるaを呼び出します。name of coinsymbol of coin

constructor function他の関数の前に実行する必要があります。_mint何枚のコインmsg.senderをミントできるかを契約に伝える議論があります。最小のイーサリアムユニットである魏msg.senderをミントすることができると指定しました。1000000000000000000

Wei、Gwei、Ether

イーサリアム通貨の変換

ちなみに、イーサリアムユニットについて少しお話しする必要があります。この契約では、1つのイーサリアムを作成していますが、値を表すために最小のイーサリアム単位(Wei)を使用しています。

これは、Wei、Gwei、Finney、Etherなどのさまざまなイーサリアム単位を変換するための便利なツールです。

ネストされたコントラクトのデプロイと呼び出し

次に、契約を展開します。Remix DEPLOY&RUNパネルに、契約のドロップダウンと契約のリストが表示されます。これらの契約は、私たちが作成した2つの契約である私たちCOINMAKERと契約と一緒に引き込まれます。scofield

コインメーカー契約

それでは、COINMAKERコントラクトをデプロイしましょう。

MetaMaskウォレットを最初にインストールせずにデプロイしようとすると、次のように表示されます。

保留中のコインメーカーの作成

次に、ガス料金とテストネットの蛇口について話しましょう。この契約を処理するには、テストネットからテストETHをリクエストできます。記事ではリンケビューを使用しましたが、減価償却中です。必要に応じて、代わりにGoerliを使用できます。

Ethを受け取る

上の画像に示されているように0.1 ether、テストネットから取得します。これは、ガス料金を支払うのに十分すぎるほどです。ただし、練習を続けたい場合は、何度かリクエストすることができます。

コントラクトをデプロイする前に、をEnvironmentからJavascript VMに変更してくださいInjected Web3

それでは、コントラクトを再度デプロイしましょう。今回は、次のMetaMask通知が表示されます。

メタマスク通知

パネルの下部に、の作成COINMAKERが保留中であることがわかります。

コインメーカー保留中

次に、etherscanの表示をクリックします。これによりEtherscanが開き、作成したばかりのコインを見ることができます。

トークンの名前、、およびLOGROCKETこの契約を展開するために使用されたガスの量を確認できます。

トークン名とガス

詳細を表示するには、トークンの名前をクリックしてください。

トークンの詳細

ここでは、トークンを保持している人の数を確認できます(現在は1人だけです)。

それでは、契約に戻りましょう。

契約内の各機能には目的があります。要約は次のとおりです。

  • Approve:送信者が、指定された金額を引き出すことができるアドレスを使用して、ブロックチェーンに特定の金額の資金を保持できるようにします
  • DecreaseAllowance:関数で設定した金額をApprove減らすことができるため、スケジュールが高すぎる場合、作成されたコントラクトが指定された金額を減らす可能性があります
  • IncreaseAllowance:ブロックチェーンに割り当てられた資金を増やします
  • Transfer:契約所有者が契約内の資金を別のユーザーに転送できるようにします
  • TransferFromApprove:ブロックチェーンに承認された後、所有者が所有者の資金からではなく、機能から転送できるようにします

コインメニュー

それでおしまい; 独自のWeb3コインを作成しました。

結論

複数のスマートコントラクトを使用すると、プロジェクトのセキュリティを強化できます。この記事では、ローンスマートコントラクトの例を使用して、親コントラクトからネストされたコントラクトを呼び出す方法を示しました。また、カスタムコインミンティングコントラクトの例を使用して、ネストされたコントラクトから外部コントラクトを呼び出す方法を示しました。

コントラクト内にコントラクトを作成するか、ネストされたスマートコントラクトは、ユーザーが実行できることと、ユーザーが呼び出すことができることを制限するのに役立ちます。 

ソース:https ://blog.logrocket.com/nested-smart-contracts-creating-contract-within-contract/ 

#smartcontract #contract #nest #solidity 

ネストされたスマートコントラクト:コントラクト内にコントラクトを作成する

Contrats Intelligents Imbriqués : Créer Un Contrat Dans Un Contrat

Les contrats intelligents sont des programmes stockés sur la blockchain qui s'exécutent lorsque certaines conditions sont prédéterminées ou appelées. Les contrats intelligents sont utilisés pour automatiser les accords, éliminer les intermédiaires et créer un réseau plus décentralisé, libre de toute influence extérieure.

Dans cet article, nous examinerons une stratégie spécifique appelée contrats imbriqués ou contrats avec un contrat. Plus précisément, nous verrons comment créer plusieurs contrats et appeler des fonctions à partir d'un contrat parent. Nous montrerons comment appeler un contrat imbriqué à partir du contrat parent et également comment l'appeler à partir d'un contrat externe. Tous les exemples de contrats intelligents utilisés dans cet article sont écrits en Solidity.

Plongeons dedans.

Pourquoi imbriquer un contrat dans un contrat ?

Il peut être avantageux d'inclure un contrat intelligent dans un autre contrat intelligent pour plusieurs raisons :

  • Sécurité : les contrats d'imbrication peuvent aider à isoler le risque de vulnérabilités ; lorsque toutes les variables de contrat sont incluses dans un contrat intelligent, il est plus facile de passer à côté d'une erreur ou de faiblesses qui pourraient être exploitées par un mauvais acteur
  • Segmentation : plusieurs contrats nous permettent de diviser le contrat principal en plus petits morceaux avec une logique moins complexe
  • Code réutilisable : de nombreuses fonctions contractuelles de base sont facilement disponibles sous la forme d'une logique open source et réutilisable par le biais d'entreprises comme OpenZeppelin ; tirer parti de leur code peut apporter des gains de temps de développement significatifs

Les contrats intelligents peuvent-ils interagir les uns avec les autres ?

Les contrats intelligents sont capables de créer ou de déployer d'autres contrats. Ils peuvent également appeler des fonctions d'autres contrats intelligents. Dans cet article, nous examinerons deux exemples d'appel d'un contrat intelligent imbriqué :

  • Contrat dans un contrat : Lorsque des contrats sont imbriqués dans un contrat principal, ils ou leurs fonctions peuvent être appelés à partir de l'un des autres contrats
  • Appel d'un contrat imbriqué à partir d'un contrat externe : Les contrats peuvent également être appelés en externe ; par exemple, vous pouvez utiliser une fonction constructeur pour appeler un contrat externe

Démo : appeler un contrat intelligent imbriqué à partir du contrat parent

Pour notre premier exemple, créons puis déployons un contrat enfant dans un contrat parent.

Création du contrat imbriqué

Pour commencer, nous allons ouvrir Remix et créer le contrat parent. Pour cet exemple, nous allons faire un contrat de prêt ; n'importe qui peut appeler ce contrat et demander un prêt.

Contrat de prêt

 

La première ligne du contrat est notre License. Ceci est très important, car ne pas l'appeler générera une erreur :

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

Nous utilisons Remix comme compilateur, et il existe différentes versions. Vérifiez la version que vous utilisez ; si la version ne correspond pas au compilateur, vous obtiendrez une erreur. Dans cet exemple, nous utilisons la version Remix ^0.8.0et supérieure. Le ^symbole signifie « au-dessus ».

Comme indiqué ci-dessous, le ParentLoanCompanycontrat prend une fonction appelée TakeLoanqui prend des externalattributs. Des modules externes peuvent être utilisés pour introduire des API personnalisées ou tierces dans une instance Web3. Les modules externes sont simplement des classes dont les méthodes et les propriétés peuvent être rendues disponibles dans l'instance Web3.

Modules externes

contract ParentLoanCompany {
    function TakeLoan() external {
        LoanContract loan = new LoanContract (2000);
    }
}

Nous avons utilisé l' externalattribut pour appeler notre contrat enfant.

Avant de faire cela, créons notre contrat enfant dans le contrat parent :

 contract ChildLoanContract {
    uint public amount;
    constructor(uint _amount) public{
        amount = _amount;
    }
}

Notre ChildLoanContractest le contrat avec lequel l'utilisateur interagit directement, et nous appelons le contrat enfant dans le contrat parent. Passons en revue les détails de base du contrat de l'enfant :

uint public amount;
    constructor(uint _amount) public{

Nous devons faire prendre conscience à Solidity que ce contrat traite de l'argent. Pour ce faire, nous appelons le uint, qui est un entier non signé, et nous en faisons public.

Nous créons un constructorqui s'exécute en premier, et une fois que le contrat est appelé, nous donnons un argument de _amount, ce qui signifie que celui qui appelle cette fonction doit spécifier le montant qu'il souhaite emprunter.

Enfin, nous appelons amount = _amount;ce qui signifie que le montant que l'utilisateur investit devient le montant du prêt consenti public.

Revenons maintenant au ParentLoanCompanycontrat et ajoutons l'extrait de code ci-dessous pour connecter les deux contrats.

LoanContract loan = new LoanContract (2000);

Nous appelons le ChildLoanContracten appelant le LoanContractet lui donnons un nom loan. Ceci est très important lorsque nous voulons appeler plus tard l'adresse de l'emprunteur. Ceci équivaut à newquelle est la fonction qui crée un nouveau contrat de type LoanContract.

Déployer le contrat imbriqué

Après avoir déployé le ParentLoanCompanycontrat avec l'IDE Remix, nous devrions voir deux contrats dans le panneau Contrat.

Liste déroulante des contrats

Démo : appeler un contrat intelligent imbriqué à partir d'un contrat externe

Voyons maintenant comment un contrat externe peut appeler un contrat imbriqué.

Déployer les transactions d'exécution

Création des contrats

Tout comme dans l'exemple précédent, la première ligne de code est notre fichier License. Si nous ne le fournissons pas, Remix générera une erreur.

Ensuite, nous spécifions notre version et notre compilateur ; Remix utilise ce compilateur pour tester notre projet et si le compilateur et la version sont différents, nous obtiendrons une erreur.

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

Nous allons créer un contrat, appelé scofield, qui permet à l'utilisateur de stocker une adresse dans le string [] public usertableau.

Nous créons également un argument dans la NameOfUserfonction qui stocke le nom fourni par un appelant du contrat dans le fichier _user.

contract scofield{
    address owner;
    string [] public user;
    function NameOfUser(string memory _user ) public {
        user.push(_user);
    }
}

Maintenant, créons le contrat imbriqué.

Nous allons créer un autre contrat dans le même fichier qui frappe notre pièce, LOGROCKET. Le symbole de la pièce est LOG_COIN. Cette pièce sera frappée à l'aide d'un contrat que nous avons importé d'OpenZeppelin.

Dans notre scofieldcontrat, nous allons importer le contrat OpenZeppelin et coller la commande suivante dans notre éditeur Remix :

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

Ensuite, nous appelons le contrat externe COINMAKER. On précise qu'il s'agit d'un contrat ERC-20, puis on appelle a constructor functionauquel on donne comme argument name of coin, LOGROCKET, et symbol of coin, LOG-COIN.

Our constructor functiondoit s'exécuter avant toute autre fonction. Il a un _mintargument qui indique au contrat combien de pièces la msg.senderboîte peut frapper. Nous avons précisé que la msg.sendercanette 1000000000000000000Wei, qui est la plus petite unité Ethereum.

Wei, Gwei et Ether

Conversion des devises Ethereum

En passant, nous devrions parler un instant des unités Ethereum. Dans ce contrat, nous créons un Ether, mais nous utilisons la plus petite unité Ethereum (Wei) pour représenter la valeur.

Voici un outil utile pour convertir différentes unités Ethereum , telles que Wei, Gwei, Finney et Ether.

Déployer et appeler le contrat imbriqué

Il est maintenant temps de déployer notre contrat. Dans le panneau Remix DEPLOY & RUN , nous voyons la liste déroulante des contrats et une liste de contrats. Ces contrats sont ajoutés à nos contrats COINMAKERet scofield, qui sont les deux contrats que nous avons créés.

Contrat de fabricant de pièces

Maintenant, déployons le COINMAKERcontrat.

Si vous essayez de déployer sans installer au préalable votre portefeuille MetaMask, vous verrez quelque chose comme ceci :

Création de Coinmaker en attente

Parlons ensuite des frais de gaz et du robinet testnet. Pour effectuer ce contrat, vous pouvez demander un test ETH à partir d'un testnet. Dans l'article, j'ai utilisé Rinkeby, mais il est déprécié. Si vous préférez, vous pouvez utiliser Goerli à la place.

Recevoir Eth

Comme le montre l'image ci-dessus, vous obtiendrez 0.1 etherdu testnet, ce qui sera plus que suffisant pour payer les frais de gaz. Cependant, vous pouvez faire la demande plusieurs fois si vous souhaitez continuer à pratiquer.

Avant de déployer le contrat, assurez-vous de changer le Environmentde Javascript VMà Injected Web3.

Maintenant, déployons à nouveau le contrat. Cette fois, vous devriez voir la notification MetaMask suivante :

Notification de métamasque

En bas du panneau, on voit que la création de COINMAKERest en attente.

Fabricant de pièces en attente

Ensuite, cliquez sur afficher sur etherscan . Cela ouvrira Etherscan, où nous pourrons voir la pièce que nous venons de créer.

Nous pouvons voir le nom du jeton, LOGROCKET, ainsi que la quantité de gaz qui a été utilisée pour déployer ce contrat.

Nom et gaz du jeton

Cliquez sur le nom du jeton pour voir plus de détails :

Détails du jeton

Ici, nous pouvons voir le nombre de personnes détenant le jeton (un seul pour le moment).

Maintenant, revenons à notre contrat.

Chaque fonction de notre contrat a un but. Voici un résumé :

  • Approve: Permet à l'expéditeur de conserver un certain montant de fonds sur la blockchain avec une adresse qui peut retirer ce montant spécifié
  • DecreaseAllowance: nous permet de diminuer le montant que nous avons défini dans la Approvefonction, de sorte que le contrat créé pourrait réduire le montant spécifié s'il était planifié trop haut
  • IncreaseAllowance: Augmente les fonds alloués dans la blockchain
  • Transfer: permet au titulaire du contrat de transférer des fonds du contrat à un autre utilisateur
  • TransferFrom: Permet au propriétaire de transférer depuis la Approvefonction, plutôt que depuis les fonds du propriétaire, après avoir été approuvé dans la blockchain

Menu des pièces

C'est ça; vous venez de créer votre propre pièce Web3 !

Conclusion

L'utilisation de plusieurs contrats intelligents peut fournir plus de sécurité aux projets. Dans cet article, nous avons utilisé l'exemple d'un contrat intelligent de prêt pour démontrer l'appel d'un contrat imbriqué à partir du contrat parent. Nous avons également utilisé l'exemple d'un contrat de frappe de pièces personnalisé pour démontrer l'appel d'un contrat externe à partir d'un contrat imbriqué.

La création de contrats dans des contrats, ou contrats intelligents imbriqués, est utile pour limiter ce qu'un utilisateur peut faire et ce qu'il peut appeler. 

Source : https://blog.logrocket.com/nested-smart-contracts-creating-contract-within-contract/

#smartcontract #contract #nest #solidity 

Contrats Intelligents Imbriqués : Créer Un Contrat Dans Un Contrat

Nested Smart Contracts: Creating A Contract within A Contract

Smart contracts are programs stored on the blockchain that run when certain conditions are predetermined or called. Smart contracts are used to automate agreements, eliminate intermediaries, and create a more decentralized network free from external influence.

In this article, we’ll take a look at a specific strategy referred to as nested contracts, or contracts with a contract. Specifically, we’ll review how to create multiple contracts and call functions from within a parent contract. We’ll demonstrate how to call a nested contract from the parent contract and also how to call it from an external contract. All of the smart contract examples used in this article are written in Solidity.

Let’s dive in.

Why nest a contract inside a contract?

There are several reasons why it may be advantageous to include a smart contract within another smart contract:

  • Security: Nesting contracts can help isolate the risk of vulnerabilities; when all contract variables are included within one smart contract, it’s easier to miss an error or weaknesses that could be exploited by a bad actor
  • Segmentation: Multiple contracts enable us to break the main contract into smaller pieces with less complex logic
  • Reusable code: Many basic contract functions are readily available in the form of open source, reusable logic through companies like OpenZeppelin; taking advantage of their code can provide significant development time savings

See more at: https://blog.logrocket.com/nested-smart-contracts-creating-contract-within-contract/

#smartcontract #contract #nest #solidity 

Nested Smart Contracts: Creating A Contract within A Contract
Awesome  Rust

Awesome Rust

1656447000

Provwasm Mocks: Enable Unit Testing Of CosmWasm Smart Contracts

provwasm-mocks

This crate provides mocks that enable unit testing of CosmWasm smart contracts that interact with custom modules in the Provenance Blockchain.

Example Usage

// Example unit test:
// Uses provwasm mocks to test a resolve query against the provenance name module.

// ref: contracts/name/src/msg.rs

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum QueryMsg {
    Resolve { name: String },
}

// ref: contracts/name/src/contract.rs

use cosmwasm_std::testing::mock_env;
use cosmwasm_std::from_binary;
use provwasm_mocks::mock_dependencies;
use provwasm_std::Name;

#[test]
fn query_resolve() {
    // Create provenance mock deps with a single bound name.
    let mut deps = mock_dependencies();
    deps.querier
        .with_names(&[("a.pb", "tp1y0txdp3sqmxjvfdaa8hfvwcljl8ugcfv26uync", false)]);

    // Call the smart contract query function to resolve the address for our test name.
    let bin = query(
        deps.as_ref(),
        mock_env(),
        QueryMsg::Resolve {
            name: "a.pb".into(),
        },
    )
    .unwrap();

    // Ensure that we got the expected address.
    let rep: Name = from_binary(&bin).unwrap();
    assert_eq!(
        rep.address.as_str(),
        "tp1y0txdp3sqmxjvfdaa8hfvwcljl8ugcfv26uync"
    )
}

License

This crate is part of the provwasm repository, licensed under the Apache License 2.0 (see the LICENSE).

Link: https://crates.io/crates/provwasm-mocks

#rust #rustlang #blockchain #smartcontract

Provwasm Mocks: Enable Unit Testing Of CosmWasm Smart Contracts

Solidity Abi.encodePacked() implementation in Rust

Ethereum abi.encodePacked() in Rust

This project allows data serialization and packing in Rust as it's being done in Solidity with abi.encodePacked()

Example usage

packing an uint24

let input = vec![
    // this is supposed to be uint24 variable in solidity
    SolidityDataType::NumberWithShift(U256::from(4001), TakeLastXBytes(24))
];
let (bytes, hash) = abi::encode_packed(&input);
let hash = format!("0x{:}", hash);
let expected = "0x000fa1";
assert_eq!(hash, expected);

Packing a lot of data

Solidity

    function packer(
        uint24 uint24_data,
        uint256 tokenId,
        string calldata ipfsURI,
        address sample,
        uint256 id
    ) public pure returns (bytes memory ){
        bytes memory res = abi.encodePacked(uint24_data, tokenId, ipfsURI, sample, id);
        return res;
    }

Rust

let address = hex::decode("d8b934580fcE35a11B58C6D73aDeE468a2833fa8").unwrap();
let address: [u8; 20] = address.try_into().unwrap();
let input = vec![
    SolidityDataType::NumberWithShift(U256::from(3838), TakeLastXBytes(24)),
    SolidityDataType::Number(U256::from(4001)),
    SolidityDataType::String("this-is-a-sample-string"),
    SolidityDataType::Address(Address::from(address)),
    SolidityDataType::Number(U256::from(1)),
];
let (_bytes, hash) = abi::encode_packed(&input);
let hash = format!("0x{:}", hash);
let expected = "0x000efe0000000000000000000000000000000000000000000000000000000000000fa1746869732d69732d612d73616d706c652d737472696e67d8b934580fce35a11b58c6d73adee468a2833fa80000000000000000000000000000000000000000000000000000000000000001";
assert_eq!(hash, expected);

Download Details:
Author: roberts-ivanovs
Source Code: https://github.com/roberts-ivanovs/eth-encode-packed-rs
License: MIT license

#solidity #smartcontract #ethereum #rust

Solidity Abi.encodePacked() implementation in Rust

Fenris Solid: Solid Mechanics Functionality for Fenris

A Rust library for building advanced applications with the Finite Element Method (FEM).

Although developed with a special emphasis on solid mechanics in computer graphics, Fenris is a highly generic and versatile library applicable to many other domains.

Status

As of October 2021, Fenris is heavily developed alongside several of our ongoing academic projects, with the overarching goal of supporting our research efforts.

Our goal is to rework, document and polish the library for external users during 2022. In its current state, Fenris is not recommended for general usage. We currently offer no API stability whatsoever, the documentation is severely lacking, and only parts of the library has been extensively tested. Moreover, some parts of the library will likely be removed altogether in future versions.

Goals

With Fenris, we aim to provide an open-source, composable, flexible and performant library for advanced finite element computations in Rust.

Fenris is intended primarily as an alternative to C++ FEM libraries. With Fenris, users can take advantage of the significant productivity boost afforded by working with Rust, a modern programming language with a best-in-class dependency management system and a revolutionary model for memory-safe, high-performance system programming.

This statement is motivated by our own experiences writing FEM code in Rust: gone are the hours upon hours of wrestling with CMake to integrate an external library. Furthermore, the expressive type system and borrow checker model employed by Rust encourages good designs that are free of the myriads of footguns associated with (even modern) C++. And perhaps even more important, the excellent generic trait system found in Rust - which importantly is type-checked at compile time - allows us to write highly generic code with explicit invariants encoded in the type system that are automatically and correctly represented in the generated documentation.

In short, we have found that Rust allows us to spend more time on solving interesting and complex problems (the fun part), and less time on dealing with auxiliary issues largely caused by language deficiencies (the annoying part).

Summary of technical goals

  • Provide a number of low-order and high-order standard Lagrange elements of a variety of geometric shapes in 2D and 3D (at the very least triangles, quadrilaterals, tetrahedra and hexahedra).
  • High-performance shared-memory parallelism for assembly.
  • A composable architecture: Higher-level functionality is built by the composition of lower-level functionality. Users choose the level at which they need to work at.
  • Facilitates generic programming: write code once and have it work across a number of different elements, dimensions and operators.
  • Convenient I/O, currently in the form of export to VTK/VTU for visualization in ParaView.

Non-goals

  • Fenris is not intended to compete with the likes of FEniCS or similar libraries that let users provide high-level weak formulations of PDEs. In contrast, Fenris targets users who need lower-level functionality, and is perhaps more comparable to the likes of deal.II.
  • Fenris by itself provides no functionality for solving (non-)linear systems, only the functionality for assembling (as scalars/vectors/matrices) and applying discrete operators.
  • We have no plans for supporting distributed computing or GPU acceleration at this time.

Publications

An older incarnation of Fenris was used for the code associated with the following academic papers:

  • Longva, A., Löschner, F., Kugelstadt, T., Fernández-Fernández, J. A., & Bender, J. (2020). Higher-order finite elements for embedded simulation. ACM Transactions on Graphics (TOG), 39(6), 1-14.
  • Löschner, F., Longva, A., Jeske, S., Kugelstadt, T., & Bender, J. (2020).
    Higher‐Order Time Integration for Deformable Solids. In Computer Graphics Forum (Vol. 39, No. 8, pp. 157-169).

Contribution

Apart from minor bug fixes or changes, we do not accept source code contributions at this time. We would however be happy for daring users who want to try out our library to report issues on our issue tracker.

We have a number of unrealized plans that will require significant reworking of parts of the library. Once the library is in a more stable state we will be grateful for contributions from the community.

Download Details:
Author: InteractiveComputerGraphics
Source Code: https://github.com/InteractiveComputerGraphics/fenris
License: Apache-2.0, MIT licenses found

#solidity #smartcontract #ethereum #rust

Fenris Solid: Solid Mechanics Functionality for Fenris

Cargo Solid: Cargo to Genereate Solidity Struct Definitions

Solidity

A Solidity encoding and decoding framework for Rust.

// Basic usage using the built in `Encode` derive macro.
// (Requires the `derive` feature.)
#[derive(Encode)]
struct ContractCallEncode<'a> {
    pub name: &'a str,
    pub number: u128,
    pub bytes10: Bytes10,
    pub bytes: Bytes<'a>,
}

// Basic usage using serde. (Requires the `serde` feature).
// Note: Serde only supports a subset of the types that Solidity supports.
// If you need to support more types you'll have to use the `Encode` derive
// macro, or use the `solid::Builder` manually.
#[derive(Serialize)]
pub struct ContractCallSerde<'a> {
    // String is also supported, but it's recommened you use &str when possible.
    // pub name: String,
    pub name: &'a str,
    pub number: u128,
    pub bytes: Bytes<'a>,
    // Bytes10 cannot be serialized correctly using serde.
    // pub bytes: Bytes10,
}

// Use the `#[solid(constructor)]` attribute to declare a struct as a constructor.
// This is important because constructors do not have the function name prefix,
// unlike all other functions. Usually the struct name is used as the function
// name. To rename the function use the `#[solid(name = "<function_name>")]`
// where `<function_name>` is the name of your function.
// ie. `#[solid(name = "transfer")]`.
#[derive(Encode)]
struct ContractConstructorEncode<'a> {
    pub value: u128,
    pub string: &'a str,
}

// Basic usage with the built in `Decode` derive macro.
// (Requires the `derive` feature.)
// Note: `Uint256` and all other `Int`/`Uint` types are simple
// wrappers around `[u8; 32]`. The point of them is to support all
// `int`/`uint` Solidity types.
#[derive(Decode)]
#[solid(error)]
struct ContractCallResponse<'a> {
    int: Uint256,
    // Note: &'a [u8] is *not* the same as `Bytes<'a>`. The former is is `uint8[]` in solidity
    // while the latter is `bytes`. The two types are encoded very differently so decoding
    // `bytes` as `uint8[]` array will give you invalid data if not fail outright.
    bytes: Bytes<'a>,
    memo: &'a str,
    address: Address,
}

// Basic usage with serde's `Deserialize` derive macro.
// (Requires the `serde` feature.)
// Note: Serde only supports a subset of the types that Solidity supports.
// If you need to support more types you'll have to use the `Encode` derive
// macro, or use the `solid::Builder` manually.
#[derive(Deserialize)]
struct ContractCallResponseSerde<'a> {
    int: u128,
    bytes: &'a [u8],
    memo: &'a str,
    // There is no way to read `Address` with serde.
    // address: Address
}

// Support for composite types and `Vec`
#[derive(Encode)]
struct ContractCallComposite<'a> {
    to: (&'a str, u128),
    memos: &'a [&'a str],
    matrix: &'a [&'a [&'a [u8]]],
}

// If you want to manually build the contract you can use the provided `Builder`
let function = Builder::new()
    .name("transfer")
    .push("daniel")
    .push(10u128)
    .push(Bytes10([1u8; 10]))
    .build();

num_bigint Support

If you'd like support for num_bigint enable the bigint feature.

// Note: BigInt is variable sized and encodes to `int256`.
// To encode to `uint256` use the `BigUint` struct.
// Also, BigInt supports numbers larger than the max value a uint256 can store, so the value
// will be truncated to 32 bytes before it's encoded.
#[derive(Encode)]
#[solid(rename = "transfer")]
struct ContractTransfer<'a> {
    amount: BigInt,
    to: &'a str
}

ethereum_types Support

If you'd like support for ethereum_types enable the ethereum_types feature.

// Support for Address, U256, U128 from `ethereum_types` crate.
#[derive(Encode)]
#[solid(rename = "transfer")]
struct ContractTransfer<'a> {
    amount: ethereum_types::U256,
    to: ethereum_types::Address,
}

Install

# Cargo.toml

# Default features which includes `derive`, and `serde`
solid = "0.1.4"

# num_bigint support
solid = { version = "0.1.4", default-features = false, features = [ "derive", "serde", "bigint" ] }

# ethereum_types support
solid = { version = "0.1.4", default-features = false, features = [ "derive", "serde", "ethereum_types" ] }

Using cargo-edit

cargo add solid

Features

  • derive: Add support for the Encode and Decode derive macros. (Recommended)
  • derse: Add support for serdes Serialize and Deserialize derive macros, and to_bytes function.
  • bigint: Add suport for num_bigint crate.
  • ethereum_types: Add support for ethereum_types crate.
  • nightly: Experimental const generic support.

cargo-solid Subcommand

cargo-solid is a cargo subcommand that allows you to generate the encoding functions and decodable struct definitions for named return types of associated Solidity methods. example

Subcommand Install

cargo install cargo-solid

The following command generates the solidity abi for a contract.

solc --combined-json abi solidity_contract.sol > solidity_contract.json

Then run the following command to generate the rust definition.

cargo solid solidity_contract.json

The name of the output file will the be same name as the input file with the extension set to .rs, and will be located in the local src directory. You can freely move the file if you would like, but either way you will still need to add the file as a module:

mod solidity_contract;

As of version cargo-solidv0.1.4 you can also generate the files into a directory such as src/generated, and there is also support for generating code using nightly definitions of BytesFix and Int.

cargo solid --nightly -o generated stateful.json

example

Download Details:
Author: danielakhterov
Source Code: https://github.com/danielakhterov/solid
License: Apache-2.0, MIT licenses found

#solidity #smartcontract #ethereum #rust

Cargo Solid: Cargo to Genereate Solidity Struct Definitions