¡Ahorremos gas en Layer 2! - [Desarrollo en Arbitrum]
Ahmed Castro
Posted on July 12, 2022
Arbitrum es la Layer 2 mas utilizada hoy y una de mis favoritas por su simplicidad, seguridad y capacidad de ahorrar gas. En este video revisaremos los pasos a seguir para desarrollar aplicaciones decentralizadas en un optimistic Rollup.
https://www.youtube.com/watch?v=wNkyLMTgJW0
Antes de comenzar
Para este tutorial ocuparás NodeJs que recomiendo descargarlo en Linux via NVM, y también necesitarás Metamask u otra wallet compatible.
1. Agrega a Arbitrum en tu Metamask
En este video lanzaremos en Arbitrum Testnet pero les explico cómo hacerlo en Mainnet si es de su interés.
Arbitrum Mainnet
- Network Name:
Arbitrum One
- New RPC URL
https://arb1.arbitrum.io/rpc
- Chain ID:
42161
- Currency Symbol:
AETH
- Block Explorer URL:
https://arbiscan.io/
Arbitrum Testnet
- Network Name:
Arbitrum Testnet
- New RPC URL
https://rinkeby.arbitrum.io/rpc
- Chain ID:
421611
- Currency Symbol:
AETH
- Block Explorer URL:
https://testnet.arbiscan.io/
2. Obtén fondos en Layer 2
Sigue los siguientes pasos para obtener fondos en Arbitrum Testnet:
- Habilita los testnets en tu Metamask
- Obtén Rinkeby ETH desde un Faucet.
- Usa El Bridge para enviar los fondos desde L1 a L2.
3. Crea una DApp
El Smart Contract
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
contract Hello
{
string public hello = "Hola mundo!";
function setHello(string memory _hello) public
{
hello = _hello;
}
}
El 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>
El Javascript
blockchain_stuff.js
const NETWORK_ID = 421611
const MY_CONTRACT_ADDRESS = "0xADDRESSDELCONTRATOAQUÍ"
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 Rinkeby";
}
});
};
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: 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)
});
}
El JSON ABI
Crea el archivo ./json_abi/MyContract.json
y coloca dentro el ABI genereado por Remix o por el compilador que estés usando.
4. Ahora estamos listos para probar la Dapp
Primero instalamos un servidor web.
npm install -g lite-server
Ahora lo levantamos.
lite-server
El resultado se encuentra en tu browser en http://localhost:3000.
Gracias por ver este tutorial!
Sígannos en dev.to y en Youtube para todo lo relacionado al desarrollo en Blockchain en Español.
Posted on July 12, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.