2019년 7월 28일 일요일

Davinci Resolve - 3D 레고 효과 주기

                                        FXMesh3D1(Brick.fbx)
pImageEmitter - Render1 - Replicate3D1 - Merge3D1 - Renderer3D1 - Merge
                                                              Camera3D1  Background2

연결이 잘 안된다면, 타임라인 가서 영상을 다시 클릭해주자
프록시 연결하지말고 작업하자. (나중에 다시 조절해야함)

1280x720 기준
pImageEmitter 에서 X Density, Y Density 조절 (양 조절) - 0.1
FXMesh3D1 - size 0.005
Replicate3D1 Scale - 0.01 (조절하기). X 로테이션 90도로 조절하기
pImageEmitter 에서 Alpha Threshold 값 조절하기 0.8 - 늘리면 애매한 투명한 애들이 삭제된다. 근데 이거 잘 안되는거같다 성능때문인가?
 Create Particles Every Frame 을 체크해주고 pCustom 을 만들어서 if 로 Alpha Expression 에서
 if(a<0 .5="" 0="" 1="" p="">
BrightnessContrast 알파 체크, 게인을 0으로 주면 사진 사라짐.
폴리곤 연결한다음, Y 축 기준으로 움직이게 함

pImageEmitter1 에서 Lifespan 을 최대로 줌

Camera3D 만들고 각도 잡은다음, perspective - Copy PoV to Camera3D1



2019년 3월 27일 수요일

루트스탁 (RSK) 개념 잡기


루트스탁(RSK)

단순히 비트 코인에 튜링 완전한 스마트 컨트랙트를 올릴수 있게 하는 것으로 알려져 있습니다...만!

현재 RSK 자체가 비트코인을 기본 통화로 사용하고 있고, 2way peg 를 통해1 RBTC = 1 BTC 고정 전환된다는 것일 뿐,

사실상 그 개념 자체는 비트코인 종속적이지 않으며 다른 곳에서도 사이드 체인으로써 동작 가능합니다.

(2way peg에 대해서는 조금 이따 다시 한번 알아보도록 하죠.)

스마트 컨트랙트가 이더리움에서 처음 등장한 것으로 알려져 있지만,
사실 비트코인 스크립트라는 이름으로 이미 존재하고 있었습니다.
(사실 스마트 컨트랙트라는 개념은 비트코인 이전에 이미 존재하던 것이긴 합니다. 빌게이츠 )

그러나 Bitcoin Script는 DoS 공격을 우려한 나머지 Loop 를 지원하지 않아 튜링 완전하지 않았습니다.

그렇다면 튜링 완전하다는 것은 무엇일까요 ?
튜링 머신과 같은 성능을 낼 수 있으면 튜링 완전하다고 봅니다.

그렇다면 튜링 머신은 무엇일까요?
튜링이 1939년에 제시한 하나의 개념입니다.

길다란 테이프가 있고, 테이프 칸 각각에는 지시가 적혀있는 기계를 떠올려 봅시다.



기계는 테이프를 한칸씩  읽으면서 지시를 따라하는 것이죠.

지시는 상태에 따라 다른 테이프의 지시를 변경할 수도 있습니다.

  • '현재 상태가 A인데 기호 '1' 을 읽었다면 '0' 을 기록하고 현재 상태를 E로 바꾼 후 앞으로 한칸 이동.'



이 개념 어디서 많이 본 것 같은데 뭐죠? 컴퓨터입니다. 튜링은 천재였죠

(나의 노트북 == NASA 의 슈퍼컴퓨터 == 튜링 머신... 개념은 똑같다.)

간단히 말해서, 모든 계산 가능한 문제를 풀 수 있는가? 
Yes -> 튜링 완전 하다!

※튜링 머신에 대한 좀 더 자세한 내용 : Gödel : A Life of Logic


RSK의 역사는 아래와 같은데요,

2013년 튜링 완전한 언어 개발
2015년 백서 생성
2016년 테스트넷 펀딩 및 런칭
2017년 메인넷 펀딩
2018년 메인넷에 런칭

비트코인에 올라가는 RSK 는 튜링 완전합니다.

왜냐하면 이더리움을 기반으로 하고 있기 때문입니다.

RSK 는 코드 실행을 위해 RVM이라는 가상 머신을 사용하는데, RVM은 EVM을 가져와서 비트코인에 올라갈 수 있도록 포팅한 것입니다.


그럼 어떻게 이 체인을 유지하고 1 RBTC <=> 1 BTC Transfer 를 지원하는지 아까 제쳐 두었던 2 way peg 개념을 먼저 확인해 봅시다.

2 way peg 

이것은 어쩌면 잠깐의 눈속임이라고 할 수 있겠습니다.

비트코인을 lock 시켜두고, 이후에 사이드 체인에서 같은 양의 코인을 unlock 함으로써

마치 비트코인이 사이드체인으로 옮겨간 것 처럼 보이게 하는 것입니다.

약간은 플라즈마와 닮았네요.

2 way peg는 Side chain, Multi sig, Drive chain등으로 구현할 수 있는데요.

RSK는 Side chain + Drive Chain 의 조합의 Hybrid Chain 으로 Merged Mining 으로 체인을 유지합니다.

더 자세한 내용은 다음 글에서 확인해보도록 하죠.



2016 기준 RSK와 Bitcoin 의 성능 차이



2019년 3월 25일 월요일

Coin Wallet Account - 12 단어의 비밀 (mnemonic 복구 원리)


필요 선행 지식 : Hash, Metamask 등 생성 경험

12 단어, 그 찜찜함

메타마스크도 그렇고 어카운트 생성할 때 항상 12개의 단어를 어디에 잘 적어두라고 하죠?

https://iancoleman.io/bip39/#korean


저는

참석 한문 다행 최악 결과 언덕 공기 영상 다음 근로 마요네즈 사실 사용 운명 청바지

가 나왔는데요. 지갑 분실시 이 mnemonic 으로 복구가 가능하므로 메모가 필요하다고 합니다.

갑자기 궁금하지 않나요? 대체 이 문자들이 무엇이며 어떻게 복구가 가능한 것일까요?

아니 이렇게 쉬운 12개 단어들만 갖고 내 월렛이 복구가 된다고!!!? 한번 정확히 짚어보고 싶군요.


월렛의 역사

사토시가 처음 비트 코인을 고안 했을 때를 생각해 봅시다.

이제 막 '개인키를 갖고 거래를 하겠다' 라는 개념을 도입 했을 것이고

개발 초기에는 하나의 개인키로 거래를 했을 겁니다.

그러다보니 한가지 문제점을 깨닫게 된 것 입니다. 추적이 가능하다!?

네, 하나의 개인키와 공개키 세트로 거래를 하다보니 한 계정의 자산 규모가 대강 나오더라는 것이죠.

그래서 개인키 공개키를 매번 랜덤하게 만들도록 했더니 그걸 본인이 다 로컬에서 관리해야 해서 난감합니다.

로컬의 개인키를 잃어버리기라도 하면 눙물이...

그래서 키 관리 시스템 월렛 이 나오게 된 것이죠.

제 생각에는 카드라고 이름을 붙였다면 혼란이 덜하지 않았을까 싶네요.

실제 월렛도 카드처럼 현금(코인)은 없고 키 그리고 블록체인에 존재하는 코인을 전송하기 위한 로직만 있으니까요.

여튼 최근의 월렛은 HD(Hierarchical Deterministic) 월렛으로, 하나의 시드만을 사용해 계층적으로 관리가 가능합니다.


월렛의 원리

일단 복구를 이해하려면 먼저 월렛의 키가 어떻게 생성되고 관리되는지 알아봐야 할 것 같네요.

가장 먼저, 랜덤하게 생성한 128bits 값에 Hash를 적용해서 Digest 를 만들고,

사전 단어 리스트에 매핑합니다.



정확히는
1. Random 하게 128bits 생성하고
2. SHA256 돌린다음 앞에 4bits 를 떼서
3. 기존 128bits 뒤에 붙입니다
4. 11bits 씩 12개로 나눕니다
5. 사전 단어에 매핑합니다

즉, 12개의 랜덤한 단어가 랜덤한 순서로 생성되게 됩니다.

그 다음 키 스트레칭을 합니다.

DIGEST = PBKDF2(PRF, Password, Salt, c, DLen)

  • PRF: 난수 알고리즘. (HMAC-SHA512 를 사용합니다.)
  • Password: 패스워드. (위에서 만든 12개의 단어로 이루어져 있습니다.)
  • Salt: 암호학 솔트. (mnemonic + 패스워드로 이루어져 있습니다.)
  • c: 원하는 iteration 반복 수. (2048 번 반복합니다.)
  • DLen: 원하는 다이제스트 길이. (길이는 512.)
월렛 표준 중 하나인 BIP-0039 에서 마스터 시드는 괄호 안의 값을 바탕으로 생성됩니다. 

즉, 입력 받은 랜덤한 단어와 패스워드를 바탕으로 512길이의 Digest를 생성하는 것입니다.


왜 근데 하필 단어 12자를 넣도록 했을까요?

랜덤한 128bits 는 외우기도 어렵고 숫자 0 이랑 영문자 O 등등 헷갈리니까요.

즉, 사람의 편의를 위해서 입니다.


이후 이렇게 생성된 마스터 시드(Digest) 를 기반으로 개인키를 생성 하므로,

우리는 12개의 단어 및 순서와 패스워드만 알면 개인키를 생성 할 수 있게 됩니다.

즉, 어딘가 저장되어있는 개인키를 Restore 하는 것이라기 보다는 Re-Generation 한다는 개념이 맞습니다.

실제로는 온라인에서 생성하면 안되겠죠?


요약 .

1. 랜덤한 128bits 키로 12개의 랜덤한 단어를 생성한다.
2. 위에서 생성한 단어들과 패스워드 조합으로 개인키를 생성한다.
3. 즉, PKI 와 다르게 개인키를 즉석에서 Derive 할 수 있기 때문에 딱히 로컬에서 개인키를 잘 관리할 필요는 없고 단어와 패스워드만 잘 기억해두면 된다.
4. 무작위 seed 대입을 통해 위에서 만든 개인키를 생성하려면 패스워드가 없다고 가정해도 괴에에엥장히 오랜 시간(최악의 경우 내 PC로 약 2500000000000000000000000 정도)이 걸린다.


2019년 3월 24일 일요일

루트스탁(RSK) 실전 - Bitcoin Smartcontract


1. RSK 설치

일단 설치를 합니다. (도중에 네트워크 선택은 regtest 로 하였습니다.)
$ sudo add-apt-repository ppa:rsksmart/rskj
$ sudo apt-get update
$ sudo apt-get install rskj


Mainnet : 실제 비트코인 위에서 동작하는 메인 네트워크
Testnet : 인터넷에 올라가있는 테스트 네트워크
Regtest : 로컬에서 구동하는 테스트 네트워크


자 이제 시작해 봅시다. stop, restart 도 됩니다.

sudo service rsk start

실제 실행 명령은 아래와 같습니다.

/usr/bin/java -Dlogback.configurationFile=/etc/rsk/logback.xml -cp /usr/share/rsk/rsk.jar co.rsk.Start 2>&1 &


2. Truffle 로 시작하기
이제 SmartContract 를 올려볼건데요, 일단 truffle 로 틀을 잡아주고 실행합니다.

mkdir securekim-storage
cd securekim-storage
truffle init
truffle develop

그러면 계정이 생성됩니다.
(이름은.. 심사숙고 끝에 김보안 저장소로 정했답니다..)

truffle(develop)> create contract SecurekimStorage

이러면 contracts 폴더 밑에 SecurekimStorage 가 생깁니다
├── contracts
│   ├── Migrations.sol
│   └── SecurekimStorage.sol

3. SmartContract 작성하기
이제 SmartContract 를 작성해 봅시다.
이더리움의 스마트컨트랙트와 완전히 호환되니.. solidity 로 짜면 되겠죠?

저장된 데이터를 가져오는건 누구나 할 수 있지만,
값을 저장하는 것은 deployer 만 할 수 있는 SmartContract 입니다.

SecurekimStorage.sol
pragma solidity ^0.5.0;

contract SecurekimStorage {
    address private deployer;
    uint private storedData;

    constructor() public {
        deployer = msg.sender;
    }

    function set(uint n) public {
        if(msg.sender == deployer)
            storedData = n;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}

4. SmartContract Deploy 하기
이제 만든 SmartContract 를 Deploy 해보아야 겠죠?

migrations 폴더 밑에 2_securekim_storage.js 를 생성합니다.


├── migrations
│   ├── 1_initial_migration.js
│   └── 2_securekim_storage.js


2_securekim_storage.js
var SecurekimStorage = artifacts.require("./SecurekimStorage.sol");

module.exports = function(deployer) {
  deployer.deploy(SecurekimStorage);
};

이제 컴파일 해봅니다.

(참고로 앞으로도 3_, 4_ ... 규칙으로 생성하셔야 실행되고 스마트컨트랙트가 디플로이 됩니다.)
truffle(develop)> compile

Compiling ./contracts/Migrations.sol...
Compiling ./contracts/SecurekimStorage.sol...
Writing artifacts to ./build/contracts

(compile 명령은 contracts 폴더 내부에 있는 모든 sol 파일을 컴파일합니다.)

truffle(develop)> migrate

자 ! 이제 로컬 블록체인 네트워크에 migrate 되었습니다.


5. SmartContract 써보기

이제 SmartContract 와 Interact 하는 시간입니다.

Truffle 자체는 코드는 사실상 거대한 Javascript 코드 이며, Node 콘솔처럼 Javascript 명령을 받아 처리가 가능합니다.

자, 이제 SecurekimStorage instance 를 가져와서 securekimStorage 변수에 담아 봅니다.
truffle(develop)> var securekimStorage
truffle(develop)> SecurekimStorage.deployed().then(instance => securekimStorage = instance)

securekimStorage 의 get 함수를 볼까요?
truffle(develop)> securekimStorage.get
{ [Function]
  call: [Function],
  sendTransaction: [Function],
  estimateGas: [Function],
  request: [Function] }

내부는 4가지 함수로 이루어져 있네요. 그렇다면 이제 get 을 하고 결과를 Number 로 바꿔봅시다.

truffle(develop)> securekimStorage.get().then(bn => bn.toNumber())

아무것도 없으니 기본값 0 이 나오네요. 이제 10을 세팅하고 다시 가져와 봅시다.

truffle(develop)> securekimStorage.set(50)


지금 까지는 이더리움이랑 똑같네요 !

다음 글에서 계속 하겠습니다.

2019년 3월 21일 목요일

회사 프록시와 인증서에 고통받는 그대를 위한 글 (Bash, Gradle, Python, wget, nodejs(npm), apt-get, cURL, git, yarn, androidStudio)


대기업에 입사하면 장단점이 있는데,

단점 중에 하나가 회사에서 프록시를 사용하여 트래픽 감시를 하므로 프록시 설정을 해주어야 한다는 점 입니다.

특히, 회사에서는 https 트래픽도 감시를 하므로 인증서도 설정해 주어야 합니다.

그런데 문제는, 각 프로그램마다 또 인증서와 프록시 설정을 따로 해줘야 하는 경우가 많다는 것입니다.

그래서 항상 설정 할 때마다 고통을 받고는 하는데요,

특히 입사 초반에는 특별한 이유 없이 안되는 것처럼 느껴져 시간 낭비와 짜증을 불러 일으키곤 합니다.


각 프로그램별 정리를 해 보았습니다.

SERVER 는 프록시 서버 + 포트
CERT 는 인증서 명을 뜻합니다.

strict ssl false 어쩌고 하는 옵션은 모두 인증서 검사를 안하겠다는 것이며,
MITM 의 위험을 감수한다는 뜻입니다. (어차피 프록시 서버에서 MITM 할거지만..)

기본적으로 우분투 대상이며, 오타가 있을 수 있으니 유의하시기 바랍니다.


** Bash

sudo vi /root/.bashrc
export http_proxy="SERVER"
export https_proxy="SERVER"
export ftp_proxy="SERVER"

sudo mkdir /usr/share/ca-certificates/extra
sudo cp CERT /usr/share/ca-certificates/extra/CERT
sudo dpkg-reconfigure ca-certificates

cat CERT >> /etc/ssl/certs/ca-certificates.crt


** Gradle

C:\Users\YOURID\.gradle\gradle.properties 생성

systemProp.proxySet="true"
systemProp.http.keepAlive="true"
systemProp.http.proxyHost=SERVERHOST
systemProp.http.proxyPort=SERVERPORT

systemProp.https.keepAlive="true"
systemProp.https.proxyHost=SERVERHOST
systemProp.https.proxyPort=SERVERPORT
systemProp.https.proxyUser=USERNAME
systemProp.https.proxyPassword=PASSWORD
systemProp.https.nonProxyHosts="local.net|some.host.com"

keytool -importcert -keystore "%JAVA_HOME%\jre\lib\security\cacerts" -storepass changeit -trustcacerts -alias "My PROXY" -file CERT


** Python (Win)

https_proxy 환경 변수에 프록시 서버 주소 설정
PIP_CERT 환경 변수에 인증서 설정

잘 안되는 경우
pip --cert CERT install <원하는 패키지>



** wget

vi ~/.wgetrc
use_proxy=yes
http_proxy=SERVER
https_proxy=SERVER
ca_certificate=CERT


** nodejs

sudo npm config set https-proxy SERVER --global
sudo npm config set http-proxy SERVER --global
sudo npm config set cafile CERT

그래도 잘 안될 땐 눈물을 머금고
sudo npm config set strict-ssl false --global
sudo npm config set registry http://registry.npmjs.org/ --global

윈도우에서 에러 날때 :
VCTargetsPath 환경변수에 C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\v140
npm install java

** apt-get

sudo vi /etc/apt/apt.conf
Acquire::http::Proxy "SERVER";
Acquire::https::Proxy "SERVER";

우분투에서 뭔가 잘 안된다면 kr.archive.ubuntu 를 ftp.daum.net 으로 변경해 봅시다.
sudo vi /etc/apt/sources.list
:1,$ s/kr.archive.ubuntu.com/ftp.daum.net/g

sudo apt-get update

** cURL

sudo vi /etc/ssl/certs/ca-certificates.crt 파일에
CERT 내용 add ( cat CERT >> /etc/ssl/certs/ca-certificates.crt )

** git

sudo git config --global http.proxy SERVER
sudo git config --system http.sslcainfo CERT


** npm

npm config set proxy SERVER
npm config set https-proxy SERVER
npm config set cafile CERT

npm --add-python-to-path='true' --debug install --global windows-build-tools

그래도 잘 안되면 눈물을 머금고
npm config set "strict-ssl" false -g

** yarn

yarn config set proxy SERVER
yarn config set https-proxy SERVER

그래도 잘 안되면 눈물을 머금고
yarn config set "strict-ssl" false -g
set NODE_TLS_REJECT_UNAUTHORIZED=0
Export NODE_TLS_REJECT_UNAUTHORIZED=0

** Android Studio (Win)

기본적으로 프록시 설정이 쉽게 잘 되어 있습니다만... 인증서 설정은 아니죠
C:\Program Files\Android\Android Studio\jre\bin>keytool.exe -import -alias proxycert -file CERT -keystore ../jre/lib/security/cacerts






2019년 2월 24일 일요일

Plasma Leap (leap-node, leap-core, leap-contracts 등) 구동 자동화


전체를 재구동 하는 일이 잦아 자동화 하였고, Eth 넣어주는 동작까지 잘 되는것을 확인하였습니다.

Base를 위한 자동화는
https://github.com/securekim/auto-leap
에 최신 버전이 있으니 참고하세요

먼저 auto-leap.js 의 METAMASK_ACCOUNT 는 본인의 METAMASK 계정으로 수정해야 합니다.

수정 이후 yarn add web3 한번 하고 auto-leap.sh 을 leap-node, leap-contracts 등이 있는 폴더 위에서 돌리면

truffle 실행, contract compile, contract deploy, node / bridge / remix, auto-leap.js 를 실행 해 줍니다.

이후 auto-leap.js 에서는 METAMASK 계정에 10 이더를 넣어주고

컨트랙트 주소, 계정 주소를 leap-node.log 에 출력해 줍니다.

※ 8545 로 동작하도록 해 두어 remix 에서 포트 수정할 필요가 없습니다.

cat auto-leap.js

const METAMASK_ACCOUNT = "0x9C73363B89C0Eda0dbA1B4a5250E891F60723378"; //바꾸세요

var Web3 = require("web3");
const fs = require('fs');

//const web3 = new Web3(Web3.givenProvider || 'ws://localhost:9545');//, options); //FOR CONSOLE
const web3 = new Web3(Web3.givenProvider || 'http://localhost:8545');//, options); //FOR TEST RPC


web3.eth.getAccounts((error, result) => {
web3.eth.sendTransaction(
{from:result[0],
to:METAMASK_ACCOUNT, //CHANGE IT (METAMASK)
value: "10000000000000000000",
data: "0xdf"
}, (err, transactionHash) => {
if (!err)
console.log(transactionHash + " success");
});

fs.appendFile('auto-leap.log', '\nTruffle Account :\n ' + result[0] + '\n', function (err) {
if (err) throw err;
console.log('Saved!');
});

fs.appendFile('auto-leap.log', '\nMetamask Account :\n ' + METAMASK_ACCOUNT + '\n', function (err) {
if (err) throw err;
console.log('Saved!');
});
});


cat auto-leap.sh
#!/bin/bash
sudo killall -9 node
sudo killall -9 sudo
cd leap-contracts
truffle networks --clean
clear
testrpc&
sleep 3
truffle compile
truffle migrate --reset
truffle networks > ../auto-leap.log
sed -i 's/undefined\:undefined/localhost\:8545/g' build/nodeFiles/generatedConfig.json
cd ../leap-node
node index.js --config=../leap-contracts/build/nodeFiles/generatedConfig.json&
cd ../leap-contracts
sudo remixd -s . --remix-ide "https://remix.ethereum.org"&
python -mwebbrowser https://remix.ethereum.org&
cd ../bridge-ui
yarn start&
sleep 5
python -mwebbrowser http://localhost:1234&
cd ..
node auto-leap.js

실행 위치를 위한 구조는 아래와 같습니다.

├── auto-leap.js     // Metamask 계정에 10 이더 넣어 줌
├── auto-leap.log  // 컨트랙트 주소, 계정 주소 알려줌
├── auto-leap.sh   // truffle 실행, contract compile, contract deploy, node / bridge / remix
├── bridge-ui
├── leap-contracts
├── leap-core
├── leap-node
├── node_modules


testrpc 설치가 필요합니다.

sudo npm install -g –production windows-build-tools 
sudo npm install -g ethereumjs-testrpc 


2019년 2월 9일 토요일

Javascript 배열 복사 (Deep copy, Shallow copy)


자바스크립트 변수 중 배열을 복사하는 것은 두가지 유형이 있습니다.

copyArr = originArr 로는 일반적으로 의도하는 Deep copy가 이루어 지지 않기 때문에, 아래를 참조하시기 바랍니다.

1. 참조

origin = [1,2,3];
var copy = origin;

copy 된 변수가 origin 을 가리키고 있는 상태입니다.
즉, copy 값이 변경되면 origin 도 함께 변경됩니다.

copy[1] = 5; // origin [1, 5, 3];

2. Shallow copy 

copy 된 변수의 값이 변경되어도 origin 은 변하지 않습니다.


Example


Speed

Deep copy 에서 가장 빠른것은 slice(0) 이므로 이것을 이용하면 되겠습니다.









2019년 1월 30일 수요일

Plasma Leap 소스코드 분석하기 (leap-node)


leap-node 는 index.js 로 시작하므로, 여기서부터 살펴봅니다.

먼저 require 하는 아래 3가지 핸들러부터 살펴보겠습니다.

const txHandler = require('./src/tx');
const blockHandler = require('./src/block');
const periodHandler = require('./src/period');

txHandler : 


일단 leap-core 에서 트랜잭션들을 가져오고,

트랜잭션 타입에 따라서 기존의 상태를 리턴해 줍니다.

tx의 타입은
DEPOSIT, EPOCH_LENGTH, EXIT, TRANSFER, VALIDATOR_JOIN, CONSOLIDATE, VALIDATOR_LOGOUT 로 총 7개 가 있습니다.

applyTx 에서는
checkOutpoints, removeInputs, addOutputs 를 진행하는데

checkOutpoints 는 트랙잭션 인풋을 돌면서 input.prevout이 unspent 되었는지 즉, 존재하지 않는 output을 spend 하려 했는지 체크하고 에러를 throw 합니다. (에러는 계속 위로 올려버립니다.)

removeInputs 는 트랜잭션 인풋을 돌면서 input.prevout 이 unspent로 존재하면 해당 balance 를 삭제합니다.

addOutputs 에서는 트랜잭션 아웃풋을 돌면서 이미 존재하는 output 을 또 만들지 않도록 주의하면서 unspent 목록에 추가합니다.


cBalances Array 는 완전 복사(Deepcopy) 가 된 상태가 아니라서 balances 를 가리키게 됩니다.
Deepcopy 와 Shallow copy 에 대해서는 다음 시간에 알아보도록 하죠.

accumulateTx 에서는 남아있는 tx 들을 메모리풀에 적재합니다.

결국 기존 트랜잭션을 오류 없이 불러오려고 하는 것이네요.

blockHandler : 

updatePeriod 에서는
체인 길이를 32로 나눈 나머지가 0인 경우에 period 를 업데이트 하고 있습니다.
업데이트란, 이전 period 에 현재 period 를 복사하고, 이전 Period 의 merkleRoot() 로 현재 period 를 생성하는 것입니다. (swap)
체인 길이를 32로 나눈 나머지가 16인 경우, slot을 확인해서 활성화된 epoch 와 현재 epoch 의 차이가 1보다 크면, 각 slot 을 활성화 시킵니다. 이 부분은 확실히 이해가 안되서 코드를 남겨놓습니다.


addBlock 에서는
아까 메모리 풀에 적재해 놓았던 트랜잭션들을 매핑, JSON 화 해서 각각 새로운 블록에 바인딩 합니다. 이 새로운 블락을 bridgeState.currentPeriod 의 addBlock 의 매개변수로 줘서 블록을 생성하고, 메모리 풀을 비웁니다. 만약 받은 chainInfo 의 길이가 마지막으로 싱크된 블록의 길이보다 더 길면 블록을 다시 싱크하고 마지막으로 싱크된 블록의 길이를 늘려 줍니다.

updateValidators 에서는
state 의 slot 들에서 올바른 public key 를 불러오고, Address 를 가져옵니다.
그리고 각 Address에서 power 를 계산해서 (이것이 어디에서 변경되는지 확인 필요) 인덱스가 없고 0이 아니면 삭제하고, 인덱스가 있는데 0이면 체인에 validator로 추가합니다. 그리고 체인에서 해당 address 가 validator 로서 존재하지 않으면, power 10으로 추가해 줍니다.
key 의 알고리즘은 ed25519 이네요.

updateEpoch 에서는
코드가 짧아서 대체합니다. 말 그대로 epoch 의 길이를 업데이트 합니다.



periodHandler : 

submitPeriod 에서는
먼저 bridgeContract의 periods 메소드를 콜합니다. 그러면 submit 된 period 가 나옵니다.
--> bridgeState.bridgeContract.methods
submit 된 period 중 timestamp 가 0인 경우
slot을 가져와서 현재 slot 이 존재 하는 경우 slot의 id, submitPeriod 를 갖고 트랜잭션을 발생시킵니다. 트랜잭션은 아래처럼 받은 method -

를 ABI 인코딩 하고 가스를 랜덤하게 설정한 다음 private key로 사인합니다.

submitPeriod 이후에는 마찬가지로 contractPeriod 의 timestamp 가 0인지 확인하는 작업이 있는데, 위에서도 나왔지만 timestamp 가 0이라는게 어떤 의미인지 지금까지는 잘 모르겠네요.




결국 요약하면, 위 3개의 핸들러의 표면(index.js) 은
기존에 사용하던 트랜잭션과 블록을 안전하게 로딩 하기 위한 것임을 알 수 있었습니다.
물론 이름처럼 핸들링 하기 위한 코드도 있을 것 같은데, 아래에서 더 살펴보도록 합니다.


다시 돌아와서 최초 index.js 의 코드 시작을 보면 lotion 을 사용하고 있습니다. 로션이란 뭘까요?


lotion :

로션은 자바스크립트로 새로운 블록체인 앱을 만들어 내는 새로운 방법 중 하나로,

ABCI 프로토콜을 사용해 텐더민트 위에서 동작합니다.

ABCI 란 Application BlockChain Interface 의 약자로, 블록체인과 앱 사이의 인터페이스입니다.

컨센서스 엔진은 소켓 프로토콜을 사용, ABCI 를 통해

다른 프로세스에서 실행되는 응용 프로그램 상태를 관리 할 수 있게 됩니다


이후 BridgeState 를 사용해서 이것저것 하게 되는데요. 그렇다면 BridgeState 를 알아봅시다.



bridgeState

브릿지의 상태를 관리 할 수 있는 객체로, exitHandler 컨트랙트, bridge 컨트랙트, operator 컨트랙트 그리고 account 키 등 상태 정보가 있습니다.
하지만 결국 web3 eth 를 쓰고 있어서 이게 뭔지 정확히 알아야 되겠죠.

최초 init 을 실행하면 마지막으로 싱크된 블록을 확인하고, 컨트랙트 이벤트 워쳐를 실행하고
블록을 이닛합니다. 이게 뭔가 순서가 중요한지 비동기인데 await 으로 동기화 해 주었네요.

컨트랙트 이벤트 워쳐는 새로운 Deposit 이 생겼거나 Exit 가 시작 되었을때,
EpochLength 를 핸들링 합니다.



2019년 1월 29일 화요일

Plasma Leap 사용하기 (Deposit)


이전 편에 이어서 사용하기 편입니다.

우선 각종 주소들을 확보합니다.

1. Truffle 주소



2. Metamask 주소


3. native token 주소 (truffle)


이제 remix 에서 NativeToken 을 컴파일하고 추가합니다.

At Address 는 3번 native token 주소를 적습니다.



아래에서 isMint 를 콜해서 1번 Truffle Account와 2번 Metamask 주소를 넣고
해당 Account 에 토큰을 넣어봅니다.


메타마스크 계정에 돈을 넣고


메타마스크에서 토큰 추가 버튼을 클릭, 3번 네이티브 주소를 추가해 결과를 확인합니다.


월렛에 돈이 쌓입니다~



이제 remix 에서 1번 2번을 approve 합니다.




이제 가스 지불을 위한 ETH 를 확보합니다.

Truffle 에서 아래 명령 입력.


web3.eth.sendTransaction({from:"1번 Truffle 계정", to:"메타마스크주소", value:web3.utils.toWei("10","ether")}).then(function(rec){console.log(rec);});



그러면 메타마스크에 이더가 들어와서 잠시나마 행복을 느낄 수 있습니다.

이후 Deposit 을 해봅니다.

Deposit


1 LEAP 을 걸고 메타마스크에서 승인을 클릭합니다.
->

아직 안나갔고, 테스트만 되었습니다. 이제 다시 승인하면 진짜로 갑니다.



이더에서 가스비가 나갔네요



leap-node 쪽 로그를 보면 Deposit 을 체크했고

텐더민트쪽에서는 block 이 실행되었음이 체크 되었고,
현재 상태가 커밋되었음을 알 수 있습니다.





2019년 1월 23일 수요일

우분투 18.04 멀티 부팅 설치 이후 멈추는 현상


멀티부팅 한두번 해본게 아닌데

이번에 외장 그래픽 카드를 사용하는 노트북에 멀티부팅 세팅하다가 고통을 많이 겪어 기록한다.


이미지는 우분투 공식 사이트에서 iso 파일 받으면 되고

USB 에 넣는건 rufus 사용하면 되고 인터넷 찾아보면 많다.

멀티 부팅을 위해 파티션 줄이고 설치하면 된다.

첫번째 시련 - USB 부팅 후 멈춤


나의 첫번째 문제는 USB 부팅 후 설치시 멈추는 현상이었는데,

외장 그래픽 사용시 충돌나는 것 때문이었다.

install ubuntu 쪽에 커서를 갖다놓고 e 를 누른다음

nomodeset 을 추가해주고 f10 을 누르니 해당 문제가 없어졌다.

linux /boot/vmlinuz-linux ..... quiet splash nomodeset

다만 설치시 화면 해상도가 낮아 다음 단계로 가는 버튼을 클릭 할 수가 없는 문제가 있었는데,

Alt + I 또는 엔터를 치면 다음 단계로 넘어가니 참조한다.

두번째 시련 - 윈도우즈로만 부팅 됨


이후 무조건 윈도우즈로 다이렉트 부팅이 되는 문제가 있었는데, 아래와 같이 해결했다.


Ubuntu boot-repair
1. Ubuntu를 설치할때 부팅했던 USB 또는 CD를 넣고 부팅한다.
2. Try Ubuntu without installing을 선택하고 엔터는 치지 않는다.
3. e 를 눌러 다시 nomodeset 을 추가해주고 f10을 눌러 Try Ubuntu 함.
4. 부팅완료 후 터미널을 실행한 후 boot-repair를 설치한다. 
$ sudo add-apt-repository ppa:yannubuntu/boot-repair
$ sudo apt-get update
$ sudo apt-get install -y boot-repair
$ sudo boot-repair

5. Recommended repair (repairs most frequent problems) 선택
6. 설치 완료 후 재부팅하면 되는 경우도 있겠지만, 
나는 계속 다이렉트로 윈도로 들어가 졌다.
윈도우에서 cmd.exe 를 찾아서 (windows/system32 쪽에 있음)
우클릭 하여 관리자 권한으로 실행 한 다음,
bcdedit /set {bootmgr} path \EFI\ubuntu\shimx64.efi
를 실행해 주면 이제 우분투로 부팅은 가능해 진다.

세번째 시련 - 설정 진입 또는 컴퓨터 종료시 멈춤

쓰다가 설정에 들어가거나 컴퓨터 종료시 컴퓨터가 멈추는 현상이다.
이상한 점은 컴퓨터 켜자마자 설정에 진입하면 안 멈춘다는 점이다.
sudo apt-get install nvidia-384
이후 강제종료 ㅠ.ㅜ 하고
sudo apt-get update
그 다음부터는 잘된다 !!

2019년 1월 15일 화요일

Plasma Leap 구동하기 (최종편)


저번에 결국 구동도 못해보고 삽질을 너무 많이 했다.

저번에 이어서 다시 한번 정리해 보고, 구동을 해보자.

일단 truffle 을 구동하고 필요한 contract 를 deploy 해본다.

contract deploy : 

git clone https://github.com/leapdao/leap-contracts.git
cd leap-contracts
yarn
truffle develop


이후 tuffle 내부에서
migrate --reset

을 진행하면 contract 가 배포된다.

////// 아래 에러가 나는 경우, truffle 버전을 5.x 대로 올려줘야 합니다. //////

migrate --reset
Error parsing /home/brokim/workspace/leapdao/leap-contracts/contracts/AdminableProxy.sol: ParsedContract.sol:34:41: ParserError: Expected ',' but got identifier
  function applyProposal(bytes calldata data) external ifAdmin returns (bool) {
                                        ^--^
Compilation failed. See above.

///////////////////////////////////////////////////////////////////////////////

그럼 마지막에 어디에 config 가 generated 되었는지 알려준다.


build/nodeFiles 에 가보면 generatedConfig.json 파일이 있다.

버그때문인지, rootNetwork 가 http://undefined:undefined 로 잡혀있다.
이걸 localhost:9545 로 바꿔준다.

sed -i 's/undefined\:undefined/localhost\:9545/g' build/nodeFiles/generatedConfig.json

NODE

이제 leap-node 를 구동할 차례이다.

그러면 아래와 같이 Validator 가 되라는 소리가 나오는데,
git clone https://github.com/leapdao/leap-node.git
cd leap-node
yarn

뜬금없이 crash 가 나면서 core dump 가 떨어지는 경우, 직접 lotion 을 설치해준다.
yarn add lotion

아까 만들었던 generatedConfig.json 을 바탕으로 leap-node 를 구동해 본다.

DEBUG=leap-node,leap-node:period,leap-node:tx,leap-node:error,leap-node:validators,tendermint node index.js --config=../leap-contracts/build/nodeFiles/generatedConfig.json
bridge-dev 는 현재 문제가 많아서 에러가 나고 있고 개발진에서 수정중이다.


좀 더 살펴보자면, 해당 bridge URL로 접속하면 나는 에러의 유형은 다음과 같다.

1. TypeError: Cannot read property 'toLowerCase' of undefined
2. index.330c117862a877cbfb8b.js:1 Uncaught (in promise) Error: Returned values aren't valid, did it run Out of Gas?
3. inpage.js:1 MetaMask - RPC Error: Error: JsonRpcEngine - response has no error or result for request:
{
  "jsonrpc": "2.0",
  "id": 2967365567,
  "method": "net_version",
  "params": [],
  "origin": "bridge-dev.leapdao.org"
}
4. OPTIONS https://testnet-2.leapdao.org/ net::ERR_CONNECTION_TIMED_OUT

자, 느꼈는가? 일단 1번에서 Object.toLowerCase 를 호출하다가 undefined 에러가 났다.
이것은 응당 받아서 존재해야 할 Object 가 비어있다는 뜻이고
에러는 2, 3, 4 번에서 이어진다.
4번을 보면 이유가 확실한데, testnet-2 를 접속하려다가 에러가 나고 있다.
개발자 확인 결과 testnet-1, testnet-2 는 지금 동작하지 않고 있다.

즉, bridge-UI 의 RPC network 주소가 잘못되어 있는 것이다 !
그럼 어떻게 해야할까... 이것은 스스로 bridge 까지 돌려야 한다는 의미다..

일단 leap-node 를 디버깅 하기 위해서 args 설정을 해 주어야 한다.
.vscode/launch.json 파일을 수정해서 args 에 넣어주고, F5 를 눌러 구동한다.
"args": [ "--config=../leap-contracts/build/nodeFiles/generatedConfig.json" ]



remixd
그전에 remix 를 구동해 본다.
이걸 구동하면 remix 가 로컬 파일에 접근 가능 하도록 할 수 있다.
https://github.com/ethereum/remixd 에서 설치한다.

cd leap-contracts
remixd -s . --remix-ide "https://remix.ethereum.org"

그리고 웹 브라우저를 통해 https://remix.ethereum.org/ 로 이동한다.

왼쪽 상단에 링크 표시를 누르게 되면 로컬 호스트에 접근 가능해진다.

(가장 우측 초록색 버튼)


///////////////////// 눌렀을 때 하기 에러 나는 경우 : root 권한으로 실행. //////////////////////

$ remixd -s . --remix-ide "https://remix.ethereum.org"
[WARN] You may now only use IDE at https://remix.ethereum.org to connect to that instance
[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

[WARN] Symbolic link modification not allowed : . | /home/securekim/workspace/leapdao/leap-contracts
Tue Jan 29 2019 00:31:26 GMT+0900 (KST) Remixd is listening on 127.0.0.1:65520
Tue Jan 29 2019 00:31:37 GMT+0900 (KST) Connection accepted.
[WARN] Symbolic link modification not allowed : ./ | /home/securekim/workspace/leapdao/leap-contracts
setup notifications for /home/securekim/workspace/leapdao/leap-contracts/contracts
events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: watch /home/securekim/workspace/leapdao/leap-contracts/contracts ENOSPC
    at _errnoException (util.js:1022:11)
    at FSWatcher.start (fs.js:1382:19)
    at Object.fs.watch (fs.js:1408:11)
    at createFsWatchInstance (/usr/local/lib/node_modules/remixd/node_modules/chokidar/lib/nodefs-handler.js:37:15)
    at setFsWatchListener (/usr/local/lib/node_modules/remixd/node_modules/chokidar/lib/nodefs-handler.js:80:15)
    at FSWatcher.NodeFsHandler._watchWithNodeFs (/usr/local/lib/node_modules/remixd/node_modules/chokidar/lib/nodefs-handler.js:232:14)
    at FSWatcher.NodeFsHandler._handleDir (/usr/local/lib/node_modules/remixd/node_modules/chokidar/lib/nodefs-handler.js:414:19)
    at FSWatcher. (/usr/local/lib/node_modules/remixd/node_modules/chokidar/lib/nodefs-handler.js:462:19)
    at FSWatcher. (/usr/local/lib/node_modules/remixd/node_modules/chokidar/lib/nodefs-handler.js:467:16)
    at FSReqWrap.oncomplete (fs.js:153:5)

////////////////////////////////////////////////////////////////////////////


여기 contracts 에서 Bridge.sol 을 찾은 다음, 우측 상단에 run 을 클릭하고
Environment 에서 Web3 Provider 를 클릭한 다음, http://localhost:9545 를 입력한다.

Compile 에서 버전도 맞춰줘야 한다.

이제는 트러플 콘솔에서 마이그레이션 실행할 때 해당 주소에 ParsecBridge 를 로딩 할 수 있고, Contract 함수를 호출이 가능해 진다.

metamask 도 사용자 정의에서 9545 로 RPC 연동하자



bridge-ui 

로컬에서 bridge-ui 도 구동해 보자

git clone https://github.com/leapdao/bridge-ui.git

일단 나는 지속적으로 yarn && yarn start 시 다음 에러가 났다.

(개발진은 에러 재현이 안된다고 한다.)


그런데 메시지를 잘 살펴보면 그 전에 메모리 관련 오류가 있었다...

컴퓨터가 안좋으면 가끔 저런 에러가 뜨게 된다.ㅠ

일단 yarn 명령을 살펴보면 다음과 같다.

"postinstall": "rm -f node_modules/web3/index.d.ts && rm -f node_modules/web3/types.d.ts",
    "start": "./node_modules/.bin/webpack-dev-server --config webpack.config.dev.js",
    "build": "rm -rf dist/ && webpack-cli --config webpack.config.prod.js",
    "stats": "rm -rf dist/ && webpack-cli --config webpack.config.prod.js --json > stats.json",
    "precommit": "lint-staged",
    "deploy:dev": "aws s3 sync ./dist s3://bridge-dev.leapdao.org/ --acl public-read && aws cloudfront create-invalidation --distribution-id E3UQO39J2ZIILR --paths '/*'",
    "deploy:testnet": "aws s3 sync ./dist s3://testnet.leapdao.org/ --acl public-read && aws cloudfront create-invalidation --distribution-id ERDV80HEAIPI6 --paths '/*'",
    "deploy:mainnet": "echo \"No bucket for mainnet\" && echo 0"

저건 또 바이너리처럼 보이지만 사실 링크라는 것을 알 수 있고...
cd bridge-ui
node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.config.dev.js

하면 실행 된다는 것을 알 수 있다. 그럼 디버깅을 해보자.
아까 처럼 하면 된다.

디버깅을 하다보니 알게 된 사실인데, web3 를 참조하는 위치는
node_modules/@types/web3/ 인데
어떤애는 Eth 를 참조하고 어떤애는 eth 를 참조해서 생기는 문제로 보인다.

결국 모두 수정해서 patch 파일을 만들었다.

diff --git a/src/stores/governanceContract.ts b/src/stores/governanceContract.ts
index 1ee7f29..3ee5698 100644
--- a/src/stores/governanceContract.ts
+++ b/src/stores/governanceContract.ts
@@ -5,7 +5,7 @@
  * found in the LICENSE file in the root directory of this source tree.
  */
 import Web3Store from './web3';
-import { ABIDefinition } from 'web3/Eth/ABI';
+import { ABIDefinition } from 'web3-eth-abi';
 import { range } from '../utils';
 import {
   governance as governanceAbi,
diff --git a/src/utils/abis/bridge.ts b/src/utils/abis/bridge.ts
index 3c6dba9..b04c785 100644
--- a/src/utils/abis/bridge.ts
+++ b/src/utils/abis/bridge.ts
@@ -1,4 +1,4 @@
-import { ABIDefinition } from 'web3/Eth/ABI';
+import { ABIDefinition } from 'web3-eth-abi';

 export default [
   {
diff --git a/src/utils/abis/exitHandler.ts b/src/utils/abis/exitHandler.ts
index 85181d7..30a25fa 100644
--- a/src/utils/abis/exitHandler.ts
+++ b/src/utils/abis/exitHandler.ts
@@ -1,4 +1,4 @@
-import { ABIDefinition } from 'web3/Eth/ABI';
+import { ABIDefinition } from 'web3-eth-abi';

 export default [
   {
diff --git a/src/utils/abis/poaOperator.ts b/src/utils/abis/poaOperator.ts
index 70aeab8..0bff456 100644
--- a/src/utils/abis/poaOperator.ts
+++ b/src/utils/abis/poaOperator.ts
@@ -1,4 +1,4 @@
-import { ABIDefinition } from 'web3/Eth/ABI';
+import { ABIDefinition } from 'web3-eth-abi';

 export default [
   {
diff --git a/src/utils/abis/posOperator.ts b/src/utils/abis/posOperator.ts
index d428192..3acc1d4 100644
--- a/src/utils/abis/posOperator.ts
+++ b/src/utils/abis/posOperator.ts
@@ -1,4 +1,4 @@
-import { ABIDefinition } from 'web3/Eth/ABI';
+import { ABIDefinition } from 'web3-eth-abi';

 export default [
   {
diff --git a/src/utils/abis/proxy.ts b/src/utils/abis/proxy.ts
index 616e15f..6976a10 100644
--- a/src/utils/abis/proxy.ts
+++ b/src/utils/abis/proxy.ts
@@ -1,4 +1,4 @@
-import { ABIDefinition } from 'web3/Eth/ABI';
+import { ABIDefinition } from 'web3-eth-abi';

 export default [
   {
드디어 에러가 없어졌다.

-> 현재는 개발자 측에서 위 패치를 반영하여 에러가 없어졌다. 참고.


그리고 추가적으로 bridge-ui/src/utils/index.ts 의 수정이 필요한데,
지금 새로 해보니 수정을 안해도 잘 된다.

diff --git a/src/utils/index.ts b/src/utils/index.ts
index 4083aef..82b5cca 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -15,7 +15,7 @@ export const PLASMA_NODES = {
   4: 'http://node4.testnet.leapdao.org:8645',
 };

-export const DEFAULT_NETWORK = '4';
+export const DEFAULT_NETWORK = '4447'; // Error... Please change the network.

 export const NFT_COLOR_BASE = 32769; // 2^15 + 1

기본적으로 열리는 주소는

http://localhost:1234/

이다. 접속해 보면 블록을 볼 수가 있다.




wallet 에서 아래 에러가 나고 있었는데... 지금은 별도의 수정 없이도 에러가 안나고 있다.


//////////////////////////////////////// 지금은 안남 ////////////////////////////////////
Setting up event listener for contract at 0x06828E256dA65fB03d275Bb698A4f20E537723D3..
-> AdminableProxy 를 접근한 이후에 에러가 나고 있다.

Uncaught (in promise) Error: Returned values aren't valid, did it run Out of Gas?
    at ABICoder.decodeParameters (webpack:///./node_modules/web3-eth-abi/src/index.js?:226)
    at Contract._decodeMethodReturn (webpack:///./node_modules/web3-eth-contract/src/index.js?:465)
    at Method.outputFormatter (webpack:///./node_modules/web3-eth-contract/src/index.js?:818)
    at Method.formatOutput (webpack:///./node_modules/web3-core-method/src/index.js?:163)
    at sendTxCallback (webpack:///./node_modules/web3-core-method/src/index.js?:473)
    at eval (webpack:///./node_modules/web3-core-requestmanager/src/index.js?:147)
    at XMLHttpRequest.request.onreadystatechange (webpack:///./node_modules/web3-providers-http/src/index.js?:96)
    at XMLHttpRequestEventTarget.dispatchEvent (webpack:///./node_modules/xhr2-cookies/dist/xml-http-request-event-target.js?:34)
    at XMLHttpRequest._setReadyState (webpack:///./node_modules/xhr2-cookies/dist/xml-http-request.js?:208)
    at XMLHttpRequest._onHttpResponseEnd (webpack:///./node_modules/xhr2-cookies/dist/xml-http-request.js?:318)



Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.

decodeParameters 로 변수가 제대로 안가고 있음. (비어있음)

콜스택 :

네트워크 상황 :
wallet call 을 하는데 localhost:8645 랑 rinkeby.infura.io 다.
뭔가가 잘못되었다


src/config/index.ts 부분도 수정

const defaultConfig = {
'name': 'localnet',
'rootNetworkId': '4',
'consensus': 'poa',
'nodes': [
'http://localhost:9545'
]
};

//////////////////////////////////////////////////////////////////////


월렛도 잘 나옵니다 !