[TIL] 23.03.27

bpark14·2023년 3월 27일
0

WEEK 3

목록 보기
1/5

키와 주소

키는 코인에 대한 소유권을 입증시켜주는 수단이다.개인키(private key) 와 공개키(public key) 가 쌍을 이루며 개인키로 부터 공개키가 형성된다. 하지만 공개키를 통하여 개인키가 역추적될 수는 없다. (일방향성)

주소

여기서의 주소는 Bitcoin Address 를 의미한다. 주소는 공개키로부터 형성된다. 이 역시 주소로 공개키를 역추적할 수는 없다. (일방향성)

키와 주소 그리고 거래

개인키와 공개키는 각각 서명과 주소를 생성한다. 거래를 할 때에는 서명과 주소가 항상 사용된다.
개인키로 생성된 서명은 내가 보유한 코인을 소비할 때, 사용되고 공개키로 서명된 주소는 내가
누군가에게 코인을 보내거나 누군가에게 보내야할 때 사용된다.

개인키와 공개키

개인키

개인키는 통장의 PIN 번호 , 비밀번호와 같다. 공개되어서는 안되고 오직 나만 알고 있어야 한다. Not your key, not your coin. 소유한 코인을 소비할 때 사용되고 만약에 잃어버렸다면 코인을 모두 잃어버린 것이다.

  • 무작위로 선정된 숫자이다
  • 서명을 할 때 사용된다
  • 공개키를 생성하는 재료
  • 화폐의 소유권을 결정하는 요소이다
  • 보통 4비트씩 64개의 진수로 표현된다

공개키

공개키는 통장의 통장번호와 같다. 공개되어도 상관이 없는 정보이다. 오히려 공개가 되어야 다른 사람이 나에게 전송을 해줄 수 있다. 주로 전송을 주거나 받을 때 사용된다. 엄연히 얘기하면 주소는 공개키가 아닌 공개키로부터 형성된 비트코인 주소이다.

  • K = k * G (G : 생성포인트)
  • 타원곡선 암호법 사용
  • k 를 출발점으로 해서 미리 정해진 G 값을 곱한다
  • 일방향성이기에 K 로 k 추적 절대 불가능
  • 점의 좌표이기에 x, y 값의 쌍으로 이루어져 있다

단방향성

  • 단방향성은 문자 그대로 한 방향으로만 계산이 가능하다는 것을 의미한다. 개인키에서 공개키가 생성되고 공개키에서 비트코인 주소가 생성된다. 하지만 공개키를 통해서 개인키를 비트코인 주소를 통해서 공개키를 역추적할 수는 없다.
  • 역추적 불가능함이라는 특징 덕분에, 비트코인 주소를 공개해도 문제가 되지 않는 것이다. 만약 일방향성이 아니어서 역추적이 가능했다면 비트코인 주소를 통해 개인키가 유출될 수 있게 되고 모든 자산을 잃게 된다.
  • 그렇기에, 단방향성은 키와 주소 생성에 있어서 가장 중요한 암호학적 특징중 하나이다.

비트코인 주소

용도

비트코인 주소는 거래를 할 때, 주로 사용된다. 주소를 알려주어야만 거래가 진행가능하다. 공유가 되어도 크게 문제가 되지 않는다. 개인키에서 공개키가 그리고 공개키에서 비트코인 주소가 생성된다. 이 모든 과정은 일방향성이기 때문에, 비트코인 주소를 통해 개인키로 역추적하는 것은 사실상 불가능하다.

홈페이지 만들기 진행상황

index.html

<!DOCTYPE html>
<html lang="en">
  <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>
    <link rel="stylesheet" />
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <main>
      <div class="time">Time</div>
      <div class="quotes">
        <div class="quotesMsg">Quotes</div>
        <button class="quotesAddBtn" onclick="onClickAdd()">
          새 명언 추가하기
        </button>
      </div>
      <div class="newQuotes">
        <input class="newQuotesInput" type="text" />
        <button class="newQuotesButton" onclick="onClickRegist()">등 록</button>
      </div>
      <div class="search">
        <div class="searchTitle">
          <svg
            class="searchLogo"
            xmlns="http://www.w3.org/2000/svg"
            width="671.194"
            height="680.2487"
            viewBox="0 0 671.194 680.2487"
          >
            <path
              d="M626.9464,278.4037a169.4492,169.4492,0,0,0-14.5642-139.187A171.3828,171.3828,0,0,0,427.7883,56.9841,169.45,169.45,0,0,0,299.9746.0034,171.3985,171.3985,0,0,0,136.4751,118.6719,169.5077,169.5077,0,0,0,23.1574,200.8775,171.41,171.41,0,0,0,44.2385,401.845,169.4564,169.4564,0,0,0,58.8021,541.0325a171.4,171.4,0,0,0,184.5945,82.2318A169.4474,169.4474,0,0,0,371.21,680.2454,171.4,171.4,0,0,0,534.7642,561.51a169.504,169.504,0,0,0,113.3175-82.2063,171.4116,171.4116,0,0,0-21.1353-200.9ZM371.2647,635.7758a127.1077,127.1077,0,0,1-81.6027-29.5024c1.0323-.5629,2.8435-1.556,4.0237-2.2788L429.13,525.7575a22.0226,22.0226,0,0,0,11.1306-19.27V315.5368l57.25,33.0567a2.0332,2.0332,0,0,1,1.1122,1.568V508.2972A127.64,127.64,0,0,1,371.2647,635.7758ZM97.3705,518.7985a127.0536,127.0536,0,0,1-15.2074-85.4256c1.0057.6037,2.7624,1.6768,4.0231,2.4012L221.63,514.01a22.04,22.04,0,0,0,22.2492,0L409.243,418.5281v66.1134a2.0529,2.0529,0,0,1-.818,1.7568l-136.92,79.0534a127.6145,127.6145,0,0,1-174.134-46.6532ZM61.7391,223.1114a127.0146,127.0146,0,0,1,66.3545-55.8944c0,1.1667-.067,3.2329-.067,4.6665V328.3561a22.0038,22.0038,0,0,0,11.1173,19.2578l165.3629,95.4695-57.2481,33.055a2.0549,2.0549,0,0,1-1.9319.1752l-136.933-79.1215A127.6139,127.6139,0,0,1,61.7391,223.1114ZM532.0959,332.5668,366.7308,237.0854l57.25-33.0431a2.0455,2.0455,0,0,1,1.93-.1735l136.934,79.0535a127.5047,127.5047,0,0,1-19.7,230.055V351.8247a21.9961,21.9961,0,0,0-11.0489-19.2579Zm56.9793-85.7589c-1.0051-.6174-2.7618-1.6769-4.0219-2.4L449.6072,166.1712a22.07,22.07,0,0,0-22.2475,0L261.9963,261.6543V195.5409a2.0529,2.0529,0,0,1,.818-1.7567l136.9205-78.988a127.4923,127.4923,0,0,1,189.34,132.0117ZM230.8716,364.6456,173.6082,331.589a2.0321,2.0321,0,0,1-1.1122-1.57V171.8835A127.4926,127.4926,0,0,1,381.5636,73.9884c-1.0322.5633-2.83,1.5558-4.0236,2.28L242.0957,154.5044a22.0025,22.0025,0,0,0-11.1306,19.2566Zm31.0975-67.0521L335.62,255.0559l73.6488,42.51v85.0481L335.62,425.1266l-73.6506-42.5122Z"
            />
          </svg>
          <div class="searchMsg">Chat GPT 무엇이든 물어보세요 !</div>
        </div>
        <div class="searchForm">
          <input class="searchInput" type="text" />
          <button class="searchButton" onclick="onClickSearch()">검 색</button>
        </div>
      </div>
      <div class="searchResult">Search Result</div>
      <div class="nft">
        <img
          src="https://i.seadn.io/gcs/files/1a03fbc6528ee7e9f985db96c553267e.png?auto=format&w=1000"
          alt="my nft"
        />
        <div class="nftHover">
          <a
            href="https://opensea.io/assets/matic/0xcb0fe82c34e2ce106f76b0ed054e6f437acaa119/28"
            target="_blank"
            >더보기</a
          >
          <button onclick="onClickToggle(false)">X</button>
        </div>
      </div>
      <button class="nftView" onclick="onClickToggle(true)">NFT보기</button>
    </main>
    <video
      class="bgVideo"
      src="images/background.mp4"
      autoplay
      muted
      loop
    ></video>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script src="main.js"></script>
  </body>
</html>

input.scss

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

body {
  margin: 0;
  color: rgb(22, 22, 22);
}

.bgVideo {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  object-fit: cover;
}

main {
  position: fixed;
  z-index: 2;
  width: 100vw;
  height: 100vh;

  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;

  .time {
    color: black;
    font-size: 60px;
    font-weight: 900;
  }

  .quotes {
    position: relative;
    font-size: 60px;

    .quotesAddBtn {
      display: none;
      position: absolute;
      top: 50%;
      right: 50%;
      transform: translate(50%, -50%);
    }

    &:hover {
      .quotesAddBtn {
        display: inline-block;
      }
    }
  }

  .newQuotes {
    display: none;
  }

  .search {
    .searchLogo {
      width: 32px;
      height: 32px;

      animation: spin 5s linear infinite;
    }
  }

  .searchResult {
    display: none;
  }

  .nft {
    position: fixed;
    top: 0;
    right: 0;
    margin: 24px;

    img {
      width: 256px;
      height: 256px;
    }

    .nftHover {
      position: absolute;
      display: none;
      width: 256px;
      height: 256px;
      top: 0;
      left: 0;
      background-color: rgba(0, 0, 0, 0.5);

      a {
        color: white;
      }
      button {
        position: absolute;
        width: 24px;
        height: 24px;
        top: 0;
        right: 0;
        margin: -8px;
        border-radius: 9999px;
      }
    }

    &:hover {
      .nftHover {
        display: flex;
        justify-content: center;
        align-items: center;
      }
    }
  }

  .nftView {
    position: fixed;
    top: 0;
    right: 0;
    margin: 24px;
    display: none;
  }
}

main.js

const QUOTES = "quotes";

function getTime() {
  const time = document.querySelector(".time");

  const newDate = new Date();

  // const hours = newDate.getHours();
  // const minutes = newDate.getMinutes();
  // const seconds = newDate.getSeconds();

  const hours = String(newDate.getHours()).padStart(2, "0");
  const minutes = String(newDate.getMinutes()).padStart(2, "0");
  const seconds = String(newDate.getSeconds()).padStart(2, "0");

  // time.innerText = hours + ":" + minutes + ":" + seconds;
  time.innerText = `${hours}:${minutes}:${seconds}`;
}

getTime();
setInterval(getTime, 1000);

function getQuotes() {
  const quotesMsg = document.querySelector(".quotesMsg");
  let savedQuotes = localStorage.getItem(QUOTES);

  if (!savedQuotes) {
    localStorage.setItem(
      QUOTES,
      JSON.stringify([
        "열심히 살지맙시다.",
        "그래도 열심히 살아야지.",
        "열심히 살면 뭐해~",
        "열심히 살면 반드시 빛이 온다.",
      ])
    );

    savedQuotes = localStorage.getItem(QUOTES);
  }

  let quotesArray = JSON.parse(savedQuotes);

  quotesMsg.innerText =
    quotesArray[Math.floor(Math.random() * quotesArray.length)];
}

getQuotes();
// setInterval(getQuotes, 1000);

function onClickAdd() {
  const newQuotes = document.querySelector(".newQuotes");

  newQuotes.style.display = "inline-block";
}

function onClickRegist() {
  const quotesMsg = document.querySelector(".quotesMsg");
  const newQuotes = document.querySelector(".newQuotes");
  const newQuotesInput = document.querySelector(".newQuotesInput");

  if (!newQuotesInput.value) {
    return;
  }

  let savedQuotes = localStorage.getItem(QUOTES);

  let quotesArray = JSON.parse(savedQuotes);
  quotesArray.push(newQuotesInput.value);

  localStorage.setItem(QUOTES, JSON.stringify(quotesArray));

  quotesMsg.innerHTML = `<span style="color:red;">${newQuotesInput.value}<span/>`;
  newQuotes.style.display = "none";
  newQuotesInput.value = "";
}

let isLoading = false;

async function onClickSearch() {
  const searchInput = document.querySelector(".searchInput");
  const searchResult = document.querySelector(".searchResult");

  if (!searchInput.value) return;
  if (isLoading) return;

  // 여기까지옴 === isLoading false

  isLoading = true;
  const question = searchInput.value;
  searchInput.value = "검색 중 입니다... 잠시만 기다려주세요...";

  console.log("챗 지피티 동작중");

  // 프론트엔드에서 백엔드
  const response = await axios.post(
    "https://주소는 공개되면 안되지롱!!!!!!!!!",
    {
      question,
    },
    {
      headers: {
        "Content-Type": "application/json",
        Authorization: "Bearer BLOCKCHAINSCHOOL3",
      },
    }
  );

  if (response.status === 200) {
    searchResult.style.display = "inline";
    searchResult.innerText = response.data.choices[0].message.content;
  }

  searchInput.value = "";
  isLoading = false;
}

function onClickToggle(value) {
  const nft = document.querySelector(".nft");
  const nftView = document.querySelector(".nftView");

  if (value) {
    nft.style.display = "inline-block";
    nftView.style.display = "none";
  } else {
    nft.style.display = "none";
    nftView.style.display = "inline-block";
  }
}
profile
개발자로 성장중

0개의 댓글