코어 이더리움



통신학회에서 통신연구자를 위한 블록체인 강좌가 2017년 10월 12일 열립니다. 70분간 이더리움 아키텍쳐와 Dapp개발에 대해 강의를 하는 데 긴 추석 연휴 기간에 월령교를 보며 준비한 자료입니다. 


통신학회-CoreEthereum.pdf



이더리움은 블록체인 기반 기술하에 암호 화폐의 생성 , 전송  라이프사이클 관리외에 스마트 컨트랙을 지원한다스마트컨트랙은 서로 모르는 당사자간의 계약을 준수하도록 강제할  있는 응용 프로그램이다컨트랙 프로그램은 바이트코드로 컴파일된  블록체인을 통해 배포되고 , 로컬 로드상에서 실행되는 일종의 에이전트라   있다이렇게 개발된 스마트 컨트랙은 기존  인터페이스를 통해 접근하고 활용할  있으며 이렇게 스마트 컨트랙 기반하에 개발된 응용 서비스를 Dapp이라 한다 발표에서 이더리움 플랫폼의 상세 아키텍쳐와 기반 기술그리고 스마트 컨트랙과 이를 기반한 Dapp 개발 방안에 대해 상세히 소개한다





저작자 표시 비영리 변경 금지
신고

Posted by 박재현

암호화폐 선판매인 ICO가 반드시 필요한 이유.

 

 ZDNet 에 기고된 글입니다. 

http://www.zdnet.co.kr/column/column_view.asp?artice_id=20170911104944



9 4일 암호화폐 거래시장이 심하게 출렁거리며 급격한 하락세를 보였다. 시가 총액 203조원($180B) 규모의 시장이 20% 가까이 하락했다. 다음날 바로 시장이 회복되었지만 큰 충격이었기에 많은 사람들에게 궁금증을 불러 일으키기 충분한 계기가 되었다.  

 

이번 시장 하락의 직접적인 원인은 중국 인민은행의 ICO 금지책에 기인한다. 지난 93일 중국 인민은행, 증권감독관리 위원회 등 7개 중국 정부 부처는 "중국내 ICO를 전면 중단한다"고 발표했다. 또한 60 여개의 주요 블록체인 기반 플랫폼에 대한 수사에 착수했다. 그 여파로 중국의 블록체인 플랫폼인 네오(NEO) 퀀텀(QTUM) , 에이치쉐어(Hshare), 바이톰(Bytom)의 암호화폐 가치가 크게 하락하였고 중국 최대 ICO 플랫폼인 ICOAGE ICOIMFO가 모든 영업을 중단하겠다고 밝혔다. 더불어 우리나라 포함 전세계 암호화폐 시장도 크게 하락하였다.



 

암호화폐 선판매(ICO, Initial Coin Offerings)란 무엇인가?

 

일반 회사의 경우 회사 지분을 투자가들에게 팔아 투자금을 확보하거나 ,  유가 증권 시장 등에 회사 주식을 공개하여 투자자금을 확보한다. 특히, 후자의 경우를 IPO(Initial Public Offering)라 한다. IPO는 비상장기업이 정해진 법률과 절차에 따라 회사의 주식을 유가증권시장에서 공개적으로 거래할 수 있도록 해주는 합법적인 방법이며 법률에 따라 규제와 관리를 받는다. IPO를 하기 위해서는 회사를 성장시켜 그 가치를 입증해야 하기 때문에 많은 시간이 걸린다.

 

암호화폐 선판매 방식인ICO는 암호화폐 기반 프로젝트와 회사들이 초기 사업 자금을 확보하기 위해 미리 암호화페를 발행하고 이를 투자자들에게 선판매하여 자금을 확보하는 방법을 말한다. 이렇게 판매된 암호화폐는 암호화폐시장을 통해 거래될 수 있다.

 

ICO에 성공한 회사와 프로젝트들은?

 

2013년 마스터코인(Mastercoin)은 최초의ICO이다. 이후 블록체인 플랫폼을 선도하고 있는 이더리움은 2014년 이더라는 암호화폐를 판매하여 200억 원 이상의 투자금을 확보했고 현재 이를 기반으로 성공적으로 플랫폼 개발과 운영을 하고 있다. 현재 5조원 이상의 가치로 성장하였다. 이후 여러 업체들이 앞다투어 ICO를 진행했으며 2017년 들어 그 열기는 더욱 고조가 되었다.

 

2017블록체인기반 분산 스토리지 네트워크 구축을 추구하는 파일코인(Filecoin)ICO를 통해 2 5천만 달러 이상을 모금했으며 차세대 스마트 컨트랙트 시스템 구축하려는 테조스(Tezos)2 3 2백만 달러를 ICO로 확보하였다. 또한  이더리움을 기반으로 개발된 탈중앙화된 앱(Dapp)들에 대한 브라우저, 메신저 등을 개발하는 스테이터스(Status) 1 8백만 달러를 확보하였다. 현재에도 새로운 ICO 가 계속해서 나오고 있고 앞으로도 나올 것이다.


이더리움을 포함, 성공적인 ICO를 통해 건실하게 플랫폼을 추진하고 있는 프로젝트들은 공통적으로 명확한 목표와 추진 일정, 높은 기술력과 많은 경험이 갖고 있는 구성원이 모였다는 공통점이 있다. 비록 , 성공 여부는 누구도 모르지만 그 가능성은 짐작해 볼 수 있다. 현재에도 새로운 ICO 가 계속해서 나오고 있고 앞으로도 나올 것이다.

 

ICO의 성공여부, 어떻게 검증할 것인가?

 

순기능 측면에서ICO는 좋은 회사, 프로젝트에 공정하고 합법적인 투자를 할 수 있는 기회를 제공한다고 할 수 있다. 그러나 만약 신뢰할 수 없는 회사나 프로젝트팀이 과장된 내용으로 ICO를 통해 자금을 확보할 수 있다. 따라서 투자가는 많은 ICO 중 옥석을 가려내야 만 한다.

사실 투자자 입장에서 얻을 수 있는 ICO관련 정보는 해당 ICO에서 제공하는 기술 및 사업 설명서가 전부이다. 만약 이 설명서의 내용이 과장되었거나 비현실적이라면 ICO 에 참여하지 않는 것이 바람직하다.

 

특히, ICO를 통해 판매된 암호화폐는 즉시 거래가 될 수 있다. 따라서 자칫 잘못된 정보를 기반으로 ICO 가 진행이 되거나 , 악의적으로 정보를 조작하여 가치를 부풀려 진다면 큰 문제를 야기할 수 있다. 이번 중국의 ICO 금지 결정의 배경에도 현재 추진중인 ICO중 투기 성격의 그 실체를 명확히 파악할 수 없는 것이 다수 있기 때문이다. 실제 필자가 검토한 많은 ICO 과제 설명서 중 내용이 구체적이고 , 이를 수행할 팀들을 자세히 설명한 자료를 찾기 어려웠다.  

 

따라서 ICO를 통해 투자를 하려면 다음 사항을 고려할 필요가 있다.



- ICO투자를 하기전 해당 회사에 대해 철저히 조사를 해야 한다.

일반적으로 많은 ICO를 추진한 과제들은 깃허브(github)같은 공개 개발 플랫폼에 과제의 결과물을 공개해 둔다. 따라서 해당 ICO의 개발 결과물이 얼마나 자주 업데이트 되고 있는지 반드시 조사한다. 만약 , 업데이트가 자주 일어나지 않고 관련 문서가 업데이트되지 않는 다면 해당 프로젝트는 의심해 볼 필요가 있다.


-해당 ICO를 추진하는 팀의 구성원들을 철저히 조사한다. 

그들이 프로젝트를 성공할 만큼 충분한 경험과 기술을 갖고 있는지 , SNS 등을 통해 평판은 어떤지, 법적으로 도덕적으로 문제가 없는지 확인한다. 결국 프로젝트는 사람이 하는 것이기 때문에 팀에 대한 조사가 가장 중요하다고 생각한다.


ICO가 반드시 필요한 이유.

 

ICO는 암호화폐 기반의 신규 플랫폼 사업을 위한 자금 조달 방법으로 반드시 필요하다. ICO 를 추진하는 블록체인 기반 플랫폼들은 탈중앙집중화되어 모든 구성원들이 직접 서비스의 주체로 연결이 되어 각기 자신의 역할을 수행하고 그 공헌도에 따라 암호화폐를 대가로 받는다.

 

따라서 ICO 는 단순히 자금 확보라는 차원을 넘어 해당 프로젝트를 사용자에게 소개하고 이에 대한 반응을 확인하는 것이다. 이 반응의 결과가 바로 암호화폐의 구매이다.

 

또한 블록체인 기반 플랫폼은 비트코인이나 이더리움처럼 참여하는 사용자가 늘수록 가치가 지수상승한다. 특히, 암호화폐를 구매한 사용자는 가치 상승에 따라 암호화폐의 가치 또한 상승하기 있는 때문에 열성적인 후원자가 될 수 밖에 없다. 이러한 열성적인 사용자를 초기에 확보하기위해 ICO는 반드시 필요하다.   

 

프로젝트 소개할 때 속임수, 과장 등을 통해 사기를 치는 회사가 많을 수 있고 , 투자가 아니라 투기를 목적으로 ICO 참여한 후 확보한 암호화폐를 부풀려 이득을 얻으려는 투기꾼이 많을 수도 있다. 왜냐하면 지금은 암호화페 기반 블록체인 시장의 태동기 이기 때문이다. 지금과 같은 시련을 거치면 질서와 규칙이 세워지고 이를 통해 다양한 혁신이 나올 것이다.

 

국내에서 필요한 것은 ICO를 금지하는 것이 아니라 ICO를 투명하게 추진하기 위한 거버넌스와 제도가 필요하다. 특히, 중국 등 해외에서 ICO등을 금지할 때 우리나라에서 이를 합법화하고 활성화한다면 오히려 우리나라가 블록체인 기술을 선도할 수 있는 기회를 얻을 수 있다.  현재 스위스 등 유럽의 많은 국가와 도시에서 블록체인 기반 암호화폐 기술을 선도하기 위해 스스로 많은 규제를 풀고 관련 회사와 인재들이 찾는 곳이 되기 위해 노력하고 있다는 사실 또한 기억하자.

저작자 표시 비영리 변경 금지
신고

Posted by 박재현



블록체인, 이더리움 기술 튜토리얼


WhitePaper, YellowPaper 외에 체계적으로 블록체인과 이더리움 플랫폼에 대해 종합적으로 쉽게 정리된 자료 찾기가 어려웠습니다. 기술문서와 다양한 곳에 많은 전문가 분들의 설명글이 많았으나 이 또한 일일이 찾아 보아야 하니 번거롭기 그지 없었습니다. 실제 이더리움 오픈소스 과제를 만들고 개발하기 위해 이더리움 연구회 ( 이연 ) 를 시작하고 , 초기 시작 단계에서 개념을 잘 정리한 튜토리얼 자료가 필요했습니다. 여러 곳에서 블록체인과 이더리움 기술 관련 발표 및 교육 요청이 오는 데 이를 위해 작성하였습니다. 아직 미완성 본입니다. 실제 개념 이해와 이를 직접 코드 레벨까지 살펴볼 수 있도록 계속해서 정리할 예정입니다. 

- 현재 V 0.8 
- 차후 보강 내용 : 각 기술 내용에 대해 코드 및 콘솔  커맨드 등을 통한 확인 , 최신 내용 업데이트 , 컨트랙트 개발 추가 

- pdf 다운로드 : 

BlockChainTechTutorial-0.9.pdf



저작자 표시 비영리 변경 금지
신고

Posted by 박재현

이더리움 프로그래밍 수업(3)


들어가며


지난 두 번의 글을 통해 우리는 이더리움의 코어 엔진인 geth 를 다루는 다양한 방법에 대해 살펴보았습니다. 앞으로는 2회에 걸쳐 솔리디티를 이용해 컨트랙을 프로그래밍하는 방법에 대해 살펴보겠습니다. 특히, 단순 개발 뿐만 아니라 실제 해당 컨트랙이 어떻게 geth의 EVM 을 통해 실행되고 이 때 어떤 과정들을 거치는 지도 함께 살펴 보겠습니다.


// 첫번째 아주 간단한 예제 : Greeter.sol        

 

다음 예제 프로그램은 Greeter.sol 이라는 아주 간단한 솔리디티 프로그램입니다. Solidity-baby-steps에서 제공되는 첫번째 예제입니다. https://github.com/fivedogit/solidity-baby-steps ) 단계별로 많은 예제들이 모여 있어 해당 예제를 분석하면서 솔리디티 매뉴얼을 함게 보시면 솔리디티 프로그래밍을 익히는 데 효과적입니다.

 

아래 예제는 greet()를 호출할 때 마다 입력받은  스트링을 반환해주는 단순한 프로그램 입니다. 이 프로그램을 통해 솔리디티로 작성한 스마트 컨트렉트 프로그램의 구조를 이해해 보겠습니다. 

 

pragma solidity ^0.4.0;

contract Greeter        

{

    address creator;    

    string greeting;    

 

    function Greeter(string _greeting) public  

    {

        creator = msg.sender;

        greeting = _greeting;

    }

 

    function greet() constant returns (string)         

    {

return greeting;

    }

   

    function getBlockNumber() constant returns (uint)

    {

        return block.number;

    }

    function setGreeting(string _newgreeting)

    { 

        greeting = _newgreeting;    

     }

    function kill()

    {

        if (msg.sender == creator) 

        suicide(creator);      

    }

}

[ 3-1 ] Greeter.sol

 

하나씩 분해해서 살펴 보겠습니다.

 

pragma solidity ^0.4.0;

이 소스 파일은 0.4.0 보다 이전 버전의 컴파일로 컴파일 하지 마세요. 그리고 ^는 버전 0.5.0로 시작하는 컴파일러에서도 작동하지 않는다 라는 의미입니다. 항상 pragma 버전은 선언이 되어야 합니다

 

contract Greeter  {   }

Greeter 라는 컨트렉을 만든다 라는 것이고 하나의 파일에 여러개의 컨트렉을 정의하고 사용할 수 있습니다.

 

address creator;  string greeting;    

Greeter의 상태를 선언하는 것 입니다. address 데이타 타입의 creator와 string 데이타 타입의 greeting을 상태로 선언합니다. address는 20바이트(160 bit, 이더리움의 어드레스 사이즈) 로 산출연산을 할 수 없기 때문에 컨트랙의 주소나 키값 등을 저장하는 데 용의합니다. 또한 balance와 transfer를 멤버로 갖습니다.

 

가령, address myaddress = this; 라는 의미는 현재 이 컨트랙의 주소를 말하는 데 myaddress의 balace는 현재 이더 금액을 그리고 myadress.transfer(금액)은 해당 금액 만큼 내게 전송한다 라는 의미입니다.  아주 많이 이용되는 Value Type 중 하나입니다. 그리고 string은 UTF8 으로 인코딩되었고 크기가 지정되지 않은 임의 크기를 갖는 타입입니다. 


function Greeter(string _greeting) public { }

상태를 선언했다면 해당 상태를 바꿀, 실행할 수 있는 코드 단위인 함수를 선언하고 작성해야 합니다. 이 때 function 키워드를 사용하여 함수를 선언합니다. 위의 함수 선언은 Greeter라는 컨트랙 이름과 동일합니다. 생성함수로서 Creeter 컨트랙이 생성되는 순간 자동으로 호출되어 실행됩니다. strng 타입의 _geeting을 입력받도록 선언되어 있습니다. public 키워드는 외부에서도 호출이 될 수 있도록 지정하는 것 입니다. 

 

참고로 , 여기서 모든 설명을 할 수는 없지만 다음은 솔리디티에서 사용하는 함수 선언 방식입니다. 가령, internal은 내부에서만 사용하기 때문에 외부로 보여지지 않습니다. 쉽게 말해 Remix에서도 접근이 안되니 실행이 안됩니다. Payable은 실행을 할 때 이더(Ether)를 대가로 받는 함수입니다. 모두 미리 상세히 알고 있을 필요는 없습니다. 실제 개발을 하며 하나씩 하나씩 적용하며 익히는 것이 가장 효율적입니다.


function (<parameter types>) {internal|external} [constant] [payable] [returns ,!<return types>)]

 

creator = msg.sender;

선언하지 않았는데 갑자기 나타난 변수가 있습니다. msg 입니다. msg는 컨트랙을 생성한 사람의 어드레스를 영구적으로 저장하고 있는 글로벌 변수로서 블록체인에 접근해서 다양한 정보를 획득할 수 있습니다. msg.sender는 현재 함수를 호출한 사람의 주소를 알려준다. 호출자를 확인 후 제약할 수 있어 유용하게 사용된다.

 

function greet() constant returns (string)         

greet 함수는 변하지 않는 상수 타입의 스트링을 반환하는 함수라는 것을 말한다.

 

function getBlockNumber() constant returns (uint)

getBlockNumber 함수에는 앞서 선언하지 않았지만 block.number 이라는 것이 사용된다. msg처럼 block은 블록체인에 대한 정보에 접근할 수 있는 글로벌 변수이다. block.number 는 현재 블록의 넘버를 알려준다. 현재 블록의 gas limt을 알고 싶다면 block.gaslimit을 사용하면 된다. msg,block,tx 등은 아주 유용한 글로벌 변수로서 잘 이해하는 것이 필요하다.

 

function kill()

마지막에 나오는 kill 이라는 무시무시해 보이는 함수는 내부에서 suicide는 호출한다. suicide는 self descruct를 말하는 데 해당 컨트랙을 kill하고 남은 금액을 모두 생성한 사람에게 보내라는 것이다. 이를 위해  if (msg.sender == creator)    msg.sender가 creator인지 체크한 후  맞다면 컨트랙을 모두 suicide 하고 남은 금액을 반환하게 된다. 

 

//Remix에서 실행 - Greeter 컨트랙 배포

 

해당 소스를 오타 없이 입력했다면 Remix에서 제대로 실행이 될 것 입니다. 다음은  "how are you"  문자열을 입력하고 <<Create>> 버튼을 통해 배포된 Greeter의 실행 화면 입니다.  greet 함수의 value를 보면 "how are you"  문자열이 실제 utf8으로 인코딩되어 있는 실제값을 볼 수 있습니다.

 

[3-2] Greeter 컨트랙 배포

 

setGreeting 함수에 "반갑습니다." 라는 문자열을 입력하고 실행을 시켜 보겠습니다. 정상적으로 실행이 된 후 , 다시 greeet 함수를 실행하면 기존 greeting의 상태가  "how are you"  문자열에서 "반갑습니다." 로 변경된 것을 확인할 수 있습니다.

 


[3-3]  setGreeting 함수 실행

 

kill 함수를  실행시켜 보겠습니다.  앞서 설명 드린 것처럼 kill 함수는 suicide를 호출하여 해당 컨트랙을 삭제합니다. kill 함수 실행 후 , 다시 setString 함수를 실행시키면  Kill에 의해 해당 컨트랙이 삭제된 상태이기 때문에  TypeError 가 발생하는 것을 확인할 수 있습니다.

 


[3-4] kill 함수 호출 후 결과

 

잠시 이해를 돕기 위해 컴파일된 컨트랙의 상세 정보에 대해 살펴보겠습니다. <<iContract details (bytecode, interface etc.)>> 링크를 클릭하면 컨트랙의 상세 정보를 볼 수 있습니다. 상세 정보 중 다음의 주요한 것들만 정리해 봅니다.

 

- Bytecode & Runtime Bytecode

 

60606040526000357c0100000000000000000000000000000000000000000000000000000000900………………<중략생략>………………………....……………………………………………………………………...……11561039a576000816000905550600101610382565b5090565b905600a165627a7a723058203a53b67dee629a7ee6cd6008427d8043c1a2c8d30759ffba5d3b68e055e3c91e0029

 

솔리디티로 작성된 프로그램은 컴파일된 후 아래와 같은 형태의 바이트코드로 변환이 됩니다. 이 바이트 코드는 블록체인을 통해 각 노드에 배포가 됩니다. 배포후에는 주소(address)가 생성이 됩니다. 

 

이 바이트코드 중 가령, setGreeting 이라는 함수가 실행이 되면 이 실행 내용이 블록체인의 각 노드에 이 사실이 전파됩니다. 그리고 해당 트랜젝션이 문제가 없다면 블록에 해당 내용이 추가됩니다. 이렇게 수행중인 바이트코드가 Runtime Bytecode 입니다.

 

Interface


[{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getBlockNumber","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_newgreeting","type":"string"}],"name":"setGreeting","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"payable":false,"type":"constructor"}]

 

Greeter 컨트랙의 터페이스입니다. 인터페이스는 구현된 코드가 없는 추상화된 명세입니다. 이 니터페이스가 Web3.js를 통해 바이너리에 접근할 때 사용하는 ABI(Application Binary Interface)로 활용됩니다.  가령, 자바 스크립트 언어 상에서 var greeterABI = [{"constant" … "constructor"}]; 으로 지정 후 web3.eth.contract(greeterABI) 이렇게 호출하여 인터페이스를 사용합니다. 

 

 

Web3 deploy

 

지난 글에서도 설명했듯이 컨트랙은 Web3.js를 통해서 JSON RPC를 통해 자바 스크립트로 제어가 가능합니다. 이를 위해서는 Greeter 컨트랙이 Web3.js에서 접근할 수 있도록 deploy가 되어야 합니다.

 

var _greeting = /* var of type string here */ ;
var localhost_solidity-baby-steps_contracts_05_greeter_sol_greeterContract = web3.eth.contract([{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":...................<<중략>>
var localhost_solidity-baby-steps_contracts_05_greeter_sol_greeter = localhost_solidity-baby-steps_contracts_05_greeter_sol_greeterContract.new(
   _greeting,
   {
     from: web3.eth.accounts[0], 
     data: '

60606040526000357c0100000000000000000000000000000000000000000000000000000000900………………<중략생략>………………………....……………………………………………………………………...……11561039a576000816000905550600101610382565b5090565b905600a165627a7a723058203a53b67dee629a7ee6cd6008427d8043c1a2c8d30759ffba5d3b68e055e3c91e0029

', 
     gas: '4300000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

 

 

Meta data & Meta data location

 

{"compiler":{"version":"0.4.14+commit.c2215d46"},"language":"Solidity","output":{"abi":[{"constant":false,"inputs":[],"name":"kill","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getBlockNumber","outputs":[{"name":"","type":"uint256"}]......중략.......,"libraries":{},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"localhost/solidity-baby-steps/contracts/05_greeter.sol":{"keccak256":"0x5fe8bd1258cf319ac111e904ea5954e93630b1c77a66fd77095a4587670454af","urls":["bzzr://9a434bbf17d4662bd0bc822cd9cba702cc5c6828f608fa9c3cc26b086e49b1c7"]}},"version":1}

 

솔리디티 컴파일러는 자동으로 JSON 타입으로 해당 컨트랙의 메타 데이타를 생성한다. 이 메타 데이타 파일은 컴파일러의 버전, 사용된 개발 언어, ABI 등 해당 바이트 코드의 안정성을 체크하고 컨트랙과 보안 안전하게 상호작용하기 위해 필요한 정보들이 담겨 있다. 메타 데이타 파일은 Swarm 이라는 이더리움 분산 파일 시스템에 저장되고 조회될 수 있다. Swarm 에 접근할 때 사용하는 URL 이 bzzr이다.  메타파일의 마지막에는 Swarm에 접근하는 프로토콜이 선언되어 있다. -["bzzr://9a434bbf17d4662bd0bc822cd9cba702cc5c6828f608fa9c3cc26b086e49b1c7"]

 

 

Opcodes와 Assembly

 

컨트랙은 컴파일 후 바이트코드로 변환이 됩니다실제 이 바이트 코드는 1바이트 크기의 OpCode들로 분해되어 EVM의 스택에 쌓인 후 EVM에 의해서 실행이 됩니다. 다시 말해, 모여진 OpCode들의 실행이 바로 해당 컨트랙의 트랜젝션입니다. 현재 OpCode들은 Stop과 산술연산자, 각종 로직 연산자 , SHA3 , 환경 정보 , 블럭 정보, Stack/Memory/Storage와 플로우 연산자 , push 연산자, duplication 연산자 , Exchange 연산자 , 시스템 연산자 , 앞서 kill()에서 사용한 suicide 같은 self descruct연산자 등 많은 OpCode가 있습니다.

 

 [3-5] Opcodes와 Assembly

 

각 OpCode들을 실행을 하려면 실행 대가로 Gas를 제공해야 합니다. Gas를 제공하는 이유는 앞서도 설명했지만 해당 OpCode의 이상유무를 체크하고 이상이 없다면 블록에 등록하는 절차를 수행하는 마이너들에 대한 대가이자 , DDos 공격 등을 막기 위한 방법으로 사용됩니다. 지난 2016년 9월 해커들이 이더리움 네트웍에 지속적인 DDos 공격을 하여 정상적인 운영이 안된 문제가 있었습니다. 해커들이 서로 다른 계좌에 다수의 빈 트렌젝션을 발생시키고 사용하지 않는 빈 어카운트를 무한정 생성하여 이더리움 메모리를 소비해 버리는 공격이었습니다. 

  이 때 , 이더리움은 공격에 사용된 일부 OpCode의 Gas 비용을 높이고 발신자가 소비하는 리소스에 비례하여 강제로 수수료를 지불하게 하는  메이져 업그레이드(하드포크)를 한 적이 있습니다.  보다 자세한 OpCode와 Gas 등에 대한 내용은 Gavin Wood가 작성한 Ethereum Yellow Page를 참조하기 바랍니다.


마치는 말

 

새로운 컨트랙 기능 추가가 될 때 마다 OpCode가 추가될 터이고 , 이중 분명히 문제가 있는 OpCode들이 있을 것 입니다. 이 취약한 OpCode들로 인해 문제가 발생할 때 마다 메이저 업그레이드가 생긴다면 이더리움의 기술 신뢰성과 가치에 큰 영향을 줄 것 같습니다. 본질적으로 이더리움의 성능 향상을 위한 이더리움 커뮤니티의 노력이 필요한 것 같습니다. 이러한 부분에 관심이 많다면 Qtum과 EOS 프로젝트를 살펴보면 많은 새로운 관점을 얻으실 것 입니다. 그리고 최근에 MS에 발표한 Coco 프레임웍도 현재 이더리움에서 해결해야 할 여러 이슈들을 해결하는 데 주안점을 두고 있습니다. 나중 기회가 되면 함께 살펴보면 좋을 것 같습니다.


이번에는 컨트랙 프로그램의 기초에 대해 살펴보았습니다. 다음에는 좀 더 복잡하고 솔리티디의 다양한 언어적 특성을 이해할 수 있는 예를 분석해보겠습니다. 참고로 , 모두 아시다시피 개발 언어는 직접 작은 것이라도 하나를 직접 작성해 보면서 경험을 늘리는 것이 가장 중요합니다.

     








저작자 표시 비영리 변경 금지
신고

Posted by 박재현


이더리움 프로그래밍 수업(2)



들어가며 

 

지난 에서는 이더리움 코어 엔진인 geth을 설치하고 다뤄보면서 이더리움 플랫폼과 프로그래밍의 개괄적인 내용에 대해 살펴 보았습니다사용자 계정을 만들고 이들 간에 가상화폐를 주고 받고 ,  주고 받는 작업을 블록체인에 연결하기 위해 마이닝이라는 작업을 하였습니다이번에서 실제 이더리움이 제공하는 가장 유용한 기술이자 비트코인 플랫폼과 차별화되는 대표 기능인 스마트 컨트랙트를 솔리디티(Solodity) 개발 언어를 이용하여 프로그래밍하는 방법과 개발 환경 구축 등에 대해 살펴보겠습니다.   


 

// 솔리디티(Solidity) 프로그래밍에 앞 서 기억해야  들.

 

go-ethereum 1.6.0 이후 버전부터 geth 상에서 RPC API 호출을 사용하여 솔리디티 검파일러인 solc를 호출하여 Solidity 소스를 컴파일수 없습니다.  따라서 geth 엔진상에서 solidity compiler RPC 호출하여 컴파일할  있는 getCompilers() API 1.6.0 버전 이후에는 작동하지 않습니다.

 

 web3.eth.getCompilers()

 

 

"Method does not exist/is not available" eth.getCompilers(), in geth console to eth_compilers, eth_compileSolidity are gone in go-ethereum 1.6.0

 

참고 : #3740에서 해당 기능 삭제되었고 #290에 그 이유가 설명이 되어 있습니다. web3에서 제공하는 객체중 eth 객체는 이더리움 노드의 코어 기능과 관련된 것들을 담당하는 데 solc 컴파일러 호출은 이 범위를 벗어나기 때문에 삭제했다고 합니다. 또한 이더리움은 저차원 EVM 바이트 코드를 처리해야 하는 데 고수준의 프로그래밍 언어와 관련된 API를 호출하는 것은 바람직하지 않다라는 입장입니다. 이해도 가는 만 이 기능은 아주 유용하고 편리한 기능한 기능이라 반드시 지원이 되었으면 합니다.

 

// 솔리디티 개발환경을 준비합니다.

 

솔리디티 프로그래밍을 위해서는 직접 로컬 컴퓨터상에 솔리디티 컴파일러를 설치하거나 Remix(aka.Brower-solidity) 같은 개발 도구를 사용하는 방법이 있습니다.  Remix 외에도 Ethreum Studio 처럼 여러 개발 툴들이 있으나 Remix가 가장 편리합니다. 왜냐하면 다른 복잡한 것을 설치할 필요없이  브라우져를 통해 항상 최신 버전을 사용할 수 있기 때문입니다

 

Remix를 사용하기 위해 다음의 주소로 접속합니다.  참고로 OSX에서 사파리10.1.1.에서 작동이 원활치 않았고 , 크롬 59.0.3071.115 빌드에서는 사용하는  문제가 없었습니다. 여기서는 크롬을 기준으로 합니다.

 

https://remix.ethereum.org 

 

만약 온라인으로 접속하지 않고 로컬 컴퓨터 상에 Remix를 설치하여 사용하고 싶으면 Remix 소스 코드를 다운로드를 받은  사용하면 됩니다.  다음은  Brower-solidity 의 다운로드 링크입니다.

 

https://github.com/ethereum/browser-solidity/archive/master.zip

 

 

// Remix 를 사용법을 익혀 봅니다.

 

모든 제품을 사용하기 전에 매뉴얼은 한번 읽어 보는  낭패를 당하거나 시간을 낭비하지 않는 지름길이라 생각합니다적어도 어디에 뭐가 있는지는 알아야 제대로 활용할  있듯이 Remix로 솔리디티 개발을 위해서는 Remix 개발 환경에 대한 이해가 반드시 필요하다 생각합니다.  차근차근 살펴보면서 동시에 Solidity 프로그램도 함께 익숙해져 보겠습니다.



[그림 2-1 ] Remix 접속 후 첫화면. 총 3개의 영역(컬럼)으로 구성되어 있다.

 

Remix는 3 영역으로 구성되어 있습니다 - 가장 왼쪽이 소스코드 브라우져 , 가운데가 소스코드 에디터 , 그리고 오픈쪽이 컨트랙의 컴파일  배포, 디버깅, 분석 등 다양한 관련 옵션 등을 처리하는 영역입니다.

 

// 소스파일 브라우져 영역 알아보기

 


[그림2-2] 소스 파일 영역

 

소스 파일 영역에서 <<+버튼 메뉴>>는 신규 파일 생성 , 그리고 <<폴더 버튼>> 로컬 파일 열기 , 그리고 마지막 <<체인 버튼>> 특정 로컬 폴더을 연결하여 사용하는 기능입니다실제 작업을 하다보면 체인 버튼이 아주 유용한데  부분은 나중에 뒤에서 별도로 설명하겠습니다. 최초 설치 후 소스 파일 영약에 제공되는 Ballot.sol Remix에서 제공하는 기본 예제 파일입니다.

 



[그림2-3] 소스 코드 에디터 영역

 

-소스 코드 편집 영역

중간은 소스코드 편집 영역으로 <<+버튼>> 폰트 크기를 크게 ,  <<- 버튼>> 폰트 크기를 작게 해줍니다멀티 파일을 열어서 작업할 수 있습니다.

 

-컨트렉 조정 영역

마지막은 컴파일 및 배포 등 컨트롤 영역입니다.  이 영역을 잘 이해해야 솔리디티 개발을 고생하지 않고 할 수 있습니다. 

 


[그림2-4] 컨트랙 조정 영역

 

컨트랙 조정 영역중 Contract 탭에는 Environment 메뉴가 있는데 3개의 실행 환경 모드를 제공합니다 - Javescript VM , injected Web3 , Web3 provider.

 

다음은 각 실행 모드에 대한 설명입니다.

 

  • Javescript VM - geth 노드 연결 없이 모든 개발이 로컬 컴퓨터의 Remix의 메모리상에서 이루어짐
  • injected Web3 - Mist나 Metamask같이 Mist와 유사한 공급자에 의해 제공되는 실행 환경을 이용
  • Web3 provider - 로컬 컴퓨터에서 작동되는 geth 노드에 연결하여 수행됩니다. 이 환경에서는 트렌젝션이 네트웍을 통해 전달될 수 있음.

 

위의 세가지 환경 중 가장 편리한 것이 Javascript VM입니다. 첫번째 수업해서 설명한 것처럼 보통 개발자가 컨트렉트를 만들고 이를 컴파일한 후 블록체인 상에 배포하고 작동시키기 위해서는 마이닝 작업을 통해 Ether와 Gas가 미리 준비되어 있어야 합니다. 또한 구동중인 Geth 노드에  RPC 로 연결하여 컴파일된 솔리디티 바이트코드를 EVM에 배포하고 이를 다시 이더리움 체인에 연결하기 위해 다시 마이닝하는 등 여러 작업들을 해야 만 트렌젝션의 실행 결과를 확인할 수 있습니다. 다행스럽게도 Remix의 Javascript VM 환경을 이용하면 이러한 모든 작업을 로컬 메모리상에서 Remix 에서 미리 준비해둔 자바스크립트 VM모듈을 통해 수행가능합니다. 따라서 본 수업에서는 Javascript VM 환경을 기본 환경으로 사용합니다. 실제  Javascript VM 환경으로 개발을 하고 이후 Web3 Provider 환경을 통해 실제 로컬에 설치된 geth 노드에 RPC로 연결하여 작업을 하면 편리합니다. 보통 개발자들이 개인 개발 환경에서 작업을 하고 이를 개발 이나 스테이징 환경에 올려서 테스트 하는 것과 동일한 하다고 생각하면 됩니다.

 

***************************************************

$$ 정확히 알고 가자. : Ether와 Gas

 

Remix 에서 <<Contract 메뉴>>를 보면 Gas Limit 이라는 항목이 있습니다. Gas는 한마디로 이더리움에서 트렌젝션을 실행시키기 위해 필요한 수수료입니다. 이더리움에서는 트렌젝션들이 모여 블럭이 되고 , 이 블럭을 체인에 연결하기 위해서는 마이닝 작업을 통해 해쉬 계산을 하고 합의 과정을 거쳐 가장 빨리 계산한 마이너가 해당 블록을 체인에 연결을 합니다. 이러한 블록 하나를 연결할 때 마이너는 현재 0.25 Ether를 받습니다. 또한  해당 블럭내에 있는 트렉젝션을 수행하기 위해 EVM 을 작동시키는 데 드는 대가를 Gas로 받습니다.  

 

트렌젝션 수수료를 Ether로 주지 않고 Gsd라는 단위를 사용하는 이유는 무엇일가요? 바로 Ether는 가상 화폐이기 때문에 변동성이 생길 수 있으나 Gas는 거의 변동이 되지 않습니다. 따라서 트렌젝션을 수행하는 EVM은 계산량에 따라 고정된 Gas 값을 받습니다. 이더리움의 가스 가격의 변동 차트를 보면 거의 변동이 없습니다.

 

https://etherscan.io/chart/gasprice , 이더리움 가스 가격의 변동 차트

 

Gas Limit은 트렌젝션 처리에 쓸 수 있는 Gas 최대 한도비용입니다. 이 비용이 높을 수록 트렌젝션이 우선 처리가 될 수 있습니다. 그러나 트렌젝션 처리시   Gas Limit을 초과하면 트렌젝션이 중단되고 Gas는 그냥 소비되게 됩니다.

 

*****************************************************

 

// 컨트랙트 배포(Create)

 

Remix는 원격지에 있는 solc 컴파일러를 사용하여 컴파일을 합니다. <<Setting메뉴>>에 들어가면 기본값으로 컴파일 옵션이 <<Auto Compile>>로 설정되어 있습니다. 반복해서 주기적으로 컴파일을 하기 때문에 불편하면 해제해 놓아도  됩니다.

 

Contract 탭에서  <<Create 버튼>>는 작성된 컨트랙을 geth 노드에 배포합니다. 물론 Web3 provider 환경에서 배포를 하기 위해서는 RPC설정이 된 상태로 geth가 미리 작동이 되고 있어야 합니다. 또한 컨트렉을 배포할 때 잠시 생각을 해 보면 이런 의문점이 생깁니다. 이더리움은 어카운트가 기본인데 계정은 어떻게 되나? 그리고 컨트랙을 배포할 때는 당연히 비용을 지불해야 하는 데 어떻게 되는 거지?   

 

잠시 생각해 보겠습니다. 먼저 Contract은 원래 Contrace Account 의 줄임말입니다. 따라서 컴파일 후 배포가 되면 자동으로 해당 컨트렉트 계정이 생기고 컨트랙트 주소가 만들어 집니다. 대신 일반 사용자 계정 ( EOAs , Externally Owned Accounts)과는 구별이 됩니다. 실제 컨트렉트 계정은 사용자 계정에 의해서만 작동되고, 작동되면 컴파일된 코드에 의해서만 컨트롤이 됩니다.  그리고 당연히 코드를 이더리움 상에 배포시 대가를 지불해야 합니다. 다행이도 Remix의 Javascript VM환경에서는 이 대가를 Remix 대신 처리를 해주니 별도의 마이닝 작업 등을 할 필요가 없습니다. 물론, Web3 provider 환경에서는 미리 Ether를 할당해 높거나 마이닝을 통해 직접 처리해야 합니다.

 

<<Create 버튼>>을 클릭하여 배포를 하면 아래 [그림2-5]처럼 ballot 컨트렉트를 컨트롤 할 수 있는 다양한 버튼들이 나타납니다. 분홍색으로 표시된 각 트렌젝션들은 실제 해당 값을 입력하여 실행하면 그 결과를 바로 확인할 수 있습니다.

 


[그림2-5] 컨트랙 배포 후 화면

 

// web3 provider 환경 사용하기

 

로컬 컴퓨터 상의 구동중인 geth 노드에 연결하여 사용하고 싶다면 web3 provider 환경 옵션을 선택해야 합니다.  <<web3 provider >>옵션을 선택하면 다음과 같이 로컬에 있는 이더리움 노드와 연결을 원하는 지 다시 한번 묻는 팝업 윈도우가 나타납니다.

 


[그림2-6] <<web3 provider >>옵션 선택 후 팝업 화면

 

<<확인>>버튼을 선택합니다. 다음과 같이 이더리움 노드의 IP 주소와 RPC 포트를 묻는 팝업 윈도우가 나타납니다.

 


[그림2-7] <<web3 provider >>옵션에서 서버의 Endpoting 입력  화면

 

 

로컬 컴퓨터의 IP 주소와 RPC 포트인 8080을 입력합니다. 수업1에서 우리는 이미 다음과 같이 로컬컴퓨터상에서 이더리움 노드를 작동시켜 놓았습니다.

 

MacBook-Pro:go-ethereum jhpark$  geth167 --identity "JayBlockChain" --rpc --rpcaddr "127.0.0.1" --rpcport "8080" --rpccorsdomain "*" --datadir "/Users/jhpark/go-ethereum/go-ethereum-1.6.7/build/bin/privatechain" --port "30303" --nodiscover --rpcapi  "db,eth,net,web3,personal" --networkid 1999 --mine console

 

// 개발시 로컬 폴더 연결하여 활용하기

 

Remix는 웹 기반이기 때문에 작업을 하다 보면 로컬상의 폴더를 연결해서 쓰면 편하겠다라는 생각이 듭니다. 앞서 살펴본 소스 파일 브라우져 영역에서 <<체인 버튼>>이 바로 로컬 파일을 연결하는 기능입니다.

 

해당 <<체인 버튼>>을 클릭하면 다음과 같이 로컬 파일을 연결하겠느냐라는 팝업 윈도우가 나타납니다.

 

[그림2-8] 로컬 폴더를 연결하겠느냐는 확인 팝업 윈도우

 

연결을 위해 <<Connect 버튼>>을 선택하면 다음과 같이 로컬 컴퓨터의 특정 폴더를 연결할 수 있습니다. 연결된 후에는 <<Connect 버튼>>이 녹색으로 변경됩니다.

 

 [그림2-9] 로컬 호스트 상의 특정 폴더를 연결한 후의 모습

 

 그런데 이렇게 특정한 로컬 폴더에 연결을 하기 위해서는 remixd라는 모듈을 설치하고 구동시켜야 만 합니다.


 

 //로컬 폴더를 연결하기 위해 remixd 설치하기

 

 remixd를 설치하기 위해서는 npm 이 필요합니다.  Npm(Node.js package echosystem)은 오픈소스 자바 스크립트 패키지 관리툴입니다. node.js 를 설치하면 자동으로 함께 설치됩니다. 

 

 먼저 , http://nodejs.org 에서 설치 파일을 다운로드 합니다. 제 경우 macOS용 V6.11.2 LTS버전을 다운로드 받아 설치했습니다. 설치 후 npm으로 다음과 같이 remixd 설치합니다.

 

    npm install -g remixd

  MacBook-Pro:~ jhpark$ npm install -g remixd

 

   remixd 설치 후 다음과 같이 Remix에서 연결하여 사용하고 싶은 공 폴더를 -S옵션과 함께 지정하여 remixd 를 구동 시킵니다여기서는 /Users/jhpark/go-ethereum/contracts를 공유하였습니다. 

 

   remixd -S [로컬에서 공유할 폴더 위치]

 

 cBook-Pro:contracts jhpark$  remixd -S /Users/jhpark/go-ethereum/contracts

 [WARN] Any application that runs on your computer can potentially read from and write to all files in the directory.

 [WARN] Symbolinc links are not forwarded to Remix IDE

 Shared folder : /Users/jhpark/go-ethereum/contracts

 Fri Aug 04 2017 09:23:45 GMT+0900 (KST) Remixd is listening on 127.0.0.1:65520

 

 이제 Remix에서 공유한 폴더를 소스 파일 브라우져에서 연동하여 사용할 수 있습니다.


 

 // 첫번째 솔리디티 프로그램 작성 : SimpleStorage.sol 

 

 자 이제 어느 정도 준비가 되었으니 첫번째 아주 간단한 프로그램을 하나 작성하여 작동시켜 보겠습니다.

먼저 , Remix의 파일 브라우져 영역의 <<+ 메뉴>>를 선택하여 새로운 파일을 생성하고 다음의 내용을 입력합니다. 

이 경우 프로그램 파일은 로컬 브라우져 상에 저장이 됩니다. 가장 편리한 방법은 앞서 Remixd를 통해 공유한 

로컬 폴더내에 해당 파일을 원하는 에디터로 작성하는 것 입니다. 일단 파일을 작성하면 자동으로 Remix가 Remixd를

통해 해당 파일을 읽어 옵니다. 제 경우 /Users/jhpark/go-ethereum/contracts 폴더 밑에

SimpleStorage.sol를 vi를 사용하여 작성하였습니다.

 

pragma solidity ^0.4.0;

    contract SimpleStorage {

        uint storedData;

function set(uint x)

        {

            storedData = x;

        }

        function get() constant returns (uint)

        {

            return storedData;

        }

    }

 

위의 예제는 솔리디티 가이드 문서에서 첫번째로 나오는 예제 파일입니다. 보다 자세한 내용은 아래 링크를 참고하세요.

 

참고 : 솔리디티 개발 문서 : https://media.readthedocs.org/pdf/solidity/develop/solidity.pdf

 

작성 후 컴파일시 문법적 오류가 없다면  아래와 같은 화면이 나타납니다. 앞서 설명드린 것처럼 Remix는 auto compile을 합니다 ( <<settings 메뉴>> ).

 




 [그림2-10] SimpleStorage.sol 컴파일 후 화면

 

 이 프로그램은 무척 단순합니다solidity ^0.4.0은 솔리디티 0.4.0으로 작성되었으니 업그레이드된 컴파일러가 나오더라도 이 파일은 0.4.0 방식으로 처리해 달라는 의미이며 , SimpleStorage  라는 이름의 contract는 내부의 상태가 256비트 크기의 unsigned integer 타입인 storedData와 이 상태에 값을 추가하는 set 이라는 이름의 function과 상태의 값을 알려주는 get function으로 구성되어 있습니다. 특별한 사용자 계정에 의해 조작되는 것이 없기 때문에 누구나 SimpleStorage를 이용해서 상태 값을 설정하거나 조회할 수 있습니다.

 

 작동을 시켜 보겠습니다!!.

 

 오른쪽에 <<Create>> 버튼을 눌러 컴파일된 솔리디티 바이트코드를 배포하겠습니다. 배포 후 [2-11] 처럼 화면 하단에 SimpleStorage 컨트렌트의 트렌젝션과 실행 비용에 대한 Gas 비용, 그리고 컨트렉트 주소 등이 나타납니다.

 

 


 [그림2-11] 배포 된 후 SimpleStorage 컨트렉트

 

 그리고 재미나게도 함수 set은 트렌젝션, get은 Call이라고 합니다. 왜 같은 함수를 구별할까요? 제 생각에 트렌젝션은 상태의 변화를 가져오는 것이고 , Call은 상태변화가 없어서 구별하는 것이 아닐까 싶습니다. 이후 계속 맞는 지 확인해 보겠습니다.

  

 

set 트렌젝션에 1000 을 입력하고 버튼을 눌러 작동을 시킵니다. 

 

 [그림2-12] SimpleStorage 컨트렉트의 set 트렌젝션 실행




 set함수 실행 후 get 버튼을 클릭하여 수행하면 다음과 같이 내부의 상태 값이 1000으로 바뀐 것을 확인할 수 있습니다.

 


 [그림2-13] SimpleStorage 컨트렉트의 get 실행

 

 

마치는 말

 

지금까지 본격적인 스마크 컨트랙트 개발에 앞서  Remix를 사용하여 솔리디티 언어로 스마트 컨트랙트를 작성하고 이를 실행하는 등 기본 사항들을 살펴 보았습니다. 다음부터는 본격적으로 솔리디티를 통한 스마트 컨트렉트 프로그래밍에 대해 살펴 보겠습니다. 프로그래밍을 하면서 필요한 개념과 용어는 중간에 지속적으로 소개하도록 하겠습니다. 혹시, 잘못된 내용이나 추가할 내용있으면 지속적으로 알려주시면 수정하도록 하겠습니다. 




저작자 표시 비영리 변경 금지
신고

Posted by 박재현