맞보기
블록 체인 기술은 놀랍도록 매력적입니다.
전적으로 그 위에 구축 될 미래에 대해 생각하는 것이 그리 멀지는 않을 것입니다.
따라서, 블록 체인에서 개발을 시작하려면 무엇을 배워야할까요?
어떤 언어가 도움이 될까요?
이 가이드에서는 주요 몇 가지를 살펴볼 것입니다.
블록 체인 소프트웨어 개발 관련한 문제 그리고 시작하기 전에 블록 체인 개발자가 직면 한 몇 가지 문제점을 점검해 봅시다.
공개 블록 체인을 만들고 유지하는 것은 여러 가지 이유로 쉽지 않습니다.
첫째, 코드는 공개되어 있으므로 누구나 볼 수 있습니다. 누구나 코드를 살펴보고 버그와 취약점을 확인할 수 있습니다. 그러나 다른 공개 코드 리소스와 달리 블록 체인 코드에서 취약성을 찾는 단점은 엄청납니다. 어떤 프로그래머라도 잠재적으로 수백만 달러와 수백만 달러를 해킹 할 수 있습니다. 이러한 합법적인 보안 문제로 인해 블록 체인 개발은 일반적으로 매우 느립니다.
네트워크와 보조를 맞추는 것이 중요합니다. 너무 늦어서 모든 네트워크 요구 사항을 따라 잡을 수는 없습니다. Remote 및 Local Query 를 처리 할 수있도록 잘 준비되어 있어야합니다.
블록 체인은 항상 최대한의 기능을 수행해야하지만, 그렇게하기 위해서는 선택된 언어가 매우 다양해야합니다. 병렬로 처리 할 수없는 작업이있을 때 병렬 처리가 가능한 블록 체인에는 특정 작업이 있습니다.
"병렬화 가능한"작업의 좋은 예는 디지털 서명 확인입니다. 서명 확인을 위해 필요한 모든 것은 키, 거래 및 서명입니다. 세 가지 데이터 만 사용하면 병렬화 된 방식으로 검증을 수행 할 수 있습니다.
그러나 블록 체인의 모든 기능이 그런 식으로 수행되어야하는 것은 아닙니다. 트랜잭션 실행 자체를 생각해보세요. 여러 트랜잭션을 병렬로 실행할 수 없습니다. 이중 지출과 같은 실수를 피하기 위해 한 번에 하나씩 수행해야합니다. 일부 언어는 병렬 작업에서는 좋지만 일부 언어는 비 병렬 작업에서 유용합니다.
결정론적 행동이란 무엇일까요?
A + B = C이면 상황에 관계없이 A + B는 항상 C와 같습니다.이를 결정론적 행동이라고합니다.
해시 함수는 결정적입니다. 즉 A의 해시는 항상 H (A)가됩니다.
따라서 블록 체인 개발에서 모든 트랜잭션 작업은 결정적이어야합니다. 한 방향으로 행동하고 다음 날에 다른 방식으로 행동하는 거래를 할 수 없습니다. 마찬가지로 두 가지 다른 시스템에서 서로 다른 두 가지 방식으로 작동하는 현명한 계약을 할 수 없습니다.
이것에 대한 유일한 해결책은 isloation입니다. 기본적으로 스마트 계약 및 트랜잭션을 비 결정적 요소와 분리합니다.
그래서 우리는 블록 체인 개발자들이 직면 한 주요 문제에 대해 논의해봤습니다. 이제 개발자가 블록 체인에서 코드를 작성하는 데 사용할 수있는 언어 중 일부를 확인해 보겠습니다.
무엇보다 먼저, 개발자 모두의 할아버지 C ++로 시작합시다. C ++는 Bjarne Stroustrup에 의해 C 언어의 확장으로 만들어졌습니다.
C언어의 유연성과 효율성을 갖도록 설계되었지만 몇 가지 큰 차이점이 있습니다. C와 C ++의 가장 큰 차이점은 C가 프로세스 지향적이지만 C ++은 객체 지향적이라는 것입니다.
이것이 의미하는 바는 C ++에서 데이터와 함수가 "객체"라는 작은 패키지로 묶여지면 객체가 만들어지면 다른 프로그램에서 쉽게 호출하고 재사용 할 수 있으므로 코딩 시간이 크게 단축된다는 것입니다.
세계에서 가장 간단한 C ++ 프로그램을 살펴 보겠습니다. "Hello World"프로그램 :
#include <iostream.h>
main()
{
cout << "Hello World!";
return 0;
}
이 코드는 다음을 인쇄합니다 : Hello World!
그렇다면 왜 사람들은 여전히 C ++을 코딩에 사용할까요? 확실히 더 매력적인 언어가 지금도 있는데 왜 사람들은 아직도 C ++로 돌아 가야한다고 주장할까요? 왜 bitcoin 블록 체인이 C ++로 코딩 되어 있을까요?
자, C ++에는 매우 매력적인 요소가 있습니다.
블록 체인 개발의 과제에 대해 앞서 말한 것을 기억하십니까? 블록 체인은 코드를 보호해야 할뿐만 아니라 효과적인 자원 관리도해야합니다. 블록 체인은 모든 노드에 빠른 서비스를 제공하면서 많은 신뢰할 수없는 엔드 포인트와 상호 작용해야합니다.
이 신속하고 즉각적인 서비스는 비트 코킹과 같은 암호화 성공에 중요합니다. 모든 노드는 "합의"의 원칙을 기반으로하며 네트워크의 모든 노드는 정확히 동일한 블록을 수락하고 거부해야합니다. 그렇지 않으면 체인에 분기가있을 수 있습니다.
이러한 모든 요구 사항을 충족시키고 최고 수준에서 수행하려면 CPU 및 메모리 사용을 철저하고 완벽하게 제어해야합니다. C ++은 이를 사용자에게 제공합니다.
앞서 논의한 것처럼 블록 체인 프로그래밍의 주요 과제 중 하나는 병렬화가 잘되는 작업과 병렬 처리하지 않는 작업을 통합하는 것입니다. 대부분의 언어는 하나의 언어를 전문으로하지만 C ++의 스레딩 기능은 병렬 및 비 병렬 작업을 모두 처리 할 수 있습니다. 스레드는 동시에 실행될 수있는 명령 세트입니다. C ++은 효과적인 스레드 간 통신을 통해 우수한 다중 스레드 기능을 허용 할뿐만 아니라 단일 스레드 성능을 최적화합니다.
C ++의 가장 흥미로운 측면 중 하나는 이동 의미 체계입니다. 이동 의미 체계는 내용이 완전히 복사되지 않고 객체간에 이동되는 방법을 제공합니다. copy semantics와 move semantics 사이의 차이점을 확인해 봅시다. ( "Stackoverflow"에서 피터 알렉산더 (Peter Alexander)의 답변에서 가져온 데이터를 따르면..).
Copy Semantics:
assert(b == c);
a = b;
assert(a == b && b == c);
여기서 무슨 일이 일어나고있는 걸까요? b의 값은 a에 들어가고 b는 모든 값의 끝에서 변하지 않습니다.
다음걸 볼까요?
Move Semantics:
assert( b = = c);
move (a,b);
assert (a = =c );
여기서 무슨 일이 일어나고있는 걸까요?
두 코드 블록의 차이점을 확인할 수 있습니까?
우리가 이동 의미론을 사용할 때, "b"의 값은 변경 될 필요가 없습니다. 그것이 복사 의미론과 이동 의미론의 차이점입니다. 이동 시맨틱의 가장 큰 장점은 필요할 때만 특정 데이터의 복사본을 얻을 수 있기 때문에 코드의 중복성을 크게 줄이고 성능을 크게 향상시킬 수 있다는 것입니다. 보시다시피 효율적인 메모리 관리와 고성능은 블록 체인에서 모두 바람직합니다.
C ++에는 한 프로그램에서 다른 프로그램으로 가져올 수있는 네임 스페이스 기능이 있습니다. 네임 스페이스는 이름 충돌을 피하는 데 도움이됩니다. 또한 C ++에는 클래스가 있으므로 다양한 API 간의 경계 역할을 할 수 있으며 명확한 분리를 도울 수 있습니다.
C ++의 클래스는 데이터 클래스와 멤버로 함수가있는 키워드 클래스로 선언 된 사용자 정의 유형 또는 데이터 구조입니다. 특정 클래스의 객체를 선언하여 클래스에서 선언 된 함수에 액세스 할 수 있습니다.
David Schwartz가 말한 것처럼 최소한 3 개의 솔리드 컴파일러가 있으며 새로운 기능은 실제 문제를 해결하기위한 것입니다. 모든 종류의 디버거와 분석 도구는 성능 프로파일 링에서부터 모든 종류의 문제 자동 탐지에 이르기까지 모든 분야에서 사용할 수 있습니다. 이것은 언어가 새롭고 더 나은 기능을 통합하기 위해 끊임없이 성장하고 있음을 의미합니다.
위의 기능 때문에 Satoshi Nakamoto는 C ++을 비트 코인 소스 코드의 기본 언어로 선택했습니다.
다음은 자바 스크립트입니다.
HTML 및 CSS와 함께 World Wide Web Content Production의 세 가지 핵심 기술 중 하나입니다. Javascript는 대개 대화식 웹 페이지를 만드는 데 사용됩니다. 자 이제 Javascript를 사용하여 아주 간단한 블록 체인을 만드는 법을 살펴 보겠습니다.
그러기 전에 우리가 해결해야 할 몇 가지 사항이 있습니다.
블록 체인이란 무엇이며 코드 단위로 정확히 어떻게 작동할까요?
블록 체인은 기본적으로 데이터를 포함하는 블록 체인입니다. 그것은 기본적으로 연결된 목록입니다.
그러나 무엇이 그렇게 특별하게 만들까요? 블록 체인은 변경 불가능합니다. 의미는 일단 데이터가 블록 안에 들어가면 결코 변경 될 수 없다는 것입니다. 블록 체인은 어떻게 불변성을 얻습니까? 그것은 "해싱 (hashing)"이라고하는 간단하지만 독창적 인 메커니즘 때문입니다. 아래 다이어그램을 확인하십시오.
이미지 제공 : Lauri Hartikka 매체 기사
각 블록은 이전 블록의 해시를 포함하는 해시 포인터를 통해 이전 블록에 연결됩니다. 그렇다면 이것이 어떻게 체인을 불변으로 만드는가?
암호 해시 함수의 가장 매력적인 속성 중 하나는 입력을 조금만 변경해도 출력 해시에 큰 영향을 줄 수 있다는 것입니다.
첫 번째 "T"를 대문자에서 소문자로 변경하면 출력 해시가 크게 변경되었습니다.
그렇다면 이것이 블록 체인에 어떤 영향을 미칩니 까?
각 블록은 해시 포인터를 통해 이전 블록에 연결됩니다. 따라서 누군가가 블록의 데이터를 변조하는 경우 해시를 크게 변경하여 결과적으로 전체 체인에 영향을 미치게됩니다 (모든 블록이 연결됨). 이것은 불가능한 체인을 동결시킬 것이고 따라서 블록은 변하지 않을 겁니다.
그렇다면 우리는 어떻게 블록을 만들 수 있을까요? 간단한 블록은 무엇으로 구성되어 있을까요? 우리가 만들려고하는 간단한 cryptocoin ( "BlockGeeksCoin"이라고 부르 자)에서, 각 블록은 다음과 같은 정보를 가질 것입니다 :
Index: To know the block number.
Timestamp: To know the time of creation.
Data: The data inside the block.
Previous Hash: The hash of the previous block.
Hash: The Hash of the current block.
계속하기 전에. 프로그램에서 사용할 특정 용어를 이해해야합니다.
this : "this"키워드는 함수 내에서 호출되며 특정 함수를 호출하는 특정 객체 내부의 값에 액세스 할 수 있습니다.
Constructor : 생성자는 클래스 내의 객체를 만들고 초기화하는 데 도움이되는 특수 함수입니다. 각 클래스는 하나의 생성자로 제한됩니다.
이제 끝났습니다 ^^. 이제부터 블록을 만들어 보도록 하겠습니다..
const SHA256 = require("crypto-js/sha256");
class Block
{
constructor(index, timestamp, data, previousHash = '')
{
this.index = index;
this.previousHash = previousHash;
this.timestamp = timestamp;
this.data = data;
this.hash = this.calculateHash();
}
calculateHash()
{
return SHA256(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data)).toString();
}
}
자. 코드분석을 해보도록 하겠습니다..
JavaScript의 sha256 해시 함수를 사용할 수 없기 때문에 코드의 첫 번째 행에서 crypto-js 라이브러리를 호출했습니다.
다음으로 클래스 내부의 생성자를 호출하여 특정 값을 갖는 객체를 호출합니다. 아마 눈을 끈 것은 calculateHash () 함수입니다. 정확히 무엇을하는지 봅시다.
블록에서 모든 내용을 가져 와서 해시로 특정 블록의 해시를 얻습니다. JSON.stringify 함수를 사용하여 블록의 데이터를 문자열로 변환하여 해시합니다.
자 이제 블록은 준비 되고 그다음으로 넘어가 볼까요. 이제 블록을 블록 체인으로 연결해 봅시다.
class Blockchain
{
//Section 1 Genesis block creation
constructor()
{
this.chain = [this.createGenesisBlock()];
}
createGenesisBlock()
{
return new Block(0, "01/01/2017", "Genesis block", "0");
}
//section 2 adding new blocks
getLatestBlock()
{
return this.chain[this.chain.length - 1];
}
addBlock(newBlock) {
newBlock.previousHash = this.getLatestBlock().hash;
newBlock.hash = newBlock.calculateHash();
this.chain.push(newBlock);
}
//section 3 validating the chain
isChainValid()
{
for (let i = 1; i < this.chain.length; i++)
{
const currentBlock = this.chain[i];
const previousBlock = this.chain[i - 1];
if (currentBlock.hash !== currentBlock.calculateHash()) {
return false;
}
if (currentBlock.previousHash !== previousBlock.hash)
{
return false;
}
}
return true;
}
}
자 코드 분석을 섹션으로 나누어서 해보도록 하겠습니다.
제네시스 블록은 무엇입니까?
제네시스 블록은 블록 체인의 첫 번째 블록을 말합니다.. 특별한 이유는 모든 블록이 이전의 블록을 가리키고 있지만 제네시스 블록은 아무 것도 가리 키지 않기 때문입니다. 그래서, 새로운 사슬이 만들어지면 즉시 제네시스 블록이 호출됩니다. 또한 블록의 데이터를 수동으로 입력 한 "createGenesisBlock ()"함수를 볼 수 있습니다.
createGenesisBlock()
{
return new Block(0, “01/01/2017”, “Genesis block”, “0”);
}
이제 우리는 제네시스 블록을 만들었습니다. 나머지 체인을 만들어 봅시다.
첫째, 블록 체인의 마지막 블록이 현재 무엇인지 알아야합니다. 이를 위해 우리는 getLatestBlock () 함수를 사용합니다.
getLatestBlock()
{
return this.chain[this.chain.length - 1];
}
이제는 최신 블록을 결정 했으므로 새로운 블록을 추가하는 방법을 살펴 보겠습니다.
addBlock(newBlock) {
newBlock.previousHash = this.getLatestBlock().hash;
newBlock.hash = newBlock.calculateHash();
this.chain.push(newBlock);
}
그래서, 여기서 무슨 일이 일어나고 있는걸까요? 블록을 어떻게 추가할까요? 주어진 블록이 유효한지 어떻게 체크할까요?
블록의 내용을 기억합니까?
블록에 이전 블록의 해시가 있습니다.
그래서 우리가 여기서 하려고하는 것은 간단합니다. 새 블록의 previousHash 값을 최신 블록의 해시 값과 비교해주세요
이미지 제공 : Lauri Hartikka 매체 기사
이 두 값이 일치하면 새 블록이 합법적이며 블록 체인에 추가된다는 의미입니다.
이제 아무도 우리 블록 체인을 망쳐 놓지 않고 모든 것이 안정적인지 확인해야합니다.
우리는 "for"루프를 사용하여 블록 1에서 마지막 블록으로 이동합니다. 제네시스 블록은 블록 0입니다.
for (let i = 1; i < this.chain.length; i++)
{
const currentBlock = this.chain[i];
const previousBlock = this.chain[i - 1];
//이 코드 부분에서는 현재 블록과 이전 블록의 두 가지 용어를 정의합니다.
//이제 우리는 단순히이 두 값의 해쉬를 찾으려고합니다.
if (currentBlock.hash !== currentBlock.calculateHash()) {
return false;
}
if (currentBlock.previousHash !== previousBlock.hash)
{
return false;
}
}
return true;
현재 블록의 "previousHash"가 이전 블록의 "Hash"와 같지 않으면이 함수는 False를 반환하고 그렇지 않으면 True를 반환합니다.
이제 BlockGeeksCoin.True를 만들기 위해 블록 체인을 최종적으로 사용할 것입니다.
let BlockGeeksCoin = new Blockchain();
BlockGeeksCoin.addBlock(new Block(1, “20/07/2017”, { amount: 4 }));
BlockGeeksCoin.addBlock(new Block(2, “20/07/2017”, { amount: 8 }));
이게 다야? 네.. 다 입니다..
Blockchain을 기반으로 새로운 암호 화를 생성하고 BlockGeeksCoin이라고 명명했습니다.
이 새 객체를 호출하여 생성자를 활성화하고 Genesis 블록을 자동으로 생성했습니다.
우리는 단순히 두 개의 블록을 더 추가하고 데이터를 주었습니다.
사실 단순하고 간단하죠.
마지막으로, 우리는 Solidity 를 다루도록 하겠습니다. DAPP (분산 된 응용 프로그램)를 만드는 방법이나 ICO 게임을 배우는 방법을 배우려는 사람들에게 Solinity를 배우는 것이 절대적입니다.
Solidity는 ECMAScript (Javascript)와 매우 유사한 구문을 사용하여 의도적으로 슬림화되고 느슨하게 형식화 된 언어입니다. 그래서, 우리가 계속하기 전에, 기본적인 Solidity contracts 예제를 봅시다. (github에서 가져온 코드).
contract BasicIterator
{
address creator; // reserve one "address"-type spot
uint8[10] integers; // reserve a chunk of storage for 10 8-bit unsigned integers in an array
function BasicIterator()
{
creator = msg.sender;
uint8 x = 0;
//Section 1: Assigning values
while(x < integers.length) {
integers[x] = x;
x++;
} }
function getSum() constant returns (uint) {
uint8 sum = 0;
uint8 x = 0;
//Section 2: Adding the integers in an array.
while(x < integers.length) {
sum = sum + integers[x];
x++;
}
return sum;
}
// Section 3: Killing the contract
function kill()
{
if (msg.sender == creator)
{
suicide(creator);
}
}
}
코드 분석을 해볼까요?
첫 번째 단계에서는 10 개의 8 비트 부호없는 정수를 사용하는 "정수"라는 배열을 채 웁니다. while 루프 내부에서 어떤 일이 일어나는지 살펴 보겠습니다.
while(x < integers.length) {
integers[x] = x;
x++;
}
정수 x에 "0"값을 이미 지정했음을 기억하십시오. while 루프는 0에서 integer.length로 이동합니다. Integers.length는 배열의 최대 용량을 반환하는 함수입니다. 따라서 배열에 10 개의 정수가 있다고 결정하면 arrayname.length는 값 10을 반환합니다. 위의 루프에서 x 값은 0-9 (<10)에서 정수 자체에 값을 할당합니다. 루프의 끝에서 정수의 값은 다음과 같습니다.
0,1,2,3,4,5,6,7,8,9.
getSum () 함수 안에서 배열 자체의 내용을 추가 합니다. 방법은 위의 루프를 반복하면서 변수의 "sum"을 사용하여 배열의 내용을 추가하는 것입니다.
이 함수는 계약을 종료하고 계약의 나머지 금액을 계약 생성자에게 보냅니다.
이 블러그에서 블록 체인 내외에서 개발할 때 사용되는 블록 체인 코딩을위한 3 개 언어에 대해서만 가볍게 다루어봤습니다. 실제로는 잠재적으로 사용할 수있는 많은 언어가 더 많이 있습니다 (Java, Go). 세계가 점점 더 분권화되고 블록 체인 (blockchain)이 점점 더 주류가됨에 따라 미래는 분명 무한합니다.
코딩에 대한 심화 내용은 다음 글에서 다루어 보도록 하겠습니다.