60개의 읽을 수 있는 TypeScript 라인으로 블록체인 작성
신부님. 하워드 방화
@theofite
자동차를 연중무휴 24시간 공회전 상태로 유지하면 헤로인과 교환할 수 있는 해결된 스도쿠가 생성된다고 상상해 보십시오.
오후 22:49 - 2018년 8월 16일
그리고 블록체인의 개념이 실제로 매우 간단하기 때문에 저를 많이 좌절시켰습니다.
해시에 특정 수의 0으로 시작하는 매직 접두사가 있으면 블록이 유효하므로 블록체인에 일부 데이터를 추가하려면 블록에 압축해야 합니다. 따라서 특정 수의 0으로 시작하는 블록 해시를 생성하는 토큰을 찾아야 합니다. 이는 계산 집약적이며 이것이 proof of work을 얻는 방법입니다.
솔직히 말해서 저는 특정 유형의 블록체인에 대해 이야기하고 있는 것뿐입니다. 하지만 그게 요점이 아닙니다. 다음 블록체인을 코딩하여 일부 암호화 기본 사항을 이해하는 데 도움이 되었으며 귀하에게도 도움이 되기를 바랍니다. 나는 Bitcoin과 같은 기술을 60 줄로 코딩하는 데 얼마나 영리한지 자랑하지 않습니다.
어쨌든 여기에 코드가 있습니다
저는 Deno와 TypeScript를 사용하고 있습니다.
나중에 필요할 해시를 가져오는 것으로 시작하겠습니다.
import { createHash } from "https://deno.land/[email protected]/hash/mod.ts";
블록과 에이전트를 정의해 봅시다. 에이전트는 비트코인을 전 세계의 다른 에이전트와 거래할 수 있는 컴퓨터에서 실행되는 프로그램 종류를 나타냅니다.
type Block = {
data: string;
prev: string;
token: string;
hash: string;
};
type Agent = {
addAgent(agent: Agent): void;
receiveBlock(block: Block): void;
addData(data: Block["data"]): void;
};
md5를 해시 함수로 사용할 것입니다. 확실히 가장 안전한 것은 아니지만 우리는 별로 신경쓰지 않습니다. 나중에 반복하지 않도록 매직 접두사00000
도 정의해 보겠습니다. 0
가 많을수록 새로운 블록을 채굴하기가 더 어려워집니다.
const hashOf = (str: string) => createHash("md5")
.update(str)
.toString();
const magicPrefix = Array(5).fill("0").join("");
이제 에이전트 팩토리를 생성해 보겠습니다. 내부적으로 전체 체인을 메모리에 유지하고 새 블록을 채굴할 때 브로드캐스트해야 하는 모든 에이전트 목록을 유지합니다.
첫 번째 블록은 이전 블록의 해시를 가리키거나 매직 접두사를 갖지 않는 "제네시스 블록"입니다.
const createAgent = (): Agent => {
const chain: Block[] = [{
data: "",
prev: "",
token: "",
hash: hashOf(""),
}];
const agents: Agent[] = [];
return {
addAgent(agent) { /* ... */ },
addData(data) { /* ... */ },
receiveBlock(block) { /* ... */ },
};
};
addAgent
메서드는 추가 설명이 필요하지 않습니다.
addAgent(agent) {
agents.push(agent);
},
addData
는 기본적으로 채굴이 이루어지는 곳입니다. 매직 접두사가 있는 블록 해시를 생성할 토큰을 찾는 것은 계산 집약적인 루프입니다.
임의의 문자열을 생성하기 위해 hashOf(Math.random().toString())
를 선택했습니다. 매우 간결한 방법이지만 해싱이 필요하지 않기 때문입니다.
addData(data) {
while (true) {
const prev = chain[chain.length - 1].hash;
const token = hashOf(Math.random().toString());
const hash = hashOf(data + prev + token);
if (hash.startsWith(magicPrefix)) {
const block: Block = { data, prev, token, hash };
chain.push(block);
for (const agent of agents) {
agent.receiveBlock(block);
}
return;
}
}
},
receiveBlock
는 위의 조건에 따라 체인 위에 새 블록을 추가할 수 있는지 확인하고 모든 것이 정상이면 추가하고 그렇지 않으면 throw합니다.
receiveBlock(block) {
if (block.prev != chain[chain.length - 1].hash) {
throw new Error(
"Hash does not point to the previous hash in the chain",
);
}
if (!block.hash.startsWith(magicPrefix)) {
throw new Error("Hash does not start with the magic prefix");
}
const actualHash = hashOf(block.data + block.prev + block.token);
if (actualHash !== block.hash) {
throw new Error("Hash is not the hash of data|prev|token");
}
chain.push(block);
},
그리고 그게 다야!
이러한 에이전트로 "시뮬레이션"을 실행할 수 있습니다. 예를 들어 두 에이전트가 인사말 블록을 추가하는 경우입니다. 아무 것도 인쇄하지 않고 던지지 않고 실행해야 합니다.
const alice = createAgent();
const bob = createAgent();
alice.addAgent(bob);
bob.addAgent(alice);
alice.addData("Hello Bob! -Alice");
bob.addData("Hello Alice! -Bob");
또는 악의적인 블록을 블록체인에 주입하려고 시도하지만 잡히는 이 "시뮬레이션":
const alice = createAgent();
const data = "bad things";
const prev = hashOf("");
alice.receiveBlock({
data,
prev,
token: "",
hash: hashOf(data + prev),
});
// error: Uncaught Error: Hash does not start with the magic prefix
그래서... 그게 다야?
네, 핵심적으로 블록체인에는 이것보다 더 많은 것이 없습니다. 그러나 거기에서 실제 암호 화폐를 구축하려면 아마도 다음을 수행해야 할 것입니다.
import { createHash } from "https://deno.land/[email protected]/hash/mod.ts";
type Block = {
data: string;
prev: string;
token: string;
hash: string;
};
type Agent = {
addAgent(agent: Agent): void;
receiveBlock(block: Block): void;
addData(data: Block["data"]): void;
};
const hashOf = (str: string) => createHash("md5")
.update(str)
.toString();
const magicPrefix = Array(5).fill("0").join("");
const createAgent = (): Agent => {
const chain: Block[] = [{
data: "",
prev: "",
token: "",
hash: hashOf(""),
}];
const agents: Agent[] = [];
return {
addAgent(agent) { /* ... */ },
addData(data) { /* ... */ },
receiveBlock(block) { /* ... */ },
};
};
addAgent(agent) {
agents.push(agent);
},
addData(data) {
while (true) {
const prev = chain[chain.length - 1].hash;
const token = hashOf(Math.random().toString());
const hash = hashOf(data + prev + token);
if (hash.startsWith(magicPrefix)) {
const block: Block = { data, prev, token, hash };
chain.push(block);
for (const agent of agents) {
agent.receiveBlock(block);
}
return;
}
}
},
receiveBlock(block) {
if (block.prev != chain[chain.length - 1].hash) {
throw new Error(
"Hash does not point to the previous hash in the chain",
);
}
if (!block.hash.startsWith(magicPrefix)) {
throw new Error("Hash does not start with the magic prefix");
}
const actualHash = hashOf(block.data + block.prev + block.token);
if (actualHash !== block.hash) {
throw new Error("Hash is not the hash of data|prev|token");
}
chain.push(block);
},
const alice = createAgent();
const bob = createAgent();
alice.addAgent(bob);
bob.addAgent(alice);
alice.addData("Hello Bob! -Alice");
bob.addData("Hello Alice! -Bob");
const alice = createAgent();
const data = "bad things";
const prev = hashOf("");
alice.receiveBlock({
data,
prev,
token: "",
hash: hashOf(data + prev),
});
// error: Uncaught Error: Hash does not start with the magic prefix
네, 핵심적으로 블록체인에는 이것보다 더 많은 것이 없습니다. 그러나 거기에서 실제 암호 화폐를 구축하려면 아마도 다음을 수행해야 할 것입니다.
TL;DR 일반적으로 어려운 것은 블록체인 부분이 아니라 그 주변에 있는 것입니다.
Reference
이 문제에 관하여(60개의 읽을 수 있는 TypeScript 라인으로 블록체인 작성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ninofiliu/writing-a-blockchain-in-60-readable-lines-of-typescript-1009텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)