[컨센시스 아카데미] 이더리움 컨트렉트 소개

in kr •  7 years ago 

안녕하세요~ 날씨가 엄청 시원해졌네요~
이번에는 이더리움 컨트렉트에 대해 간단하게 알아보겠습니다.

이더리움 컨트렉트의 특징은 아래와 같습니다.

  • 단일거래로 블럭체인에 디플로이 됨

  • 변하지않는 주소로 유일하게 식별가능

  • 한번 디플로이되면 코드가 안 변함

  • 트랜젝션을 통해 데이터를 보낼 수 있음

  • 콜포인트를 통해 함수를 제공하는 것처럼 할 수 있음
    -> 이렇게 코딩하면 컨트렉트 데이터 변경 가능
    -> 이렇게 코딩하면 데이터에 대한 정보 호출 가능
    -> 이렇게 코딩하면 특정 공개키 또는 기타 제약조건으로 제한 가능

  • 코드에서 다른 지시가 없으면 2개의 개별 인스턴스는 같은 컨트렉트라도 서로에 대한 정보가 없으며 상호 작용하지 않음

  • 다른 지시가 없으면 주어진 컨트렉트를 추적하는 중앙 등록(central registry)이 없음

  • 특히 컨트렉트 인스턴스가 디플로이된 주소를 잊어버릴 경우 블록체인 바이트 코드나 보낸사람 주소나 다른 방법으로 찾아야 함

배포되기 전, 이더리움 컨트렉트는 자바 클래스 컴파일처럼 바이트코드 바이너리 타입이 필요합니다.

  • 상위언어로 만들어진 코드
  • 이 코드는 컴파일러에 의해 바이트코드와 함수 디스크립트 셋(Application Binary Interface)로 컴파일
  • 바이트코드는 다른 매개변수와 함께 트렌젝션으로 압축
  • 트렌젝션은 어카운트 디플로잉 컨트렉트가 승인
  • 승인 된 트렌젝션이 블록체인에 접수 됨
  • 이 트렌젝션을 수행하는 블록이 마이닝 됨

직접 한번 해보기로 하죠~ 우선 컴파일러를 설치합니다.
$ sudo apt-get install -y solc


[그림 3-1] 컴파일 버전 확인

[그림 3-1] 처럼 “solc --version”을 입력하면 버전을 확인 하실 수 있습니다.
지난번에 “net42” 연습에서 geth로그들 올라가는데 입력하기 불편하셨을껍니다.
$ geth --datadir ~/.ethereum/net42 --networkid 42 console
$ geth attach ipc:/home/XXX/.ethereum/net42/geth.ipc
이렇게 하시면 조금 편한 환경이 될 것입니다. XXX는 각자 컴퓨터 사용자 이름입니다.

Faucet 디플로이를 해볼껀데, 힘든 방법으로 해서 왜 Faucet이 약간의 이더가 필요한지 확인할 수 있습니다. 아래 코드를 “Faucet.sol”로 저장합니다.

pragma solidity ^0.4.11;

contract Faucet {
address public owner;
uint256 sendAmount;

function Faucet() payable {
    owner = msg.sender;
    sendAmount = 1 ether;
}

function getBalance() returns (uint) {
     return this.balance;
}

function getWei() {
    msg.sender.transfer(sendAmount);
}

function sendWei(address toWhom) {
    toWhom.transfer(sendAmount);
}

function getSendAmount() returns (uint256) {
    return sendAmount;
}

function killMe() returns (bool) {
    require(msg.sender == owner);
    suicide(owner);
    return true;
}

function () payable {}

}

뭘 만들꺼냐면 블록체인으로 보내는 바이트코드나 바이너리와 컨트렉트가 디플로이 되면서 상호작용하는 ABI를 만드려고 합니다.
JQ도 인스톨합니다. JQ는 JSON 컨텐츠를 다루는데 도움을 줍니다.

$ sudo apt-get install jq


[그림 3-2] JQ 사용

$ solc --combined-json abi,bin Faucet.sol > Faucet.json
로 보내주고
$ cat Faucet.json | jq '.'
해주면 [그림 3-2]처럼 나오는데 bin key는 바이트코드로 식별되고, abi key는 함수 인터페이스를 설명하고 있는데 사용자에게 친숙한 방식으로 호출 할 수 있습니다.
Geth 콘솔에서 사용하기 위해서 “$ cat Faucet.json”를 입력하면 [그림 3-3] 처럼 나오는데 복사를 해두세요


[그림 3-3] Faucet.json

[그림 3-4] Faucet 콘솔 창 입력

Geth 콘솔 창에서 [그림 3-4]처럼 아까 복사한 것을 붙여줍니다. faucetCompiled변수는 geth 콘솔을 나가면 사라집니다.


[그림 3-5] 컨트렉트 상호작용 준비

사용가능한 메소드를 정의하고 인터페이스에게 전달할껀데 [그림 3-5]처럼 ABI 인터페이스가 문자열 형식으로 작성되었으므로 붙여줍니다. 복잡한 자바스크립트 객체를 볼 수 잇는데 이제부터 Web3 컨트렉트 객체로 참조할 것 입니다. 아직 디플로이 되지 않았기 때문에 이 Web3 컨트렉트 객체는 인스턴스가 아닙니다.
Geth는 컴파일된 컨트렉트를 디플로이하는 기능이 있는데 약간의 이더가 필요합니다. 마이닝을 시작하시고~ [그림 3-6] 처럼 나오게 됩니다.


[그림 3-6] 컨트렉트 디플로이

var deployTransationObject = { from: eth.coinbase, data: "0x" + faucetCompiled.contracts["Faucet.sol:Faucet"].bin, value: web3.toWei(1, "ether"), gas: 1000000 };
var faucetInstancePartial = faucetContract.new(deployTransationObject);

잘 안보일꺼 같아서 크게 한번 더 적었습니다. eth.coinbase 언락은 하셨죠?
컨트렉트가 디플로이 인스턴스를 트렌젝션으로 보내고 Web3 컨트랙트 인스턴스를 반환했지만 주소가 부족하네요. 주소를 즉시 알아야하지만 설정하지 않았기 때문에 아직 채굴되지 않았네요.


[그림 3-7] 컨트렉트 주소 확인

반환된 주소는 우리 컨트렉트의 변경 불가능한 고유한 주소 인데 보낸사람의 트렌젝션 nonce와 보낸사람 주소 해시 값으로부터 계산 됩니다.


[그림 3-8] Faucet 주소 확인


[그림 3-9] 디플로이 위치 코드 확인

[그림 3-9]와 같이 이 코드를 faucetCompiled.contracts [ "Faucet.sol : Faucet"]. bin과 비교하면 deployedBinary의 전체 길이와 일치한다는 것을 알 수 있습니다.

지금까지 이더리움 컨트렉트에 대해서 소개해봤는데요~
조만간? 좀 더 심화된 이더리움 컨트렉트 내용도 포스팅 할 수 있지 않을까?하고 생각해 봅니다~
질문은 언제든지 환영입니다~

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

thanks for information!

you're welcome