본문 바로가기
  • 개발 / 공부 / 일상
BlockChain

(BlockChain) MetaMask axios 통신

by JJeongHyun 2023. 2. 9.
반응형

request 방식 정의

const request = axios.create({
  method: "POST",
  baseURL: "http://localhost:8080",
  // metamask 네트워크에 설정한 주소와 port 번호
  header: {
    "content-type": "application/json",
  },
});

 

계정 생성

request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "personal_newAccount",
      params: [e.target["new-pw"].value],
      // 계정 생성하면서 설정할 비밀번호 입력할 input창의 value
    },
  });

 

지갑정보 보기

  • 계정들 중 클릭 한 계정 정보 보기
<ul id="wallet-list"></ul>
const walletListElem = document.getElementById("wallet-list");

sync function getAccounts() {
  const {
    data: { result },
  } = await request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "eth_accounts",
    },
  });
  walletListElem.innerHTML = "";
  result.forEach((item) => {
    walletListElem.innerHTML += `<li onclick="getWallet('${item}')">${item}</li>`;
  });
  accounts = result;
}

 

해당 계정의 잔액 조회

<h2>잔액 : <span id="balance"></span>ETH</h2>
const balanceElem = document.getElementById("balance");

async function getBalance(_account) {
  const {
    data: { result },
  } = await request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "eth_getBalance",
      params: [_account, "latest"],
    },
  });
  balanceElem.innerHTML =
    parseInt(parseInt(result, 16) / Math.pow(10, 15)) / 1000;
}
balance가 16진수로 표현되기 때문에 10진수로 바꿔주고 ethereum 단위전환 후 3번째 소수점까지 표기

 

채굴 시작하기

  • 채굴을 하기 전에 setEthereum를 설정해 주고 채굴을 시작
  • 아무 계정도 설정하지 않았는데 채굴을 시작하면 안됨으로 해당 부분에 대한 예외처리
  • 채굴하는 과정을 브라우저에서 확인할 수 있도록 2초마다 interval 함수를 통해 잔액을 조회한다
<h1>현재 지갑 : <span id="account"></span></h1>
<h2>잔액 : <span id="balance"></span>ETH</h2>
<button id="start">채굴 시작</button>
const accountElem = document.getElementById("account");

if (accountElem.innerHTML === "") return;
  await request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "miner_setEtherbase",
      params: [accountElem.innerHTML],
    },
  });
  await request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "miner_start",
      params: [],
    },
  });
  interval = setInterval(() => {
    getBalance(accountElem.innerHTML);
  }, 2000);

 

채굴 중지하기

<h1>현재 지갑 : <span id="account"></span></h1>
<h2>잔액 : <span id="balance"></span>ETH</h2>
<button id="stop">채굴 중지</button>
request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "miner_stop",
      params: [],
    },
  });
  clearInterval(interval);
  interval = undefined;

 

트랜잭션 전송 ( 이더 보내기 )

  • 보내기 전에 보낼 계정의 잠금을 풀어준다
  • 이 후 form태그 내의 value는 이전에 잔액 표기 방법을 다시 역변환을 해주어서 16진수로 바꿔주고 마지막으로 이더리움 서버에서 16진수임을 알 수 있게 '0x'를 앞에 더 해준다
<form id="transaction">
      <input
        type="password"
        id="tran-pw"
        placeholder="Password"
        pattern="[A-Za-z0-9]+"
      />
      <input
        type="text"
        id="transaction-account"
        placeholder="0xCB8775C5943Dc32ed8C1A8182Ce9A53E5b87383a"
      />
      <select id="select-account"></select>
      <input type="number" id="ether" placeholder="Ether" step="0.001" />
      <button>이더 보내기</button>
</form>
document.forms["transaction"].onsubmit = async (e) => {
  e.preventDefault();
  let to = selectElem.value;
  if (e.target["transaction-account"].value)
    to = e.target["transaction-account"].value;
  await request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "personal_unlockAccount",
      params: [accountElem.innerHTML, e.target["tran-pw"].value],
    },
  });

  await request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "eth_sendTransaction",
      params: [
        {
          from: accountElem.innerHTML,
          to,
          value:
            "0x" + (+e.target["ether"].value * Math.pow(10, 18)).toString(16),
        },
      ],
    },
  });
};

 

metamask 내 계정 이더 확인하기

<form id="form-meta">
      <input type="text" id="meta" placeholder="meta account 확인" />
      <button>계정 이더 확인</button>
    </form>
document.forms["form-meta"].onsubmit = (e) => {
  e.preventDefault();
  getWallet(e.target["meta"].value);
};

 

 

전체 코드

<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <style>
      input,
      select {
        display: block;
        margin: 0.5rem;
      }
      #transaction {
        border: 1px solid black;
        width: fit-content;
        padding: 10px;
        margin: 5px;
      }
    </style>
  </head>
  <body>
    <h1>현재 지갑 : <span id="account"></span></h1>
    <h2>잔액 : <span id="balance"></span>ETH</h2>
    <button id="start">채굴 시작</button>
    <button id="stop">채굴 중지</button>
    <form id="form-meta">
      <input type="text" id="meta" placeholder="meta account 확인" />
      <button>계정 이더 확인</button>
    </form>
    <form id="transaction">
      <input
        type="password"
        id="tran-pw"
        placeholder="Password"
        pattern="[A-Za-z0-9]+"
      />
      <input
        type="text"
        id="transaction-account"
        placeholder="0xCB8775C5943Dc32ed8C1A8182Ce9A53E5b87383a"
      />
      <select id="select-account"></select>
      <input type="number" id="ether" placeholder="Ether" step="0.001" />
      <button>이더 보내기</button>
    </form>
    <form id="new-wallet">
      <input
        type="password"
        id="new-pw"
        placeholder="Password"
        pattern="[A-Za-z0-9]+"
      />
      <button id="new-wallet-btn">계정 생성</button>
    </form>
    <ul id="wallet-list"></ul>
    <script src="./index.js"></script>
  </body>
</html>
const request = axios.create({
  method: "POST",
  baseURL: "http://localhost:8080",
  header: {
    "content-type": "application/json",
  },
});

const walletListElem = document.getElementById("wallet-list");
const accountElem = document.getElementById("account");
const balanceElem = document.getElementById("balance");
const startBtn = document.getElementById("start");
const stopBtn = document.getElementById("stop");
const selectElem = document.getElementById("select-account");

let isCreating = false;
let interval;
let accounts = [];

async function mineStop() {
  await request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "miner_stop",
      params: [],
    },
  });
  clearInterval(interval);
  interval = undefined;
}

async function getBalance(_account) {
  const {
    data: { result },
  } = await request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "eth_getBalance",
      params: [_account, "latest"],
    },
  });
  balanceElem.innerHTML =
    parseInt(parseInt(result, 16) / Math.pow(10, 15)) / 1000;
}

async function getWallet(_account) {
  if (interval) mineStop();
  //   if (interval !== undefined) mineStop();
  accountElem.innerHTML = _account;

  await getBalance(_account);
  selectElem.innerHTML = "";
  accounts.forEach((item) => {
    if (item !== _account)
      selectElem.innerHTML += `<option value="${item}">${item}</option>`;
  });
}

async function getAccounts() {
  const {
    data: { result },
  } = await request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "eth_accounts",
    },
  });
  walletListElem.innerHTML = "";
  result.forEach((item) => {
    walletListElem.innerHTML += `<li onclick="getWallet('${item}')">${item}</li>`;
  });
  accounts = result;
}
getAccounts();
mineStop();

document.forms["new-wallet"].onsubmit = async (e) => {
  e.preventDefault();
  if (e.target["new-pw"].value.length < 5 || isCreating) return;
  isCreating = true;
  await request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "personal_newAccount",
      params: [e.target["new-pw"].value],
      // 계정 생성하면서 설정할 비밀번호 입력할 input창의 value
    },
  });
  await getAccounts();
  e.target["new-pw"].value = "";
  isCreating = false;
};

startBtn.onclick = async () => {
  if (accountElem.innerHTML === "") return;
  await request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "miner_setEtherbase",
      params: [accountElem.innerHTML],
    },
  });
  await request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "miner_start",
      params: [],
    },
  });
  interval = setInterval(() => {
    getBalance(accountElem.innerHTML);
  }, 2000);
};
stopBtn.onclick = mineStop;

document.forms["transaction"].onsubmit = async (e) => {
  e.preventDefault();
  let to = selectElem.value;
  if (e.target["transaction-account"].value)
    to = e.target["transaction-account"].value;
  await request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "personal_unlockAccount",
      params: [accountElem.innerHTML, e.target["tran-pw"].value],
    },
  });

  await request({
    data: {
      id: 50,
      jsonrpc: "2.0",
      method: "eth_sendTransaction",
      params: [
        {
          from: accountElem.innerHTML,
          to,
          value:
            "0x" + (+e.target["ether"].value * Math.pow(10, 18)).toString(16),
        },
      ],
    },
  });
};

document.forms["form-meta"].onsubmit = (e) => {
  e.preventDefault();
  getWallet(e.target["meta"].value);
};

'BlockChain' 카테고리의 다른 글

(BlockChain) Web3  (0) 2023.02.13
(BlockChain) Ganache  (0) 2023.02.10
(BlockChain) MetaMask  (0) 2023.02.09
(BlockChain) RPC  (0) 2023.02.09
(BlockChain) IPC  (0) 2023.02.09