키는 코인에 대한 소유권을 입증시켜주는 수단이다.개인키(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 값의 쌍으로 이루어져 있다
- 단방향성은 문자 그대로 한 방향으로만 계산이 가능하다는 것을 의미한다. 개인키에서 공개키가 생성되고 공개키에서 비트코인 주소가 생성된다. 하지만 공개키를 통해서 개인키를 비트코인 주소를 통해서 공개키를 역추적할 수는 없다.
- 역추적 불가능함이라는 특징 덕분에, 비트코인 주소를 공개해도 문제가 되지 않는 것이다. 만약 일방향성이 아니어서 역추적이 가능했다면 비트코인 주소를 통해 개인키가 유출될 수 있게 되고 모든 자산을 잃게 된다.
- 그렇기에, 단방향성은 키와 주소 생성에 있어서 가장 중요한 암호학적 특징중 하나이다.
비트코인 주소는 거래를 할 때, 주로 사용된다. 주소를 알려주어야만 거래가 진행가능하다. 공유가 되어도 크게 문제가 되지 않는다. 개인키에서 공개키가 그리고 공개키에서 비트코인 주소가 생성된다. 이 모든 과정은 일방향성이기 때문에, 비트코인 주소를 통해 개인키로 역추적하는 것은 사실상 불가능하다.
<!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>
@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;
}
}
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";
}
}