bitcore-lib를 이용한 비트코인 전송하기

Bobby·2023년 5월 8일
0


🪙 라이브러리 추가

# 초기화
yarn init

# bitcore-lib 설치
yarn add bitcore-lib 

# axios 설치
yarn add axios

🪙 지갑 생성하기

생성

  • 비트코인의 메인넷과 테스트넷은 주소 생성 방식이 다르므로 주소 생성시 어떤 네트워크를 사용할 지 선택해야 한다.

wallet.js

const bitcore = require("bitcore-lib");
const { testnet } = require("bitcore-lib/lib/networks");

const createWallet = () => {
  const privateKey = new bitcore.PrivateKey();
  const address = privateKey.toAddress(testnet); // 네트워크 선택 (기본값은 메인넷)
  return {
    privateKey: privateKey.toString(),
    address: address.toString(),
  };
};

module.exports = {
  createWallet: createWallet,
};

실행

app.js

const { createWallet } = require("./wallet");

const start = async () => {
  const wallet = createWallet();
  console.log(wallet);
};

start();
node app.js
  • 결과
{
  privateKey: 'a0e2b014317b443f5fb1708b4193e9be4d9223013ca0ca729ebf0decf476bd91',
  address: 'mwRoSmns2iWowMmsYAxwDukyTgaDx3qvGj'
}

🪙 지갑 잔액 조회

테스트넷 코인 받기

테스트넷 explorer

잔액 조회

wallet.js

const axios = require("axios");
const bitcore = require("bitcore-lib");
const { testnet } = require("bitcore-lib/lib/networks");

...

// 비트코인 주소가 맞는지 확인
const validWalletAddress = async (address) => {
  return bitcore.Address.isValid(address, testnet); // 네트워크 testnet
};

const getBalance = async (address) => {
  const isValid = await validWalletAddress(address);

  if (!isValid) {
    return "invalid address";
  }

  const url = `https://api.blockcypher.com/v1/btc/test3/addrs/${address}/balance`;
  const balance = await axios.get(url);

  return balance.data.balance;
};

module.exports = {
  createWallet: createWallet,
  getBalance: getBalance,
};

실행

app.js

const { getBalance } = require("./wallet");

const start = async () => {
  const balance = await getBalance("mwRoSmns2iWowMmsYAxwDukyTgaDx3qvGj");
  console.log("wallet balance : ", balance);
};

start();
node app.js
  • 결과(단위는 사토시)

🪙 코인 전송하기

토큰발급

전송

  • 비트코인을 전송하기 위해서는 UTXO를 선택해야 하는데 blockcypher api를 통해 쉽게 트랜잭션을 생성 할 수 있다.
  • 새 트랜잭션을 생성 한 후에 각 input값에 대해서 서명을 해야한다.
  • 각 input 마다 서명한 데이터를 tosign 배열에 담아서 트랜잭션 데이터를 생성한다.
const axios = require("axios");
const bitcore = require("bitcore-lib");
const { testnet } = require("bitcore-lib/lib/networks");

...

const send = async (to, value) => {
  const privateKey = new bitcore.PrivateKey(
    "a0e2b014317b443f5fb1708b4193e9be4d9223013ca0ca729ebf0decf476bd91"
  );

  const apiToken = {token};

  // input, output 지정
  let newtx = {
    inputs: [{ addresses: ["mwRoSmns2iWowMmsYAxwDukyTgaDx3qvGj"] }],
    outputs: [{ addresses: [to], value: value }],
  };

  // 새로운 트랜잭션 생성
  const newTxData = await axios.post(
    `https://api.blockcypher.com/v1/btc/test3/txs/new`,
    JSON.stringify(newtx)
  );

  // 트랜잭션 서명
  const tmptx = newTxData.data;
  tmptx.pubkeys = [];
  
  tmptx.signatures = tmptx.tosign.map((sign, n) => {
    const pubkey = privateKey.toPublicKey().toString("hex");
    tmptx.pubkeys.push(pubkey);
    
    // private key를 가지고 서명 
    const signature = bitcore.crypto.ECDSA.sign(
      Buffer.from(sign, "hex"),
      privateKey,
      "big"
    ).toString("hex");
    return signature;
  });

  // 전송
  axios
    .post(
      `https://api.blockcypher.com/v1/btc/test3/txs/send?token=${apiToken}`,
      JSON.stringify(tmptx)
    )
    .then((finaltx) => {
      console.log(finaltx.data);
    })
    .catch((err) => {
      console.log(err);
    });
};

module.exports = {
  createWallet: createWallet,
  getBalance: getBalance,
  send: send,
};

실행

app.js

const { send } = require("./wallet");

const start = async () => {
  send("mogiyYzT98HWbXW4bDhpDg5VJBtWDBLUgS", 100000);
};

start();
node app.js
  • 결과
  • 트랜잭션 생성이 완료 되고 수수료 16800 사토시 소모


코드

profile
물흐르듯 개발하다 대박나기

0개의 댓글