Esta tecnología que revolucionará Ethereum está próxima a lanzar

zkSync 2.0은 ZK 롤업과 이더리움 가상 머신과 완벽하게 호환됩니다. Esto no solo nos permitirá ahorrar gas de la manera mas segura, sino que también podremos lanzar smart contracts escritos en solidity haciéndolo un buen lugar para acoger a DeFi, NFTs y todo lo demás que hoy está ocurriendo en Layer 1. zkSync 2.0 el primer proyecto en lograr esto ya está disponible en un alpha testnet. 테스트넷과 랜자레모스를 스마트 컨트랙트 UI와 관련하여 사용하는 동영상이 있습니다. Personalmente estoy muy emocionado por este proyecto que nos permitirá ahorrar gas confiando enteramente en pruebas matemáticas. Esto es algo que especulabamos que iba a ser posible hasta dentro de varios años pero ya está a la vuelta de la esquina.

Antes de iniciar



안전한 설치Metamask, zkSync의 테스트넷 지갑에 연결:
  • 네트워크 이름: zkSync alpha testnet
  • 새 RPC URL: https://zksync2-testnet.zksync.dev
  • 체인 ID: 280

  • y también asegúrate conseguir ether de prueba en L2 desde ya sea el bridge o el faucet que puedes encontrar en elPortal de zkSync . Para usar el bridge ocuparás Ether de Goreli que puedes conseguir en este faucet .

    1. 분취제



    Necesitaremos npm para este 튜토리얼. 우분투 22.04에서 가장 중요한 점은 무엇입니까?

    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
    nvm install 14
    nvm use 14
    


    도커가 필요하면 설치를 계속해야 합니다.

    sudo apt-get update
    sudo apt-get install \
        ca-certificates \
        curl \
        gnupg \
        lsb-release
    sudo mkdir -p /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    sudo apt-get update
    sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
    wget https://desktop.docker.com/linux/main/amd64/docker-desktop-4.8.2-amd64.deb
    sudo apt install ./docker-desktop-4.8.2-amd64.deb
    systemctl --user start docker-desktop
    sudo usermod -aG docker $USER
    


    Docker를 설치하면 Hardhat에서 새로운 프로젝트를 생성할 수 있습니다.

    mkdir MyL2Project
    cd MyL2Project
    npm install --save-dev hardhat
    npx hardhat
    


    Luego de completar el diálogo de Hardhat en la terminal, finalizamos instalando un par de librerías extra.

    # si estás en ubuntu necesitarás esto: sudo apt install build-essential
    npm install --save-dev typescript ts-node ethers zksync-web3 @matterlabs/[email protected] @matterlabs/[email protected] dotenv
    


    2. Lanzar un contrato



    Primero boramos el contrato que viene por defectocontracts/Greeter.sol y escribimos uno nuestro en la carpetacontracts/ .
    contracts/Hello.sol
    // SPDX-License-Identifier: MIT
    pragma solidity 0.8.12;
    
    contract Hello {
        string public hello;
    
        constructor()
        {
            hello = "Hola mundo!";
        }
    
        function setHello(string memory _hello) public {
            hello = _hello;
        }
    }
    


    Hardhat también es compatible con Typescript que es lo que usaremos en este video. Así que renombramos hardhat.config.js a hardhat.config.ts y haremos los cambios necesarios.
    hardhat.config.ts
    require("@nomiclabs/hardhat-waffle");
    require("@matterlabs/hardhat-zksync-deploy");
    require("@matterlabs/hardhat-zksync-solc");
    
    module.exports = {
      zksolc: {
        version: "0.1.0",
        compilerSource: "docker",
        settings: {
          optimizer: {
            enabled: true,
          },
          experimental: {
            dockerImage: "matterlabs/zksolc",
          },
        },
      },
      zkSyncDeploy: {
        zkSyncNetwork: "https://zksync2-testnet.zksync.dev",
        ethNetwork: "goerli", // Can also be the RPC URL of the network (e.g. `https://goerli.infura.io/v3/<API_KEY>`)
      },
      networks: {
        // To compile with zksolc, this must be the default network.
        hardhat: {
          zksync: true,
        },
      },
      solidity: {
        version: "0.8.12",
      },
    };
    
    


    Ahora escribimos el script de deploy que debe estar en una nueva carpeta llamadadeploy/ .
    deploy/deploy.ts
    import { utils, Wallet } from "zksync-web3";
    import { HardhatRuntimeEnvironment } from "hardhat/types";
    import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
    import dotenv from "dotenv"
    
    // An example of a deploy script that will deploy and call a simple contract.
    export default async function (hre: HardhatRuntimeEnvironment) {
      dotenv.config()
      console.log(`Running deploy script for the Hello contract`);
    
      // Initialize the wallet.
      const wallet = new Wallet("" + process.env.PRIVATE_KEY);
    
      // Create deployer object and load the artifact of the contract we want to deploy.
      const deployer = new Deployer(hre, wallet);
      const artifact = await deployer.loadArtifact("Hello");
    
      // Deploy this contract. The returned object will be of a `Contract` type, similarly to ones in `ethers`.
      const helloContract = await deployer.deploy(artifact, []);
    
      // Show the contract info.
      const contractAddress = helloContract.address;
      console.log(`${artifact.contractName} was deployed to ${contractAddress}`);
    
      // Call the deployed contract.
      const helloFromContract = await helloContract.hello();
      console.log(`Contract says hello to us with ${helloFromContract}!`);
    }
    


    Crea un archivo llamado .env y coloca tu llave privada adentro siguiendo el siguiente 형식:
    .env
    PRIVATE_KEY=TULLAVEAQUÍ
    


    Ahora compilamos el contrato.

    npx hardhat compile
    


    Y lo lanzamos.

    npx hardhat deploy-zksync
    


    3. 엘 프론트엔드



    Hacer un frontend para un contrato en zkSync 2.0 Testnet es igual que en cualquier blockchain compatible con la EVM. Solo asegúrate de establecer el netwrok id280 .

    Comenzamos creando un archives de HTML.
    index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
    </head>
    <body>
      <input id="connect_button" type="button" value="Connect" onclick="connectWallet()" style="display: none"></input>
      <p id="account_address" style="display: none"></p>
      <p id="web3_message"></p>
      <p id="contract_state"></p>
      <input type="input"  value="" id="_hello"></input>
      <input type="button" value="Set Hello" onclick="_setHello()"></input>
      <br>
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/web3/1.3.5/web3.min.js"></script>
      <script type="text/javascript" src="blockchain_stuff.js"></script>
    </body>
    </html>
    
    <script>
      function _setHello()
      {
        _hello = document.getElementById("_hello").value
        setHello(_hello)
      }
    </script>
    


    Luego el javascript necesario. Asegúrate de establecer la variable MY_CONTRACT_ADDRESS con el address de tu contrato.
    blockchain_stuff.js
    const NETWORK_ID = 280
    
    const MY_CONTRACT_ADDRESS = "0x0000000000000000000000000000000000000000"
    const MY_CONTRACT_ABI_PATH = "./json_abi/MyContract.json"
    var my_contract
    
    var accounts
    var web3
    
    function metamaskReloadCallback() {
      window.ethereum.on('accountsChanged', (accounts) => {
        document.getElementById("web3_message").textContent="Se cambió el account, refrescando...";
        window.location.reload()
      })
      window.ethereum.on('networkChanged', (accounts) => {
        document.getElementById("web3_message").textContent="Se el network, refrescando...";
        window.location.reload()
      })
    }
    
    const getWeb3 = async () => {
      return new Promise((resolve, reject) => {
        if(document.readyState=="complete")
        {
          if (window.ethereum) {
            const web3 = new Web3(window.ethereum)
            window.location.reload()
            resolve(web3)
          } else {
            reject("must install MetaMask")
            document.getElementById("web3_message").textContent="Error: Porfavor conéctate a Metamask";
          }
        }else
        {
          window.addEventListener("load", async () => {
            if (window.ethereum) {
              const web3 = new Web3(window.ethereum)
              resolve(web3)
            } else {
              reject("must install MetaMask")
              document.getElementById("web3_message").textContent="Error: Please install Metamask";
            }
          });
        }
      });
    };
    
    const getContract = async (web3, address, abi_path) => {
      const response = await fetch(abi_path);
      const data = await response.json();
    
      const netId = await web3.eth.net.getId();
      contract = new web3.eth.Contract(
        data,
        address
        );
      return contract
    }
    
    async function loadDapp() {
      metamaskReloadCallback()
      document.getElementById("web3_message").textContent="Please connect to Metamask"
      var awaitWeb3 = async function () {
        web3 = await getWeb3()
        web3.eth.net.getId((err, netId) => {
          if (netId == NETWORK_ID) {
            var awaitContract = async function () {
              my_contract = await getContract(web3, MY_CONTRACT_ADDRESS, MY_CONTRACT_ABI_PATH)
              document.getElementById("web3_message").textContent="You are connected to Metamask"
              onContractInitCallback()
              web3.eth.getAccounts(function(err, _accounts){
                accounts = _accounts
                if (err != null)
                {
                  console.error("An error occurred: "+err)
                } else if (accounts.length > 0)
                {
                  onWalletConnectedCallback()
                  document.getElementById("account_address").style.display = "block"
                } else
                {
                  document.getElementById("connect_button").style.display = "block"
                }
              });
            };
            awaitContract();
          } else {
            document.getElementById("web3_message").textContent="Please connect to zkSync Testnet";
          }
        });
      };
      awaitWeb3();
    }
    
    async function connectWallet() {
      await window.ethereum.request({ method: "eth_requestAccounts" })
      accounts = await web3.eth.getAccounts()
      onWalletConnectedCallback()
    }
    
    loadDapp()
    
    const onContractInitCallback = async () => {
      var hello = await my_contract.methods.hello().call()
    
      var contract_state = "Hello: " + hello
    
      document.getElementById("contract_state").textContent = contract_state;
    }
    
    const onWalletConnectedCallback = async () => {
    }
    
    
    //// Functions ////
    
    const setHello = async (_hello) => {
      const result = await my_contract.methods.setHello(_hello)
      .send({ from: accounts[0], gas: 100000, value: 0 })
      .on('transactionHash', function(hash){
        document.getElementById("web3_message").textContent="Waiting confirmation...";
      })
      .on('receipt', function(receipt){
        document.getElementById("web3_message").textContent="Success.";    })
      .catch((revertReason) => {
        console.log("ERROR! Transaction reverted: " + revertReason.receipt.transactionHash)
      });
    }
    


    Ahora extraemos el JSON ABI que está en el archivoTUPROYECTO/artifacts-zk/contracts/Hello.sol/Hello.json bajo el tag"abi" . Que debería verse algo así una vez puesto en una nueva carpeta que creamos llamada json_abi :
    json_abi/MyContract.json
    [
        {
          "inputs": [],
          "stateMutability": "nonpayable",
          "type": "constructor"
        },
        {
          "inputs": [],
          "name": "hello",
          "outputs": [
            {
              "internalType": "string",
              "name": "",
              "type": "string"
            }
          ],
          "stateMutability": "view",
          "type": "function"
        },
        {
          "inputs": [
            {
              "internalType": "string",
              "name": "_hello",
              "type": "string"
            }
          ],
          "name": "setHello",
          "outputs": [],
          "stateMutability": "nonpayable",
          "type": "function"
        }
    ]
    


    Ahora estamos listos para interactuar con nuestro contrato instalando un servidor local y luego iniciándolo.

    npm i --global lite-server
    lite-server
    


    Fuentes oficiales: Github de NVM , Instalar Docker en Ubuntu , Descarga de Docker Desktop , Instalar Docker Desktop en Ubuntu , zkSync Testnet Getting Started

    감사합니다 por ver este 튜토리얼!

    Sígannos en dev.to y en para todo lo relacionado al desarrollo en Blockchain en Español.

    좋은 웹페이지 즐겨찾기