CodeChain SDK in Golang

Seongjae Choi
코드체인
Published in
8 min readJan 29, 2020
Image from https://github.com/egonelbre/gophers

CodeChain SDK Go의 첫번째 버전을 공개합니다! JavaScript 버전으로만 존재하던 SDK가 Go버전으로도 제공됩니다. 이제 CodeChain을 사용하는 Go언어 어플리케이션을 개발할 수 있게 되었습니다.

Go언어는 읽기 쉽고 단순한 syntax를 가지고 있습니다. 인터프리터 언어의 용이성과 컴파일 언어의 안정성 양쪽 모두를 잡는 방향으로 개발되었습니다. 컴파일 결과가 하나의 바이너리로 나오고, 컴파일 시간도 다른 언어들에 비해 빠릅니다. garbage collection, memory safety, strongly typed와 같은 장점 때문에 많은 프로그래머들에게 사랑받고 있죠.

현재 버전의 Go-SDK로는 CodeChain에서 제공하는 모든 RPC 함수를 사용할 수 있습니다. RPC 함수를 쓸 수 있다면 CodeChain에서 제공하는 모든 기능을 사용할 수 있습니다. 하지만 이것만으로 CodeChain을 사용하는 어플리케이션을 개발하기에는 불편한 점이 있습니다. RPC 함수가 어떤 타입의 객체들로 통신하는지, 서명을 하는 과정이 어떻게 되는지 알기 위해 문서를 자세히 읽어봐야 하고 디버깅도 어렵습니다. Go-SDK에서는 개발자에게 편한 인터페이스를 제공하기 위해 많은 helper function들을 제공합니다.

패키지 설명

Go-SDK는 크게 6개의 패키지로 구성되어 있는데, 각 패키지별로 제공하는 기능들은 다음과 같습니다.

1. rpc

rpc 패키지는 CodeChain에 정의된 모든 RPC 함수를 호출할 수 있는 기능을 제공합니다. 각 함수는 RPC의 종류에 따라 Account, Chain, Devel, Engine, Mempool, Net으로 나누어져 있습니다.

2. primitives
primitives 패키지는 CodeChain에서 사용하는 기초 타입과 함수들을 정의하고 있습니다. 64, 128, 256 비트 정수와 128, 160, 256, 512비트 데이터 타입이 제공됩니다. 또한, bech32 encoding/decoding 함수가 정의되어 있고, bech32 인코딩으로부터 PlatformAddress, AssetAddress를 계산할 수 있는 함수도 제공됩니다.

3. vm
vm 패키지는 CodeChain 가상 머신 스크립트의 encoding/decoding 함수를 제공합니다. 이 패키지를 이용하면 CodeChain 스크립트를 쉽게 작성할 수 있습니다.

4. crypto
crypto 패키지는 CodeChain에 사용하는 ECDSA, Blake, Ripemd 함수 등 암호와 관련된 기능을 제공합니다. 대표적으로 해쉬함수와 서명, 검증 함수 등이 있습니다. 이 패키지는 트랜잭션을 생성할 때 거의 필수적으로 필요한 패키지입니다.

5. key
key 패키지는 CodeChain에 사용되는 key와 관련된 함수들을 제공합니다. ECDSA 개인키로부터 공개키를 얻거나 P2PKH LockScript와 UnlockScript를 이 패키지로부터 구할 수 있고, AssetAddress와 PlatformAddress도 생성할 수 있습니다.

6. core
core 패키지는 CodeChain에 트랜잭션을 전송할 수 있도록 트랜잭션의 종류별로 다양한 함수와 객체들을 제공합니다. 현재는 Pay, MintAsset, TransferAsset 세 가지 트랜잭션만 지원하지만 앞으로 모든 종류의 트랜잭션을 생성할 수 있도록 업데이트 할 것입니다.

튜토리얼

간단한 튜토리얼을 통해 Go-SDK를 직접 사용해보겠습니다. Go-SDK의 사용 방법을 보여드리기 위해 테스트 환경의 CodeChain에서 CCC를 다른 계정으로 보내는 예시를 설명하겠습니다.

우선 CodeChain 저장소에서 release된 CodeChain 바이너리를 받습니다. 그리고 solo 옵션으로 CodeChain을 실행합니다. solo 옵션은 단일 머신 CodeChain solo 테스트넷을 생성해줍니다. solo 테스트넷의 RPC 노드 주소는 http://localhost:8080입니다.

CodeChain을 solo로 실행한 화면

Go-SDK를 사용할 수 있도록 Go언어 환경을 세팅합니다. Golang 홈페이지에서 최신버전 Go언어 바이너리(1.13)를 다운받고 아래 명령어로 CodeChain의 Go-SDK를 다운로드 받습니다.

go get -u github.com/CodeChain-io/codechain-sdk-go

Go-SDK를 사용할 수 있는 환경 준비가 모두 끝났습니다. 이제 Pay 트랜잭션을 만들어보겠습니다. Pay 트랜잭션은 CCC를 다른 계정으로 보내는 트랜잭션입니다. 아래 PlatformAddress와 비밀키는 CodeChain solo의 제네시스 블록에 올라가 있으며 10000000000000000000CCC가 기본으로 제공됩니다. 이 PlatformAddress에서 CCC를 다른 PlatformAddress로 옮겨보겠습니다.

PlatformAddress: tccq9h7vnl68frvqapzv3tujrxtxtwqdnxw6yamrrgd
비밀키: ede1d4ccb4ec9a8bbbae9a13db3f4a7b56ea04189be86ac3a6a439d9a0a1addd

CCC를 받게될 새로운 PlatformAddress를 생성해보겠습니다. key 패키지의 createPlatformAddress 함수를 사용하면 됩니다. solo의 networkID는 “tc”를 사용하는 것을 참고하여 Go 코드를 작성하면 아래와 같습니다. 실행하면 ECDSA키 쌍과 PlatformAddress가 출력됩니다.

PlatformAddress를 생성하는 Go 코드
https://gist.github.com/cubismic/a180b2ffb76eef3db5e9ce3ded682302 를 실행한 화면

체인에 등록할 수 있는 Pay 트랜잭션을 만들기 위해서는 받을 사람과 받을 양을 설정하고 보내는 계정으로 서명을 해줘야 합니다. 서명을 할 때는 보내는 계정의 비밀키와 sequence number가 필요합니다. sequence number는 CodeChain RPC의 Chain.GetLatestSeq 함수를 통해 구할 수 있습니다. 서명된 트랜잭션의 RLP 인코딩을 solo의 RPC로 보내주면 Pay 트랜잭션이 체인에 포함됩니다. 아래 코드가 이 과정을 나타낸 것입니다.

pay transaction 을 만들어 보내는 Go 코드

15번 줄에서 solo의 RPC 주소를 통해 rpcClient를 초기화합니다. 그리고 18번 줄은 위에서 언급한 계정의 주소와 비밀키입니다. 21번 줄에서 앞서 생성한 받을 주소를 적습니다. 그리고 보낼 양(quantity)과 수수료(fee) 그리고 보내는 사람의 sequence number(seq)를 가져옵니다.

27번 줄에서 받을 사람, 받을 양을 이용해 Pay 트랜잭션을 만듭니다. 그리고 보내는 사람의 개인키, seq와 fee를 이용해 서명합니다. 그리고 30번째 줄에서 Mempool.SendSignedTransaction 함수를 이용해 RPC 노드에 Pay 트랜잭션을 보내줍니다. 만약 트랜잭션 전송에 실패한다면 33번 줄에서 에러의 이유를 출력할 것입니다. 트랜잭션 전송에 성공했다면 트랜잭션의 hash가 출력됩니다.

작성한 Go코드를 실행해주고 CodeChain solo를 실행하는 터미널에서 위와 같이 Imported sealed block 메시지가 보인다면 트랜잭션이 포함된 새로운 블록 생성에 성공한 것입니다! 블록 정보를 확인하고 싶다면 RPC 중 Chain.GetBlockByNumber 함수를 사용하면 됩니다. 코드는 아래와 같습니다.

solo에서 1번 블록의 정보를 출력하는 Go코드

소개글을 마무리하며

Go-SDK의 첫번째 릴리즈 버전은 자바스크립트 버전과 비교해 구현하지 못한 것이 많습니다. keystore가 구현되지 않아 유저가 비밀키를 따로 저장하고 있어야 합니다. 그리고 현재 Go-SDK에서는 Pay, MintAsset, TransferAsset 세 가지 트랜잭션만 만들 수 있습니다. 이 세 종류의 트랜잭션으로 CodeChain에서 Asset을 발행하고 보내볼 수 있는 최소한의 조건이기 때문에 우선적으로 지원하였습니다. 이후 ChangeAssetScheme, IncreaseAssetSupply, WrapCCC 등 많은 종류의 트랜잭션들을 생성하여 노드에 보낼 수 있도록 helper function들을 추가할 예정입니다.

--

--