[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 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.
For this example we will use materialize as a css framework
Para este ejemplo usaremos como framework de css materialize
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;
fee = transactionSize * 20;
if (totalAmountAvailable - satoshiToSend - fee < 0) {
throw new Error("Balance is too low for this transaction");
}
transaction.from(inputs);
transaction.to(recieverAddress, satoshiToSend);
transaction.change(sourceAddress);
transaction.fee(fee * 20);
transaction.sign(privateKey.toString());
const serializedTX = transaction.serialize();
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'
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
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