Posts

[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]

avatar of @jfdesousa7
25
@jfdesousa7
·
0 views
·
6 min read

[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&currency=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&currency=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!


Visit my official website for budges and much more

TupaginaOnline.net

Visite mi sitio web oficial para presupuestos y mucho más

TupaginaOnline.net

Colaboration with the help of Eze Sunday