ยกScroll Testnet ya lanzรณ! ๐Ÿš€๐Ÿš€

30031 ๋‹จ์–ด
Estamos viviendo en la รฉpoca de los zkRollups de uso general. En este video exploramos Scroll que es el zkRollup mas fรกcil de usar porque ofrece una experiencia muy similar a desarrollar en Capa 1.

Actualmente Scroll se encuentra en fase de Alfa cerrado asรญ que si desean ingresar deben ser whitelisteados llenando este formulario .



Antes de comenzar



Para este tutorial ocuparรกs NodeJs que recomiendo descargarlo en Linux via NVM , y tambiรฉn nececitarรกs Metamask u otra wallet compatible con la Ethereum Virtual Machine.

1. Agrega las siguientes๋Š” ๋ฉ”ํƒ€๋งˆ์Šคํฌ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.



๋ ˆ์ด์–ด 1 ํ…Œ์ŠคํŠธ๋„ท



Nombre de la red: Scroll L1 TestnetRPC์˜ ์ƒˆ ๋ฐฉํ–ฅ URL: https://prealpha.scroll.io/l1์นด๋ฐ๋‚˜ ์‹๋ณ„์ž: 534351Sรญmbolo de moneda: TSETHDirecciรณn URL del explorador de bloques: https://l1scan.scroll.io/

๋ ˆ์ด์–ด 2 ํ…Œ์ŠคํŠธ๋„ท



Nombre de la red: Scroll L2 TestnetRPC์˜ ์ƒˆ ๋ฐฉํ–ฅ URL: https://prealpha.scroll.io/l2์นด๋ฐ๋‚˜ ์‹๋ณ„์ž: 534354Sรญmbolo de moneda: TSETHDirecciรณn URL del explorador de bloques: https://l2scan.scroll.io/

2. Fondos desde el ์ˆ˜๋„๊ผญ์ง€ ๊ฐ€์ ธ์˜ค๊ธฐ



์˜ค๋ธŒํ…TSETH ๋ฐ์Šค๋ฐ์—˜faucet . Y envรญa fondos de L1 a L2 a travรฉs del bridge .

3. ๋ž€์ž ์šฐ๋‚˜ ๋Œ‘


ใ…. ์—˜ ์Šค๋งˆํŠธ ๊ณ„์•ฝ



์Šค๋งˆํŠธ ๊ณ„์•ฝ์€ ์Šค๋งˆํŠธ ๊ณ„์•ฝRemix, ์Šคํฌ๋กค L2์—์„œ Metamask๋กœ ๋ถ„๋ฅ˜๋ฉ๋‹ˆ๋‹ค.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

contract HelloWorld {
    string public hello = "Hola mundo!";

    function setHello(string memory hello_) public
    {
        hello = hello_;
    }
}


๋น„. ์—˜ HTML



Ahora en una carpeta nueva crea el archivo 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="web3_message"></p>
  <p id="contract_state"></p>
  <h1>Hola Mundo! DApp</h1>
  <p id="hello"></p>
  <input type="input"  value="" id="hello_"></input>
  <input type="button" value="Set Hello" onclick="_setHello()"></input>
  <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>


์”จ. ์—˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ



En la misma carpeta tambiรฉn agrega el archivo Javascript. Observa que estamos usando el id de red534354 . Y recuerda establecer la variable HELLO_WORLD_CONTRACT_ADDRESS con tu address.
blockchain_stuff.js
const NETWORK_ID = 534354
const HELLO_WORLD_CONTRACT_ADDRESS = "ADDRESS DE TU CONTRATO AQUI"
const HELLO_WORLD_ABI_PATH = "./HelloWorld.json"

var helloWorldContract
var accounts
var web3

function metamaskReloadCallback() {
  window.ethereum.on('accountsChanged', (accounts) => {
    document.getElementById("web3_message").textContent="Account changed, refreshing...";
    window.location.reload()
  })
  window.ethereum.on('networkChanged', (accounts) => {
    document.getElementById("web3_message").textContent="Network changed, refreshing...";
    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: Please connect to 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 () {
          helloWorldContract = await getContract(web3, HELLO_WORLD_CONTRACT_ADDRESS, HELLO_WORLD_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()
            } else
            {
              document.getElementById("connect_button").style.display = "block"
            }
          });
        };
        awaitContract();
      } else {
        document.getElementById("web3_message").textContent="Please connect to Arbitrum 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 helloWorldContract.methods.hello().call()
  document.getElementById("hello").textContent = hello;
}

const onWalletConnectedCallback = async () => {
}

//// Functions ////

const setHello = async (hello_) => {
  const result = await helloWorldContract.methods.setHello(hello_)
  .send({ from: accounts[0], gas: 0, value: 0 })
  .on('transactionHash', function(hash){
    document.getElementById("web3_message").textContent="Executing...";
  })
  .on('receipt', function(receipt){
    document.getElementById("web3_message").textContent="Success.";    })
  .catch((revertReason) => {
    console.log("ERROR! Transaction reverted: " + revertReason.receipt.transactionHash)
  });
}


๋””. ์—˜ JSON ABI



๋งˆ์ง€๋ง‰์œผ๋กœ JSON ABI๋ฅผ ํ†ตํ•ฉํ•˜์—ฌ ๋ณด๊ด€ํ•ฉ๋‹ˆ๋‹ค.
HelloWorld.json
[
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "hello_",
        "type": "string"
      }
    ],
    "name": "setHello",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "hello",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  }
]


4. Interactua con el sitio ์›น




npm install -g lite-server
lite-server


DApp๊ณผ ์ƒํ˜ธ ์ž‘์šฉํ•˜๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋‹ค์šด๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹คlocalhost:3000.

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ