Aprende a enviar bitcoin desde tu Billetera con tu propia app creada en React [Next.js]

Tecnología
  
Programación Web
  
Nodejs
  
Javascript
  
Desarrollo Web
  
React
    02 Marzo, 2021   Regresar el blog
Compartir:

[ENG-ESP] Learn how send bitcoin from your wallet with your own app created in React [Next.js] - Aprende a enviar bitcoin desde tu Billetera con tu propia app creada en React [Next.js]

To start this tutorial it is necessary to know some basic concepts

Para empezar este tutorial es necesario conocer algunos conceptos básicos

What is a blockchain?

First off, let’s define two key terms you’ll notice throughout this tutorial: the blockchain and a bitcoin transaction. The blockchain can be described as an immutable distributed database of a global log of transactions. A block in the blockchain can be likened to a record in traditional databases.

What is a bitcoin transaction?

A transaction is the transfer of value from one bitcoin wallet to another that gets included in the blockchain.

¿Qué es la blockchain?

En primer lugar, definamos dos términos clave que notará a lo largo de este tutorial: la blockchain(cadena de bloques) y una transacción de bitcoin. La cadena de bloques se puede describir como una base de datos distribuida inmutable de un registro global de transacciones. Un bloque en la cadena de bloques se puede comparar con un registro en bases de datos tradicionales.

¿Qué es una transacción de bitcoin?

Una transacción es la transferencia de valor de una billetera bitcoin a otra que se incluye en la blockchain.

Here’s a simple workflow diagram of the entire bitcoin transaction process.

Aquí hay un diagrama de flujo resumido de todo el proceso de transacción de bitcoin.

For this tutorial we are going to work with a test cryptocurrency called Testnet Bitcoin, for this we must first create a wallet and add some bitcoins to it. A testnet cryptocurrency wallet can be created on this website https://walletgenerator.net/?culture=en¤cy=testnet% 20 bitcoins Remember to save the public and private address that we will use later. Now to add funds we go to this website https://testnet-faucet.mempool.co/ and put our previously generated address.
Para este tutorial vamos a trabajar con una criptomoneda de pruebas llamada Testnet Bitcoin, para ello primero debemos crearnos una billetera y agregarle algunos bitcoins. en esta página web pueden crearse una billetera de la criptomoneda testnet https://walletgenerator.net/?culture=en¤cy=testnet%20bitcoin

Recuerda guardar la dirección pública y privada que lo usaremos después.

Ahora para agregarle fondos nos vamos hacia esta web https://testnet-faucet.mempool.co/ y colocamos nuestra dirección previamente generada.

We’ll use the SoChain API to connect to the Testnet blockchain Usaremos la API de SoChain para conectarnos a la blockchain de Testnet.

We start a node project and install the following modules:

Iniciamos un proyecto de node e instalamos los siguientes modulos:

npm init --yes
npm i react react-dom next

In the package.json file we must make sure we have the following lines:
En el archivo package.json debemos asegurarnos tener las siguientes líneas:
{"scripts":{
"dev": "next",
"build": "next build",
"start": "next start"
}
}

Install the Bitcore open-source library — we’ll use the Bitcore library and Axios to interface with the blockchain.
Instale la biblioteca de código abierto Bitcore; usaremos la biblioteca Bitcore y Axios para interactuar con la cadena de bloques.

npm i bitcore-lib axios

For this example we will use materialize as a css framework
Para este ejemplo usaremos como framework de css materialize

npm i materialize-css

FINAL CODE -

Components [Componentes]

components/Navigation.js
import Link from "next/link";
const Navigation = () => {
  return (
    <nav className="orange accent-3">
      <div className="nav-wrapper container">
        <Link href="/">
          <a className="brand-logo left">LOGO</a>
        </Link>
        <ul id="nav-mobile" className="right ">
          <li>
            <Link href="/contact">
            <a className="waves-effect waves-light btn blue darken-3">Contact <i className="material-icons right">info</i></a>
            </Link>
          </li>
        </ul>
      </div>
    </nav>
  );
};
export default Navigation;


components/Layout.js
import Navigation from "./Navigation";
import Footer from "./Footer";
import Head from "next/head";
const Layout = ({ children }) => {
  return (
    <>
      <Head>
        <link
          href="https://fonts.googleapis.com/icon?family=Material+Icons"
          rel="stylesheet"
        />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
      </Head>
      <Navigation />
       <div className=" main container ">{children}</div>
      <Footer/>
    </>
  );
};
export default Layout;


components/Form.js
import bitcore from ´bitcore-lib´
import axios from "axios";
import { useState } from "react";
const Form = () => {
  const [msg, setMsg] = useState({});
  const [loader, setLoader] = useState(false);
  const sendBitcoin = async (recieverAddress, amountToSend) => {
    setLoader(true);
    const sochain_network = "BTCTEST";
    const wif = "92abuK6TVxXfTyGYiDwRXrMt6gRhBGNhr3MpcvbbnR2wFD6vBwP";
    var privateKey = new bitcore.PrivateKey(wif);
    var sourceAddress = "mxMVDvpzsSAMEPBnewz5VQHGSHWwJKPZPC";
    const satoshiToSend = amountToSend * 100000000;
    let fee = 0;
    let inputCount = 0;
    let outputCount = 2;
    try {
      const utxos = await axios.get(
        `https://sochain.com/api/v2/get_tx_unspent/${sochain_network}/${sourceAddress}`
      );
      const transaction = new bitcore.Transaction();
      let totalAmountAvailable = 0;
      let inputs = [];
      utxos.data.data.txs.forEach(async (element) => {
        let utxo = {};
        utxo.satoshis = Math.floor(Number(element.value) * 100000000);
        utxo.script = element.script_hex;
        utxo.address = utxos.data.data.address;
        utxo.txId = element.txid;
        utxo.outputIndex = element.output_no;
        totalAmountAvailable += utxo.satoshis;
        inputCount += 1;
        inputs.push(utxo);
      });
      let transactionSize =
        inputCount * 146 + outputCount * 34 + 10 - inputCount;
      // Check if we have enough funds to cover the transaction and the fees assuming we want to pay 20 satoshis per byte
      fee = transactionSize * 20;
      if (totalAmountAvailable - satoshiToSend - fee < 0) {
        throw new Error("Balance is too low for this transaction");
      }
      //Set transaction input
      transaction.from(inputs);
      // set the recieving address and the amount to send
      transaction.to(recieverAddress, satoshiToSend);
      // Set change address - Address to receive the left over funds after transfer
      transaction.change(sourceAddress);
      //manually set transaction fees: 20 satoshis per byte
      transaction.fee(fee * 20);
      // Sign transaction with your private key
      transaction.sign(privateKey.toString());
      // serialize Transactions
      const serializedTX = transaction.serialize();
      // Send transaction
      const result = await axios({
        method: "POST",
        url: `https://sochain.com/api/v2/send_tx/${sochain_network}`,
        data: {
          tx_hex: serializedTX,
        },
        headers: {
            "Content-Type": "application/x-www-form-urlencoded"
        }
      });
      setLoader(false);
      setMsg({success: 1, data:result.data});
    } catch (error) {
      setLoader(false);
      setMsg({ success: 0, data: `Error: ${error.message}` });
    }
  };
  const handleSubmit = async (e) => {
    e.preventDefault();
    await sendBitcoin(
      e.target.recieverAddress.value,
      e.target.amountToSend.value
    );
  };
  return (
    <>
      <div className="row">
        <form className="col s12" onSubmit={handleSubmit}>
          <div className="row">
            <div className="input-field col m6 s12">
              <i className="material-icons prefix">address</i>
              <input
                name="recieverAddress"
                id="recieverAddress"
                type="text"
                className="validate"
              />
              <label htmlFor="recieverAddress">BTC Address to receive</label>
            </div>
            <div className="input-field col m6 s12">
              <i className="material-icons prefix">B</i>
              <input
                name="amountToSend"
                id="amountToSend"
                type="number"
                step=".00001"
                className="validate"
              />
              <label htmlFor="amountToSend">Amount to send BTC</label>
            </div>
            <button className="btn waves-effect waves-light">
              SEND BTC
              <i className="material-icons right">send</i>
            </button>
          </div>
        </form>
      </div>
      <div style={{ paddingTop: "10px" }}>
        {loader ? (
          <div className="progress">
            <div className="indeterminate"></div>
          </div>
        ) : msg.success === 0 ? (
          <h5 className="card-panel red darken-1"><code><pre>{msg.data}</pre></code></h5>
        ) : msg.success === 1 ? (
          <>
            <div>Message:</div>
            <h5 className="card-panel green darken-1">
                <code><pre>{msg.data.txid}</pre></code>
            </h5>
          </>
        ) : (
          ""
        )}
      </div>
    </>
  );
};
export default Form;


PAGES / ROUTES [Paginas/RUTAS]

pages/_app.js
import "materialize-css/dist/css/materialize.min.css";
import ´../custom.css´
// This default export is required in a new `pages/_app.js` file.
export default function MyApp({ Component, pageProps }) {
    return <Component {...pageProps} />
  }


pages/index.js
import Layout from "../components/Layout";
import Head from "next/head";
import Form from "../components/Form";
const index = ({ balance }) => {
  return (
    <>
      <Head>
        <title>APP | Home</title>
      </Head>
      <Layout>
        <h4>Learn how send bitcoin from your wallet with React [Next.js]</h4>
        <ul>
          <li>
            My Test BTC Address: <code>mxMVDvpzsSAMEPBnewz5VQHGSHWwJKPZPC</code>
            <a target="_blank" href="https://walletgenerator.net/?currency=Testnet%20Bitcoin">
              Click here to obtein a btc test address
              <i className="material-icons">link</i>
            </a>
          </li>
          <li>Balance BTC: <code>{balance}</code></li>
        </ul>
        <div style={{ textAlign: "center", paddingTop: "20px" }}>
          <Form />
        </div>
      </Layout>
    </>
  );
};
index.getInitialProps = async (ctx) => {
  const sochain_network = "BTCTEST";
  const sourceAddress = "mxMVDvpzsSAMEPBnewz5VQHGSHWwJKPZPC";
  const utxosResult = await fetch(
    `https://sochain.com/api/v2/get_tx_unspent/${sochain_network}/${sourceAddress}`
  );
  const utxos = await utxosResult.json();
  let totalAmountAvailable = 0;
  utxos.data.txs.forEach(async (element) => {
    totalAmountAvailable += Number(element.value);
  });
  return { balance: totalAmountAvailable };
};
export default index;


SCREENSHOT

To see this example live and make test transacctions, click on the link https://bitcoin-send-react-app.herokuapp.com/
Para ver este ejemplo en vivo y hacer transacciones de prueba, click en el enlace https://bitcoin-send-react-app.herokuapp.com/

And with those friends we reached the end of the tutorial, I hope you enjoyed it and until next time!
Y con esos amigos llegamos al final del tutorial, espero que lo hayan disfrutado y ¡hasta la próxima!

258 vistas
Compartir:


Autor
Jose Fuentes

- Web Developer -

 


0 COMENTARIO(S)
Contesta
Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *
Comentario *
Nombre *
Correo electrónico *
Sitio web

Articulos Relacionados
Articulos recientes

Desarrollos en venta

$ usd dólar 600