개발자가 되고 싶은 사람

[EOS #10] EOS json rpc를 이용한 token transfer

|

1. cleos의 push transaction과 json rpc의 push transaction

  • Terminal의 cleos에서 transaction push 기능으로는 create, transfer, push transaction, push action, buyram, sellram, set contract 등 여러가지 간편한 기능들을 지원한다.
  • cleos에서 EOS가 아닌 Token transfer를 하기 위해선 수행 내용을 json으로 작성하여 push action 기능을 사용해야 한다. 그 외 smart contract의 기능들도 마찬가지다.
  • Json rpc에서의 push transaction은 push_transaction API 단 하나이다.
  • 위의 cleos에서 제공하는 그외 push transaction 기능들을 수행하기 위해선 직접 transaction을 작성하고 서명한 후 push 해야한다.
  • 이 문서에서는 eos-java-rpc-wrapper를 사용하여 push_transaction(Token transfer) 방법을 설명한다.
  • 또한 https://git.doublechain.co.kr/backend/exchange/eos-service-webflux 에 자주 사용하는 push transaction들은 서비스로 만들어 놓을 예정이다.

2. push_transaction의 Parameter

  • push_transaction 과정의 필요한 파라미터는 최신 블록 넘버, 블록 레퍼런스 등등 많으나 여기서는 사용자가 입력해야만 하는 파라미터만 작성하겠다.
  • account, name, permission, actor, walletName, walletPassword, compression, JSON data

  • account : Contract의 생성 계정명이다. 예를 들어 EOS transfer의 경우 eosio.token이며, buyram의 경우 eosio가 account로 들어간다.

  • name : Contract의 action name이다. 예를 들어 EOS transfer의 경우 tansfer이며, buyram의 경우 buyram이 name로 들어간다.

  • permission : 해당 action을 수행하기위한 permission이 들어간다.

  • actor : Contract 수행의 주체가 되는 계정명이다. EOS transfer의 경우 EOS를 전송하려는 계정명이다.

  • walletName : actor의 wallet name이다.

  • walletPassword : actor의 wallet password이다.

  • compression : 작성하는 transaction의 압축여부를 뜻한다. “none” 또는 “zlib”이 들어간다.

  • JSON data : abi를 참고하면 structs의 fields에 있는 json이다. EOS transfer의 경우 아래와 같은 형태를 가진다. {“from”:”doublechain4”,”to”:”doublechainw”,”quantity”:”1.0000 EOS”,”memo”:”transfer test”}

3. push_transaction의 순서

  • push_transaction API를 수행하기 전에 unlock, get_info, get_block, abi_json_to_bin, list_keys, get_required_keys, sign_transaction API들을 수행해야한다.
  • unlock : 해당 wallet을 unlock한다.
  • get_info : chain id와 최신 블럭 번호 정보를 가져온다.
  • get_block : 최신 블럭의 ref_block_prefix 정보를 가져온다.
  • abi_json_to_bin : json data를 binargs로 변환한다.
  • list_keys : wallet의 key list를 반환한다.
  • get_required_keys : list_keys 중의 sign에 필요한 public key를 반환한다.
  • sign_transaction : 위의 data들로 작성된 transaction을 서명한다.

4. Token transfer 예제

  • 위의 내용대로 작성된 token transfer 코드이다.
String account = "oasistokenn1";
String name = "transfer";
String permission = "active";
String actor = "doublechain4";
String walletName = "default";
String walletPassword = "PW5JjqqVLWDTPv2hX6oyFHL7UXe6893qHgC5kqe4araqX4PqHTRQK";

// wallet을 unlock한다.
eosApiRestClient.unlockWallet(walletName, walletPassword);

// chain 정보와 최신 block정보 가져오기
ChainInfo chainInfo = eosApiRestClient.getChainInfo();
Block block = eosApiRestClient.getBlock(chainInfo.getHeadBlockNum().toString());

// account와 name, 그리고 Map으로 만든 json데이터로 binargs 변환하기.
Map<String, Object> map = new HashMap<>();
map.put("from", "doublechain4");
map.put("to", "doublechainw");
map.put("quantity", "1.0000 OAS");
map.put("memo", "Token transfer example");
String binargs = eosApiRestClient.abiJsonToBin(account, name, map).getBinargs();

// wallet의 public key 가져오기
Iterator<List<String>> itr = eosApiRestClient.listKeys(walletName, walletPassword).iterator();
List<String> keys = new ArrayList<String>();
while (itr.hasNext()) {
	keys.add(itr.next().get(0));
}

// transaction 작성
PackedTransaction packedTransaction = new PackedTransaction();
packedTransaction.getActions().add(new TransactionAction());
packedTransaction.getActions().get(0).setAccount(account);
packedTransaction.getActions().get(0).setData(binargs);
packedTransaction.getActions().get(0).setName(name);
packedTransaction.getActions().get(0).getAuthorization().add(new PermissionLevel());
packedTransaction.getActions().get(0).getAuthorization().get(0).setActor(actor);
packedTransaction.getActions().get(0).getAuthorization().get(0).setPermission(permission);
packedTransaction.setRefBlockNum(block.getBlockNum());
packedTransaction.setRefBlockPrefix(block.getRefBlockPrefix());
packedTransaction.setExpiration((((new Timestamp(System.currentTimeMillis() + 30000)).toInstant()).toString().subSequence(0, 20)) + block.getTimeStamp().substring(20));

// 서명에 필요한 key 받아오기
List<String> requiredKeys = eosApiRestClient.getRequiredKeys(packedTransaction, keys).getRequiredKeys();

// transaction에 서명하기
PackedTransaction signedPackedTransaction = eosApiRestClient.signTransaction(packedTransaction, requiredKeys, chainInfo.getChainId());

// 서명된 transaction push하기
System.out.println(eosApiRestClient.pushTransaction(compression, signedPackedTransaction));

// result
{"processed":{"id":"af2c9ac1471e56cf781d914f625e8f7d247da9cca78324c8a52613009981cbda","block_num":4657321,"block_time":"2018-12-21T05:20:09.500","producer_block_id":null,"receipt":{"status":"executed","cpu_usage_us":317,"net_usage_words":18,"trx":null},"elapsed":317,"net_usage":144,"scheduled":false,"action_traces":[{"receipt":{"receiver":"oasistokenn1","act_digest":"f97d029d115699d3f68dff3ada5ad37c2f62aa39c791e9426539d24e9ac23a24","global_sequence":24154506,"recv_sequence":16,"code_sequence":1,"abi_sequence":1},"act":{"account":"oasistokenn1","name":"transfer","authorization":[{"actor":"doublechain4","permission":"active"}],"data":{"from":"doublechain4","to":"doublechainw","quantity":"1.0000 OAS","memo":"OAS token transfer"},"hex_data":"40a6330da978344dc0a7330da978344d1027000000000000044f415300000000124f415320746f6b656e207472616e73666572"},"context_free":false,"elapsed":118,"console":"","trx_id":"af2c9ac1471e56cf781d914f625e8f7d247da9cca78324c8a52613009981cbda","block_num":4657321,"block_time":"2018-12-21T05:20:09.500","producer_block_id":null,"account_ram_deltas":[{"account":"doublechain4","delta":128},{"account":"oasiswkimdev","delta":-128}],"except":null,"inline_traces":[{"receipt":{"receiver":"doublechain4","act_digest":"f97d029d115699d3f68dff3ada5ad37c2f62aa39c791e9426539d24e9ac23a24","global_sequence":24154507,"recv_sequence":115,"code_sequence":1,"abi_sequence":1},"act":{"account":"oasistokenn1","name":"transfer","authorization":[{"actor":"doublechain4","permission":"active"}],"data":{"from":"doublechain4","to":"doublechainw","quantity":"1.0000 OAS","memo":"OAS token transfer"},"hex_data":"40a6330da978344dc0a7330da978344d1027000000000000044f415300000000124f415320746f6b656e207472616e73666572"},"context_free":false,"elapsed":6,"console":"","trx_id":"af2c9ac1471e56cf781d914f625e8f7d247da9cca78324c8a52613009981cbda","block_num":4657321,"block_time":"2018-12-21T05:20:09.500","producer_block_id":null,"account_ram_deltas":[],"except":null,"inline_traces":[]},{"receipt":{"receiver":"doublechainw","act_digest":"f97d029d115699d3f68dff3ada5ad37c2f62aa39c791e9426539d24e9ac23a24","global_sequence":24154508,"recv_sequence":69,"code_sequence":1,"abi_sequence":1},"act":{"account":"oasistokenn1","name":"transfer","authorization":[{"actor":"doublechain4","permission":"active"}],"data":{"from":"doublechain4","to":"doublechainw","quantity":"1.0000 OAS","memo":"OAS token transfer"},"hex_data":"40a6330da978344dc0a7330da978344d1027000000000000044f415300000000124f415320746f6b656e207472616e73666572"},"context_free":false,"elapsed":6,"console":"","trx_id":"af2c9ac1471e56cf781d914f625e8f7d247da9cca78324c8a52613009981cbda","block_num":4657321,"block_time":"2018-12-21T05:20:09.500","producer_block_id":null,"account_ram_deltas":[],"except":null,"inline_traces":[]}]}],"except":null},"transaction_id":"af2c9ac1471e56cf781d914f625e8f7d247da9cca78324c8a52613009981cbda"}
  • 위와 같이 account, name, permission, actor, walletName, walletPassword, compression, JSON data만 있으면 cloes의 transfer, push transaction, push action, buyram 등등의 기능을 수행할 수 있다.

[EOS #2] eos intro/eos 개략적 내용

|

EOS demon

nodeos

  • eos 블록을 생성하는 코어 데몬

cleos

  • 사용자가 컴포넌트들에 접근할 수 있게 해주는 최전방 command-line 툴.
  • 내부적으로 nodeos의 API를 사용한다. cleos -h 명령어

keosd

  • wallet 이라는 단위로 key를 관리할 수 있다.
  • eos의 wallet을 관리하는 데몬.

c, c++

  • EOSIO 기반 블록 체인은 WebAssembly (WASM)를 사용하여 사용자 생성 응용 프로그램과 코드를 실행
  • 현재 WASM으로 컴파일되는 응용 프로그램을 빌드하는 데있어 가장 성숙한 툴체인은 C / C ++ 컴파일러와 함께 clang / llvm입니다.
  • 최상의 호환성을 위해 EOSIO C ++ 툴 체인을 사용하는 것이 좋습니다.

권장 환경

  • 우분투 16.04 (우분투 16.10 권장)
  • 우분투 18.04
  • MacOS Darwin 10.12 이상 (MacOS 10.13.x 권장)
  • ** Windows에서 개발하는 경우 불행히도 현재로서는 Powershell 포트 및 지침을 제공하지 않습니다. 앞으로는 powershell 명령을 추가 할 것입니다. 그 동안 우분투에서 VM을 사용하고 이 VM 내부에 개발 환경을 설정하는 것이 가장 좋습니다.

start my node and setup

  • eos testnet(jungle)접속 및 eos rpc로 접속 test
  • 자세한 접속 정보는 slack에~

start keosd

  • shell : keosd &

Check that Nodeos is Producing Blocks

  • check installation
  • shell : tail -f nodeos.log(각자 해당되는 파일이름으로 확인)(log확인)
  • 나의 경우, jungletestnet 이라는 경로에 들어가 초마다 채굴되는 로그를 확인해 볼 수 있다.

Check the Wallet

  • shell : cleos wallet list
  • response :
Wallets:
[]
  • 이 시점부터 로컬 시스템 (Linux 또는 Mac)에서 명령을 실행할 것입니다.

Check Nodeos endpoints

  • RPC API가 제대로 동작하는지 확인하는 명령어.
  • 1). chain_api_plugin로 제공되는 get_info endpoint 를 확인하기. (Check the get_info endpoint provided by the chain_api_plugin in your browser):
  • http://localhost:8888/v1/chain/get_info

  • 2). 호스트 콘솔에서 아래와 같이 확인할 수 있다.
  • curl http://localhost:8888/v1/chain/get_info

CDT

  • eosio.cdt : EOSIO Contract Development Toolkit (CDT)은 contract compilation과 관련된 도구 모음입니다.
  • 주로 계약을 컴파일하고 ABI를 생성하기 위해 CDT를 사용합니다.

Create Development Wallet

  • 개발환경에서 지갑 생성
  • shell : cleos wallet create --to-console
  • 지갑에 토큰이 저장 되지 않습니다 . 지갑은 암호화 된 파일에 개인 키를 저장하고 트랜잭션에 서명합니다.

1. create a wallet

  • cleos wallet create --to-console

2. open a wallet

  • cleos wallet open
  • cleos wallet list
  • return :
Wallets:
[
  "default"
]

3. Unlock it

  • cleos wallet unlock 명령어 입력후 저장된 password 입력.
  • 만약 정상적으로 unlock이 된다면 아래의 결과 리턴
Wallets:
[
  "default *"
]

4. Import keys into your wallet

  • 개인키를 생성할때 아래 명령어 Generate a private key, cleos has a helper function for this, just run the following.
  • cleos wallet create_key
  • 잘 되면 아래와 같이 리턴함.
  • Created new private key with a public key of: "EOS8PEJ5FM42xLpHK...X6PymQu97KrGDJQY5Y"

6. Import the Development Key

  • 개발 키 가져 오기.
  • 모든 새로운 EOSIO 체인에는 “eosio”라는 기본 “시스템”사용자가 있습니다.
  • 이 계정은 EOSIO 체인의 관리 및 합의를 지시하는 시스템 계약을로드하여 체인을 설정하는 데 사용됩니다.
  • 모든 새로운 EOSIO 체인에는 개발 키가 있으며,이 키는 동일합니다.
  • 시스템 사용자 (eosio)를 대신하여 트랜잭션에 서명하려면이 키를로드하십시오.

Create Test Accounts

  • account

    계정은 블록 체인에 저장되어 보낸 사람 /받는 사람을 식별하는 데 사용되는 권한 모음입니다.
    권한을 구성한 방법에 따라 개인 또는 개인의 그룹이 소유 할 수있는 유연한 권한 구조가 있습니다.
    블록 체인에 유효한 거래를 보내거나 받으려면 계정이 필요합니다.

  • 아래와 같이 생성하면 owner key가 필요하다고 나온다 .
  • cleos create account eosio alice \
cleos create account eosio alice \
>
ERROR: RequiredError: OwnerKey
Create a new account on the blockchain (assumes system contract does not restrict RAM usage)
Usage: cleos create account [OPTIONS] creator name OwnerKey [ActiveKey]

Positionals:
  creator TEXT                The name of the account creating the new account (required)
  name TEXT                   The name of the new account (required)
  OwnerKey TEXT               The owner public key for the new account (required)
  ActiveKey TEXT              The active public key for the new account
  • 계정을 만드는 동안 오류가 발생하면 지갑이 잠금 해제되어 있는지 확인하십시오.
  • cleos wallet list
  • 아래에서 볼 수 있듯이 지갑 이름 옆에 별표 (*)가 있어야합니다.
Wallets:
[
  "default *"
]
  • 어카운트 생성에 대한 더 자세한 정보는 account 생성글 참고

Reference

  • https://developers.eos.io/eosio-home/docs/introduction

[EOS #1] eos 설치 및 testnet 구성

|

Version

  • ubuntu 16.04
  • EOS v1.4.4
  • EOSIO.CDT v1.4.1
  • 2018-12-03

EOS 설치

  • Dependency 설치
# Install the development toolkit
$ sudo apt-get update
$ wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
$ sudo apt-get install clang-4.0 lldb-4.0 libclang-4.0-dev cmake make libbz2-dev libssl-dev libgmp3-dev autotools-dev build-essential libbz2-dev libicu-dev python-dev autoconf libtool git mongodb

# Install Boost 1.67
cd ~/
wget -c 'https://sourceforge.net/projects/boost/files/boost/1.67.0/boost_1_67_0.tar.bz2/download' -O boost_1.67.0.tar.bz2
tar xjf boost_1.67.0.tar.bz2
cd boost_1_67_0/
echo "export BOOST_ROOT=$HOME/boost_1_67_0" >> ~/.bash_profile
source ~/.bash_profile
./bootstrap.sh "--prefix=$BOOST_ROOT"
./b2 install
source ~/.bash_profile

# Install mongo-cxx-driver (release/v3.2)
cd ~
sudo apt-get install curl
curl -LO https://github.com/mongodb/mongo-c-driver/releases/download/1.9.3/mongo-c-driver-1.9.3.tar.gz
tar xf mongo-c-driver-1.9.3.tar.gz
cd mongo-c-driver-1.9.3
./configure --enable-static --enable-ssl=openssl --disable-automatic-init-and-cleanup --prefix=/usr/local
make -j$( nproc )
sudo make install
git clone --depth 1 -b releases/v3.2 https://github.com/mongodb/mongo-cxx-driver
cd mongo-cxx-driver/build
cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local ..
sudo make -j$( nproc )
  • Build EOS
# Build EOS
cd ~
git clone https://github.com/EOSIO/eos --recursive
cd eos
git checkout v1.4.4
git submodule update --init --recursive
./eosio_build.sh

EOS TEST

  • EOSIO Build Test
cd ~/eos/build
make test
  • Fail이 난 테스트가 있을 시 ctest –output-on-failure 로 에러로그를 볼 수 있다.
  • ctest –output-on-failure -R <regex> 명령어로 특정 테스트만 진행할 수 있다.
  • test 완료시
cd ~/eos/build/
sudo make install

EOSIO.CDT

  • 설치
git clone --recursive https://github.com/eosio/eosio.cdt
cd eosio.cdt/
git checkout v1.4.1
git submodule update --recursive
./build.sh
sudo ./install.sh

EOS Junglenet

  • https://github.com/CryptoLions/EOS-Jungle-Testnet 에서 Jungle2.0 Testnet의 정보를 얻을 수 있다.
  • http://monitor.jungletestnet.io/#register 에 접속하여 Register your EOS Node 1/2 에 정보를 기입하면 Register your EOS Node 2/2 의 wget으로 설치 스크립트를 다운받을 수 있다.
cd ~
mkdir jungle
cd jungle/
wget https://api.monitor.jungletestnet.io/launchers/installJungle-[Producer Account].sh && \
chmod u+x installJungle-[Producer Account].sh
sudo ./installJungle-[Producer Account].sh
  • ~/jungle/JungleTestnet-[Producer Account]/ 디렉토리의 start.sh와 stop.sh로 nodeos 실행, 종료할 수 있다.
  • cleos.sh로 cleos기능을 수행할 수 있다.
  • Register your EOS Node 1/2의 HTTP server address를 0.0.0.0:8888 이 아닌 로컬 ip로 작성하였을 경우 cleos.sh의 ip를 변경해야 한다.

[EOS #6] EOS Account 생성법

|

1. key를 먼저 생성(public,private)

  • $ cleos create key --to-console 입력
  • 아래처럼 결과값이 나옴
Private key: 5JJ6zBcmzhPptXh54Z4uYbfRt2qabudhM4c8MK9Mvg5t.....
Public key: EOS7Vf5LLigBmbsZb1Xq6aUfcEXQEEiqmyt7khbN.....

2. 생성된 key들을 잘 보관하고, Private key를 default wallet에 import 시킨다.

  • cleos wallet import 를 입력
  • 그 뒤 private key를 넣으라면 문구가 나오고 , 위에서 생성한 private key를 입력하면 된다.
    private key 생성후 아래의 문구가 나온다.
    private key: imported private key for: EOS7.....

3. create account 명령문 입력(issue)

$ cleos create account doublechain4 wkimdevchain EOS7Vf5LLigBmbsZb1Xq6aUfcEXQEEiqmyt7khbNu5hyq....

  • 그러면 아직 해결하지 못한 아래 에러가 나온다.
Error 3080001: Account using more than allotted RAM usage
Error Details:
account wkimdevchain has insufficient ram; needs 2996 bytes has 0 bytes
  • (*글 업로드 이후에 해결함, ) ==> 두번째 이슈 해결방법 참고
  • 이상하게도, 정글넷에서 위에서 생성된 public key를 active, owner key로 같게 생성하면 account가 잘 생성된다.
  • 정글넷에서 생성하는 경우
    account_create

  • 생성된 계정에 fauset으로 토큰을 보낸뒤 계정을 잘 사용하면 된다.
  • 2번 3번의 순서가 바뀌어도 된다.

4. default wallet에 import된 private key확인하기

  • $ cleos wallet private_keys
  • 위의 명령어를 입력한뒤 지갑의 password를 입력하면 현재 default wallet에 있는 private key리스트들을 확인해 볼 수 있다.

또 다른 예외상황

  • 만약 create 할 account의 name 길이가 12자리 미만이면 아래의 에러 메세지를 던진다.
  • $ cleos create account doublechain4 wkimdevchan EOS7Vf5LLigBmbsZb1Xq6aUfcEXQEEiqmyt7khbNu5hyqxG....
  • no active bid for name..아직 정확한 의미 파악은 못하고 지나갔다.
Error 3050003: eosio_assert_message assertion failure
Error Details:
assertion failure with message: no active bid for name
pending console output:

[EOS #5] EOS Account vs 타암호화폐 Account

|

이오스와 타암호화폐와의 계정 개념 차이

  • 타암호화폐는 지갑에서 생성한 주소랑 비번이 즉각적으로 효력이 나타나며 바로 사용이 가능하지만, 이오스는 그렇지 않다.
  • 스팀과 비슷한 원리(스팀도 오너키 액티브키..존재)
  • 스팀과 이오스는 사람이 읽을 수 있는 계정명을 가지고 있고 이것을 블록체인에 **키**와 함께 연동해서 등록시키는 과정이 필요하기 때문.
  • 사실 스팀아이디를 예를 들어… wkimdev라는 아이디가 있다면, 이는 실제로는 블록체인에선 wkimdev라는 아이디와 함께 다른 암호화폐처럼 a12Hasdlfkjs…~ 이런 고유주소가 연동되어 기록되어 있다.

이오스 계정의 블록체인 등록

  • 그래서, 결국 계정을 블록체인에 기록하기 위해선 ‘전송’이라는 과정이 필요하다.
  • 그런데 블록체인에 전송하려면 주소와 비번이 있어야 접속해서 전송이 가능하다.
  • 결국 계정을 등록하기 위해, 블록체인에 접속할 계정이 필요하게 된 것.
  • 그래서 이를 대신 해주는 서비스도 존재한다

(유료) EOS Account Creator
(무료) https://www.zeos.co/en/home

  • 한번 계정을 만들면 자신도 계정이 생기기 때문에 다른 계정을 등록하는데 문제가 없어진다.
  • 서비스를 이용해 계정을 생성하게 되면 아이디랑 주소는 노출되지만 실질적으로 중요한 비밀번호는 건네주지 않기 때문에 보안문제는 없다고 볼 수 있다.

Reference

  • https://steemit.com/kr/@twinbraid/6jsubg-01