[블로그 번역] 히치하이커의 Waves 스마트 컨트랙 가이드 2부

in #coinkorea6 years ago (edited)

1D8C38AB-DF94-4237-AE61-7F836D74FC47.jpeg

지난 9월10일 Waves 플랫폼은 새로운 버전의 노드를 출시했습니다.플랫폼 최초로 자체적인 스마트 컨트랙 구현을 지원하는 노드입니다.1부에서는 Wave 스마트 컨트랙의 아이디어는 물론 현존하는 다른 솔루션들과의 차이점은 무엇인지 집중해서 살펴보았습니다.2부에서는 스마트 컨트랙 언어와 개발자들의 위한 도구에 대해서 좀더 살펴볼까 합니다.이 글은 기술적내용을 담고 있으므로,이해하기에 어려움을 느끼신다면 부디 1부를 먼저 읽어주시길 바랍니다.이글을 작성하는데 도움을 준 Waves 리서치 기술자 Nazim Faour 감사를 표하는 바입니다.

1부에서 가장 중요한 내용은 아래와 같습니다.

일단 스마트 계정이란 트랜잭션을 검사하는 스크립트가 더해진 계정이라고 할수 있습니다.다시 말해 스크립트가 더해진 계정입니다.그렇기에 계정은 모든 트랜잭션에들에 대해 컨펌을 내리기전 유효성 검증을 하는것이 가능합니다.

스마트 계정을 위한 Waves 컨트랙은 항상 True 또는 False 로서 돌아오게 됩니다.

가스와 수수료에 대하여.

기술적 부분에 들어가기에 앞서서,가스와 수수료에 대해서 이야기 해볼까 합니다.스마트 컨트랙에 개발에 임할떄 우리 스스로가 정한 주요 목표중에 하나는,간단한 작업을 할떄는 가스라는 요소가 들어가지 않게 하는것입니다.아예 수수료가 없다는 뜻은 아닙니다.마이너들이 컨트랙을 계속 실행하기 위한 인센티브가 있어야 하니까요.우리는 이 가스라는 문제를 실질적인 관점에서 해결하였습니다.우리는 성능 테스트를 하여 다양한 작업들의 실행속도를 계산해 내었습니다.JMH를 이용하여 구축된 벤치마크를 사용하였고 결과는 이곳에서 보실수 있습니다.우리의 접근방식에 대한 결과로서 논-튜링 컴플리트 스마트 계정에는 가스가 필요하지 않게 되었습니다.고정된 수수료만을 필요로 합니다. 또한 벤치마크는 다음과 같은 몇 가지 제약으로 이어졌습니다.

  1. 스크립트 사이즈는 8kb이상이 될수 없습니다.그리고 서명확인이 20번 이뤄지는 속도보다 빨라야 합니다.두번쨰 사항의 의미는 스마트 계정의 식별은 일반계정보다 20배 이상 느려져서는 안된다는 것을 뜻합니다.
  2. 스마트계정은 각 트랜잭션마다 0.004WAVES 의 추가적인 수수료를 지불하게 됩니다.즉 Waves 네트워크에서 최소수수료는 일반계정은 0.001WAVES,스마트 계정은 0.005WAVES 입니다.

RIDE 언어

스크립트 (컨트랙) 은 RIDE언어를 사용하여 작성되어야만 합니다.RIDE 는 논 튜링 컴플리트 lazy,strong typed, statically typed expression-based 의 언어입니다.이 기능들은 간편성과,풍부한 표현성,그리고 버그로 부터 자유롭게 해주는 기능들입니다.
RIDE는 F#와 함께 사용된 Scala의 영향을 받았습니다.(Waves 노드는 Scala로 작성되었습니다.)문서자료를 통해서 표준 라이브러리(내장된 기능들)와 데이터 타입에 대한 전체설명을 찾으실수 있습니다.

가장 흥미로운 기능은 패턴 매칭(pattern matching)입니다.이는 다른 종류의 트랜잭션들을 위한 다른 조건들을 작성하는 용도로 아주 편리하게 사용될 수 있씁니다.

BC1F1BB9-762B-4D07-91E8-F2D20B2B3B6A.jpeg
전송과 대량전송 트랜잭션만을 허용하도록 하는 명령어.

RIDE 가 어떻게 작동하는지에 대해 관심이 있으시다면,백서에서 더 자세한 사항을 보실수 있습니다.모든 단계에 대한 설명들이 쓰여져 있습니다.(parsing, compilation, deserialization, cost computation, evaluation)
설명하기 쉽도록 말하자면 첫번쨰 두 단계는 오프체인이며, deserialization, cost computation, evaluation은 온체인입니다.

Waves 스마트 계정 시작해 보기.

그러면 가장 흥미롭고 재미있는 부분을 시작해 봅시다.스마트 계정에 사용될 우리의 최초의 스마트 컨트랙을 한번 작성해 보죠.아주 간단한 예시로서 3명중에서 2명의 서명을 필요로 하는 다중서명 계정을 만들어 보겠습니다.다중서명이란 트랜잭션의 실행에 최소 2명의 서명을 필요로 하게 하는 기능입니다.

waves 스마트 컨트랙을 작성하고 싶으시다면 우리의 IDE를 이용하셔야 됩니다.새로운 파일을 만드시려면 클릭 New->Empty Contract 를 선택하십시오.

첫번째 단계로서,앨리스,밥,쿠퍼의 공개키에 대한 정의를 내립시다.이들 세명이서 계정을 관리하되 세명중 최소 2명의 서명이 있어야만 트랜잭션을 보낼수 있습니다.
0EAA2755-0C12-46AB-A71C-110EB7608CD1.jpeg

문서자료를 보시면 sigVerify 기능을 찾으실수 있습니다.이것은 서명을 체크하게 하는 기능입니다.
27EEECEF-7855-4D51-8BED-2AAA9FBC8D3D.jpeg

sigVerify 는 트랜잭션의 body,서명,공개키를 다루게 됩니다.트랜잭션 데이터를 담고있는 오브젝트 tx가 있습니다.트랜잭션을 체킹하는 bytes와 함께 tx.bodyBytes 필드가 있습니다.그리고 서명의 배열을 다루는 tx.proofs가 있습니다.(8까지)

두번째 단계로서 올바른 순서로 서명을 체크해 봅시다.
E7162658-6967-41E4-B5FF-5EE8AED16C65.jpeg

마지막 단계로서 2개 이상의 서명이 있는지 체크해 봅시다.
A775804A-8807-49EF-9915-19C01FC7561D.jpeg

이게 전부입니다.RIDE로 작성한 3개의 서명중 2개를 필요로하는 하는 컨트랙이 준비되었습니다.IDE로 부터 적합한 버전을 받거나,콘솔에서 바로 배치시킬수도 있습니다.최신 버전의 콘솔 커맨드는 문서자료에서 찾을수 있습니다.그리고 다음은 사용례에 대한 영상입니다.


이제 다중서명의 예제로 마무리하겠습니다. 전체 컨트랙 목록은:

Let’s wrap up with our multisignature example. Whole contract listing:
let alicePubKey  = base58'B1Yz7fH1bJ2gVDjyJnuyKNTdMFARkKEpV'
let bobPubKey    = base58'7hghYeWtiekfebgAcuCg9ai2NXbRreNzc'
let cooperPubKey = base58'BVqYXrapgJP9atQccdBPAgJPwHDKkh6A8'
let aliceSigned  = if(sigVerify(tx.bodyBytes, tx.proofs[0], alicePubKey  )) then 1 else 0
let bobSigned    = if(sigVerify(tx.bodyBytes, tx.proofs[1], bobPubKey    )) then 1 else 0
let cooperSigned = if(sigVerify(tx.bodyBytes, tx.proofs[2], cooperPubKey )) then 1 else 0
aliceSigned + bobSigned + cooperSigned >= 2

참고: return statement는 없습니다..컨트랙의 마지막라인은 결과값입니다.
비교대상으로서 이더리움의 일반적인 다중서명은 아래와 같습니다.

pragma solidity ^0.4.22;
contract SimpleMultiSig {
uint public nonce;                 // (only) mutable state
uint public threshold;             // immutable state
mapping (address => bool) isOwner; // immutable state
address[] public ownersArr;        // immutable state
// Note that owners_ must be strictly increasing, in order to prevent duplicates
constructor(uint threshold_, address[] owners_) public {
  require(owners_.length <= 10 && threshold_ <= owners_.length && threshold_ >= 0);
  address lastAdd = address(0);
  for (uint i = 0; i < owners_.length; i++) {
    require(owners_[i] > lastAdd);
    isOwner[owners_[i]] = true;
    lastAdd = owners_[i];
  }
  ownersArr = owners_;
  threshold = threshold_;
}
function execute(uint8[] sigV, bytes32[] sigR, bytes32[] sigS, address destination, uint value, bytes data) public 
{
  require(sigR.length == threshold);
  require(sigR.length == sigS.length && sigR.length == sigV.length);
  bytes32 txHash = keccak256(byte(0x19), byte(0), this, destination, value, data, nonce);
  address lastAdd = address(0); // cannot have address(0) as an owner
  for (uint i = 0; i < threshold; i++) {
    address recovered = ecrecover(txHash, sigV[i], sigR[i], sigS[i]);
    require(recovered > lastAdd && isOwner[recovered]);
    lastAdd = recovered;
}
// If we make it here all signatures are accounted for.
// The address.call() syntax is no longer recommended, see:
// https://github.com/ethereum/solidity/issues/2884
  nonce = nonce + 1;
  bool success = false;
  assembly { success := call(gas, destination, value, add(data, 0x20), mload(data), 0, 0) }
  require(success);
}
function () payable public {}
}

스마트 계정에서 데이터 트랜잭션이 가지는 중요성

데이터 트랜잭션은 임의의 데이터를 키값 페어로서 저장하기 위해서 설계되었습니다.또한 계정(주소)와도 연결되어 있습니다. 각 값에는 연관된 데이터 유형이 있습니다.데이터 유형에는 4가지, boolean, integer, string, 그리고 byte array가 있습니다.여러분의 컨트랙안의 데이터 트랜잭션으로 부터 데이터를 가져오는것이 가능합니다.

위의 간단한 예시를 통하여 어떻게 데이터 트랜잭션으로 부터 데이터를 읽어내고,값에 따른 외부의 트랜잭션의 유효성을 검증하는지 알수 있습니다.오라클과 실생활 데이터 어플리케이션용으로 아주 유용합니다.이에 대해서는 다른글에서 한번 다루도록 하겠습니다.

추가 학습자료들

문서자료

  1. Waves 스마트 계정에 대한 전체내용은 이곳에서 찾으실수 있습니다.
  2. RIDE 언어는 다양한 데이터 타입들을 지원하며,거기에 관한 내용은 이곳에서 찾으실수 있습니다.
  3. addressFromPublicKey 그리고 sigVerify 외에도 많은 기능들이 내장되어 있습니다.RIDE에 내장된 기능들을 모든 목록들은 여기에서 찾으실 수 있습니다.

튜토리얼들

  1. [여러 계정에 의해서 배포 및 서명되는 다중 서명(JS 라이브러리를 사용)](Multisignature with deploying and singing by different accounts (using JS library))
  2. 애스크로에의 사용(자바 라이브러리를 사용)

도움이 필요하실경우 찾아오시면 되는곳들

Waves 커뮤니티는 언제든지 당신에게 도움을 주고 질문에 대한 답변들을 가능한한 가장 빠르게 줄수 있는 준비가 되어있습니다.

  1. 디스코드
  2. 포럼
  3. 텔레그램 채널
  4. 깃헙

다음단계는 무엇입니까?

Waves 스마트 컨트랙의 다은 개발단계는 튜링 컴플리트 언어(또는 시스템)입니다.이를 이용하면 모든 종류의 작업들을 해결하는것이 가능합니다.Waves 생태꼐에서의 스마트 컨트랙에 관한 또 다른 흥미로운 아이디어는 스마트 자산입니다.작동방식은 토큰에 접목시킬수 있는 논 튜링 컴플리트 컨트랙과 비슷합니다.예를 들어 스마트 자산을 시용하면 특정 블럭높이까지 토큰을 보유하게 하거나,P2P거래를 금지 시키는것이 가능합니다.스마트 자산에 관한 자세한 사안은 이곳에서 찾아보실 수 있습니다.

최신 출시버전에 스마트 자산은 포함되어 있지 않습니다.그러나 Waves의 코드베이스에는 이미 구현되어 있습니다.만약 아이디어나 사용사례들을 보유하고 계시다면 댓글을 남겨주시길 바랍니다.관련하여 기꺼이 의견을 나누도록 하겠습니다.


Waves 홈페이지: https://wavesplatform.com/
Waves 텔레그램방: https://t.me/WavesKR
Waves 카카오톡방: https://open.kakao.com/o/g7rnUsM
Waveskorea 트위터: https://twitter.com/waves_korea