2018년 5월 7일 월요일

지능적 비전 지원을 위한 Azure 기반 프로젝트 키넥트

키넥트 사용했던 분들 꽤 많았을 겁니다. 이렇게 좋은 센서를 생산 중단한 마이크로소프트가 이해되지 않았던 적이 있었죠. 역시 마소는 우리의 기대를 저버리지 않고 훨씬 좋아진 키넥트 센서를 꾸준히 개발하고 있었습니다.

이 글은 마이크로소프트의 지능적 비전 지원을 위한 Azure 기반 프로젝트 키넥트 기술 소개입니다.


Satya Nadella의 Build 기조 연설에서 Azure 에서 Project Kinect 지원을 소개했습니다. 단순히 키넥트만 지원하는 것이 아니라, Azure와 연계되는 딥러닝 등 다양한 도구와 연결되어, 재미있고 유용한 유스케이스 구현이 가능함을 언급하였습니다.

주변 공간과 사물을 인식할 수 있는 능력을 Kinect와 Azure 연계된 머신러닝 등 도구가 지웜함으로써 지능적인 지각을 가능하게 해 줍니다. Azure AI 서비스와 적은 전력 소모와 높은 정확도로 동작하는 Kinect 의 ToF 깊이 센서 기술은 심도 이미지를 이용한 다양한 비전이 가능해 집니다.

건축가인 Cyrus Bamji는 이 센서를 이용해 ISSCC (International Solid-State Circuits Conference) 컨퍼런스에 활용 사례를 발표하였고 호평을 받았습니다. 이 새로운 키넥트 센서는 HoloLens의 차기 버전을 제공할 센서이기도 합니다. 센서 스펙은 다음과 같습니다.
  • 1024x1024 픽셀
  • 225-950mw 저전력소모
  • 원거리 캡쳐 가능한 넓은 동작범위
  • 햇빛에 덜 민감한 글로벌 셔터 다중 위상 깊이 계산 기술
  • 고주파수 낮은 피크 전류 작동
XBox360 Kinect를 처음 만들었을 때 많은 사람들이 관심을 가졌고, 크리에이티브 개발자들은 게임을 넘어 다양한 분야에 이를 사용했었습니다. 창의적인 작품이 만들어졌습니다. 작년 2세대 키넥트 생산은 중단했지만, 인텔 RealSense 개발에 마이크로소프트는 계속 협력했었습니다.

HoloLens 3세대는 Kinect 깊이 감지 기술을 이용해 더욱 놀라운 결과를 보여줄 계획입니다. 여기에서는 사람과 공간 환경을 이해하고, 시선, 몸짓, 음성으로 입력을 받으며, 3D 홀로그램과 몰입형 공간 사운드를 지원할 것입니다. 4세대는 진보된 키넥트 센서를 사용해 지능형 클라우드 및 인텔리전트에 연결된 서비스를 지원합니다 .

Azure는 이미 머신 러닝, 인지 기술, IoT Edge를 지원하고 있습니다. Azure AI 서비스와 통합되어 점점 더 많은 센서를 기반으로 하는 생태계가 풍성해 질 것입니다. 자세한 내용는 다음 링크를 확인하시길 바랍니다.


점점 더 흥미롭고 재미있는 혼합현실 세상이 펼쳐지는 것 같습니다.^^

2018년 3월 2일 금요일

우분투 운영체계 폴더 구조 및 핵심 명령어

이 글은 우분투 운영체계 폴더 구조 및 명령어를 정리한다.

폴더 구조 
우분투 폴더 구조는 다음과 같다.
우분투 파일 구조(Ask Ubuntu)

우분투는 리눅스 일종으로 리눅스 폴더 파일 시스템표준 FSSTND(Linux File System Standard)을 따른다.

/
루트. 최상위 폴더

/bin
기본적인 명령어가 저장된 폴더.

/boot
리눅스 부트로더(Boot Loader)가 존재하는 폴더. 즉, GRUB 과 같은 부트로더에 관한 파일들(grub.conf 등)이 존재

/dev
시스템 디바이스(device)파일을 저장하고 있는 폴더.

/etc
시스템의 설정파일이 존재하는 폴더.
/etc/sysconfig 시스템 제어판용 설정파일
/etc/passwd 사용자관리 설정파일
/etc/named.conf DNS 설정파일

/etc/mai/
sendmail.cf 나 access 파일등의 sendmail 의 설정파일들이 존재하는 폴더.

/etc/ssh/
SSH 서비스, 즉 sshd 데몬에서 사용하는 각종 설정파일들이 존재하는 폴더.

/etc/skel/
계정사용자 생성시의 초기화파일들이 저장된 폴더(useradd 에서 사용함)

/etc/rc.d/
부팅레벨별 부팅스크립트파일들이 존재하는 폴더.

/etc/rc.d/init.d/
시스템 초기화 파일들의 실제파일들이 존재함. /etc/pam.d/

/etc/xinetd.d/
xinetd 수퍼데몬에 의해 서비스되는 서비스설정파일이 존재함.

/home
사용자의 홈폴더

/lib
커널모듈파일과 라이브러리파일

/media
DVD, CD-ROM, USB 등과 같은 탈부착이 가능한 장치들의 마운트포인트로 사용되는 폴더.

/mnt
/media 폴더와 비슷한 용도로 탈부착이 가능한 장치들에 대하여 일시적인 마운트포인트로 사용하는 폴더.

/proc
가상파일시스템. 현재 메모리에 존재하는 모든 작업들이 파일형태로 존재하는 곳

/root
시스템 최고관리자인 root 사용자의 개인 홈폴더.

/sbin
ifconfig, e2fsck, ethtool, halt 등과 같이 주로 시스템 관리자들이 사용하는 시스템관리자용 명령어를 저장하고 있는 폴더.

/tmp
공용폴더

/usr
시스템이 아닌 일반사용자들이 주로 사용하는 폴더

/usr/bin/
일반 사용자들이 사용가능한 명령어 파일들이 존재하는 폴더.

/usr/X11R6/
X 윈도우 시스템의 루트 폴더

/usr/local/
MySQL, Apache, PHP 등과 같은 어플리케이션들을 소스로 컨파일설치할 때 사용되는 장소

/var
시스템운용중에 생성되었다가 삭제되는 데이터를 일시적으로 저장하기 위한 폴더

/lost+found
연결이 끊어진 inode 들이 숫자파일형태로 존재하는 곳

명령어 
주로 잘 사용하지 않는 명령어지만, 문제가 있었을 때 사용해야하는 명령어를 정리해 본다.
  • ps: 프로세스 리스트
  • df -h: 디스크 마운트 정보 확인
  • alias: 명령어 간소화하기
  • apropos: 관련된 명령어 찾기
  • arch: 컴퓨터 종류 알기
  • arp: 같은 서브넷의 IP 보여주기
  • at: 작업 시간 정하기
  • atd: 계획성 있는 작업 실행하기
  • awk: 특정 패턴 문자 처리하기
  • a2p: 펄 파일로 바꾸기
  • badblocks: 배드 블럭 검사하기
  • bc: 계산기
  • biff: 메일 수신 소리로 확인하기
  • bg: 후면작업; 배경화면 설정
  • bind: 키나 함수 순서 결합하기
  • break: 루프 빠져나가기
  • cal: 달력보기
  • builtin: 내부 명령어 알아보기
  • case: 조건 처리하기
  • cat: 화면상에서 파일 보기
  • cd: 디렉토리 변경하기
  • cfdisk: 디스크 설정하기
  • chattr: 파일 속성 변경하기
  • chfn: 사용자 정보 변경하기
  • chgrp: 파일, 디렉토리가 속했던 그룹 바꾸기
  • chmod: 파일 권한 바꾸기
  • chown: 파일 주인 바꾸기
  • chsh: 지정된 셸 바꾸기
  • cksum: CRC값을 점검한다
  • clear: 화면 청소하기
  • clock: CMOS 시각을 조정하기
  • cmp: 파일 비교하기
  • colcrt: 문자 변환 필터
  • colrm: 열 삭제하기
  • column: 가로 정렬하기
  • comm: 파일 비교 출력하기
  • command: 명령어 알아보기
  • continue: 루프 계속돌기
  • cp: 파일 복사하기
  • cpio: 복사본 만들기
  • crontab: cron을 관리한다
  • csplit: 파일에 서식, 규칙 정하기
  • cut: 필요한 필드만 출력하기
  • date: 날짜 보기
  • dd: 블럭장치 읽고 쓰기
  • debugfs: ext2 파일 시스템 디버깅하기
  • declare: 변수 선언하기
  • df: 파일 시스템의 사용량 보기
  • dirs: 디렉토리 목록 표시하기
  • dmesg: 부팅 메시지 보기
  • : X윈도우 환경에서 printk 메세지를 기본으로 못보는데 dmesg를 통해서 확인할수 있다
  • dnsdomainname: DNS 이름 출력
  • domainname: NIS 이름 출력&설정
  • du: 디렉토리와 파일의 용량 파악하기
  • dumpe2fs: 파일 시스템 정보 보기
  • echo: 표준 출력하기
  • eject: 장치 해제하기
  • elm: 메일 관련
  • enable: 내부 명령어 지정
  • env: 환경변수 출력하기
  • eval: 인수 읽기
  • exec: 셸 명령어 실행하기
  • exit: 종료하기
  • expand: 탭을 공백으로 변환하기
  • export: 변수 지정하기
  • e2fsck: 파일 시스템 복구하기
  • fc: 지정된 편집기 받기
  • fdformat: 플로피 디스크 포맷하기
  • fdisk: 파티션 나누기
  • fg: 지정된 작업을 전면 프로세스로 시작하기
  • file: 파일 종류 보기
  • find: 파일 찾기 eg) find ./ -name ./*
  • finger: 사용자 정보 알기
  • fold: 정형화하기
  • fmt: 정형화하기
  • for: 반복 실행하기
  • free: 메모리 사용량 알아보기
  • fsck: 파일 시스템 검사하기
  • fstab: 파일 시스템에 대한 고정적인 정보 저장하기
  • ftp: 파일 전송 프로그램
  • fuser: 프로세스 ID 출력
  • getkeycodes: 매핑 테이블 출력하기
  • grep: 특정 문자: 열 검색하기
  • gzexe: 실행 파일 압축하기
  • gzip: 압축하기
  • halt: 시스템 종료하기
  • hash: 기억해 두기; index 역할
  • head: 파일의 앞부분 출력하기
  • help: 도움말 보여주기
  • host: 호스트 정보 보기
  • history: 사용 명령어 목록보기
  • hostname: 서버 이름 알기
  • id: 계정 정보 알기
  • if: 조건문 실행하기
  • ifconfig: 랜카드에 주소 할당하기
  • imolamod: 모듈 설치하기
  • inetd: 인터넷 서비스의 최상위 데몬
  • init: 실행 단계 정하기
  • ispell: 철자법 검사하기
  • jobs: 수행중인 프로세스 알기
  • kbd_mode: 키보드 모드 출력하기
  • kill: 프로세스 죽이기  강제종료 : kill -9  PID
  • klogd: 커널 로그 데몬
  • ldd: 공유 라이브러리의 의존성 알기
  • less: 페이지 단위로 출력하기
  • let: 정규식 표현하기
  • lilo: 부팅하기
  • ln: 링크하기
  • locate: 패턴에 맞는 파일 찾기
  • login: 로그인하기
  • logger: 시스템 로그 기록하기
  • logname: 사용자 로그인명 보여주기
  • logout: 로그인 셸 종료하기
  • look: 특정 단어 검색하기
  • losetup: 중복 장치 확인하기
  • lpd: 프린트 데몬
  • lpq: 현재 프린트 작업 상태 출력하기
  • lpr: 출력하기
  • lprm: 대기열에 있는 문서 삭제하기
  • ls: 디렉토리 내용보기
  • lsattr: 파일 시스템의 속성 보여주기
  • lsdev: 하드웨어 장치 출력하기
  • lsmod: 모듈 정보 출력하기 lnsmod: 묘둘 올리기 rmmod : 모듈 내리기
  • mail: 메일 관련
  • make: 컴파일하기
  • man: 매뉴얼 보기
  • mattrib
  • mbadblocks
  • mcd
  • mcopy
  • mdel
  • mdeltree
  • mdir
  • mesg: 메시지를 받을 수 있는지 확인하기
  • mformat
  • minfo
  • mkdir : 디렉토리 만들기
  • mke2fs: 파일 시스템 생성하기
  • mkfs: 파일 시스템 만들기
  • mknod: 특수 파일 만들기
  • mkswap: 스왑 영역 지정하기
  • mlabel
  • mmd
  • mount
  • mmount
  • mmove
  • mpartition
  • mount: 장치 연결하기
  • more: 화면 단위로 출력하기  ls -al | more
  • mrd
  • mren
  • mtoolstest
  • mtype
  • mutt: 메일 관련
  • mv: 파일 옮기기
  • mzip
  • netstat: 현재 네트웍 상황 보기
  • nice: 프로세스 우선 순위 변경하기
  • od: 8진수로 파일 보기
  • passwd: 암호 입력하기
  • pidof: 실행중인 프로그램의 프로세스 ID 찾기
  • pine: 메일 관련
  • ping: 네트웍 확인하기
  • popd: pushd 취소
  • ps: 프로세스 상태 알기 ps -aux
  • pstree: 프로세스 상관관계 알기
  • pwd: 절대경로 보여주기
  • quota: 디스크 한계량 알기
  • rarp: rarp 테이블 관리하기
  • rcp: 원격 호스트에 파일 복사하기
  • rdev: 루트, 스왑장치, 램 크기, 비디오 모드를 조사하고 설정하기
  • rdate: 네트웍으로 시간 설정하기
  • reboot: 재부팅하기
  • readonly: 읽기 전용으로 표시하기
  • renice: 프로세스 우선 순위 바꾸기
  • reset: 터미널 초기화하기
  • restore: 다시 저장하기
  • rlogin: 바로 접속하기
  • rm: 파일 지우기
  • rmdir : 디렉토리 지우기 rm -rf
  • route: 라우팅 테이블 추가/삭제하기
  • rpm: 프로그램 추가/삭제
  • rpm2cpio: rpm을 cpio로 변환하기
  • rsh: 원격으로 명령어 실행하기
  • rup: 호스트 상태 출력하기
  • rusers: 호스트에 로그인한 사용자 출력하기
  • rwall: 호스트 사용자에게 메시지 뿌리기
  • script: 기록하기
  • set: 변수값 설정하기
  • setup: 시스템 관련 설정하기
  • showmount: 호스트의 마운트 정보 보여주기
  • shutdown: 전원 끄기
  • sleep: 잠시 쉬기
  • source: 스크립트 번역하기
  • split: 파일 나누기
  • ssh: 암호화된 원격 로그인하기
  • stty: 터미널라인 설정 보여주기
  • su: 계정 바꾸기
  • suspend: 셸 중단하기
  • swapoff : 스왑 해제하기
  • swapon: 스왑 활성화하기
  • sync: 버퍼 재설정하기
  • syslogd: 로그인 과정 설정하기
  • tac: 거꾸로 보기
  • tail: 문서 끝부분 출력하기
  • talk: 이야기하기
  • tar: 파일 묶기
  • tcpdchk: tcp wrapper 설정하기
  • tcpmatch: 네트웍 요청에 대해 예측하기
  • tee: 표준 입력으로부터 표준 출력 만들기
  • telnet: 원격접속하기
  • test: 테스트하기
  • times: 셸에서의 사용자와 시스템 시간 출력하기
  • top: cpu 프로세스 상황 보여주기
  • tr: 문자열 바꿔주기
  • true: 종료 코드 리턴하기
  • type: 유형 보기
  • ul: 밑줄 처리해서 보여주기
  • ulimit: 제한하기
  • umask: 매스크 모드 설정하기
  • umount: 장치 해제하기
  • unalias: 별명 제거하기
  • uname: 시스템 정보 보기
  • unexpand: 공백 문자를 탭으로 변환하기
  • uniq: 중복된 문장 찾기
  • useradd: 사용자 계정 만들기
  • userdel: 계정 삭제하기
  • usermod: 사용자 계정정보 수정하기
  • unset: 설정 변수 해제
  • uptime: 시스템 부하 평균 보여주기
  • users: 로그인된 사용자 보여주기
  • w: 시스템에 접속한 사용자 상황 알아보기
  • wait: 프로세스 기다리기
  • wall: 모든 사용자에게 메시지 보내기
  • wc: 문자, 단어, 라인수 세기
  • whatis: 명령어의 간단한 설명보기
  • while: 루프 명령어
  • who: 사용자 알기
  • write: 콘솔 상에서 간단한 메시지 보내기
  • xcopy: 반복적으로 복사하기
  • XFree86
  • ypchfn: NIS에서 사용하는 chfn 명령어
  • ypchsh: NIS에서 사용하는 chsh 명령어
  • yppasswd: NIS에서 사용하는 passwd 명령어
  • zcat: 압축 파일 보기
  • zcmp: 압축 파일 비교하기
  • zforce: 강제로 gz 만들기
  • zgrep: 압축 상태에서 grep 실행하기
  • zmore: 압축 상태에서 more 실행하기
  • znew: .Z 파일을 .gz로 다시 압축하기
레퍼런스

우분투 백업 및 스냅샷 만들기 방법 소개

이 글은 우분투 백업 및 스냅샷 만드는 방법을 소개한다.

여기서 백업은 user 폴더 밑에 데이터를 보관하는 것을 말하고, 스냅샷은 시스템 운영체계 데이터까지 모두 보관하는 것을 말한다.

보통 우분투에서 백업은 deja-dup, 스냅샷은  timeshift, Backup in time, rsnapshot와 같은 도구를 사용한다. 사용방법은 어렵지 않은 데, deja-dup는 시스템 운영체계까지는 저장하지 않는다.

사용 방법은 다음 링크를 참고한다.

우분투 블랙 스크린 문제 해결 방법

이 글은 고질적인 우분투 블랙 스크린(black screen) 문제 솔류션 트리를 간략히 요약한다. 이 문제는 우분투 부팅했는 데, 로그인 조차 안되는 검정색 화면만 보여지는 현상이다. 

블랙 스크린 문제는 14.04, 16.04 모두 공통적으로 발생된다. 주 발생 원인은 NVIDIA + Unity + ubuntu 간에 충돌 발생이다. 충돌 발생 원인은 매우 다양하다. 정상적인 apt-get install 설치 후에도 발생할 수 있다. 이번엔 터치패드 패키지 욕심내어 설치하다, 노트북이 또 벽돌 되어 버렸다(Deja-dup 백업도 의미 없다. 다시 솔류션 트리를 수행하고, 아애 그 과정을 영원히 기록해 놓을 요량으로 글을 쓴다). 그냥 운이 없으면 블랙 스크린을 만난다고 보면 될 것이다.
욕심내지 말껄 T.T~

블랙 스크린은 로그인 메시지도 안뜨는 벽돌 상태로 변하기 때문에, 당하면 멘붕 오게 된다. 
정신이 붕괴되는 빌어먹을 블랙 스크린(처음 대면하면 우주에 혼자 미아가 된 듯 너무 막연하고 황당하다)

본인은 두대의 노트북을 이렇게 날려먹고, 수십번의 블랙 스크린과 무한 구글링을 경험했다. 지금은 아래 솔류션 트리로 한 두시간 만에 벽돌 노트북을 살릴 수 있다.

1. 터미널 모드 부팅 및 NVIDIA 드라이버 재설치
부팅 시 grub에서 e 키를 입력해, grub 스크립트의 부팅 옵션에 nomodeset 옵션을 추가한 후 F10입력해 부팅함. 이후, 터미널모드(CTRL+ALT+F1)로 부팅한다. 그리고, nvidia 드라이버를 삭제 후, 재 설치해야 한다.

sudo apt-get purge nvidia-*
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt-get update

NVIDIA GTX 1070일 경우 다음과 같이 해당 버전의 드라이버를 설치한다. 아니면, 본인 GTX 버전에 맞는 드라이버 번호를 확인하고, 설치하라.
sudo apt-get install nvidia-384
(혹은 367, 375)

2. 우분투 데스크탑 재설치
운이 없다면, 블랙 스크린 문제가 계속 발생할 것이다. 
이 경우, 다음과 같이, unity, nvidia, ubuntu-desktop, ubuntu-session을 모두 purge하고, 재부팅 후 다시 설치한다.
sudo apt-get purge unity*
sudo apt-get purge nvidia-*
sudo apt-get install ubuntu-desktop
sudo apt-get install ubuntu-session

혹시, 디펜던시 에러가 발생한다면 해당 버전 패키지를 설치하여 해결한다(링크 참고)

2018년 2월 26일 월요일

이더리움 소스 빌드 및 스마트 계약 개발 소개

이 글은 우분투에서 이더리움 소스코드 빌드 실행 방법과 스마트 계약 개발 방법을 간략히 소개한다.
스마트 계약(Smart Contract)이란 블록체인 기반으로 금융거래, 부동산 계약, 공증 등 다양한 형태의 계약을 체결하고 이행하는 것을 말한다(wikipedia). 스마트 계약은 1996년 닉 자보(Nick Szabo)가 처음 제안했다.

만약, A, B간에 날씨에 따른 스마트 계약을 하였을 때는 계약이 참여자간 분산되어 실행되며, 참여자간 동의 없이 취소될 수 없고, 계약 실행 조건이 변경될 수 없다. 이를 위해, 계약은 프로그램으로 작성되며, 계약과 거래는 분산 저장된다. 다음 영상은 그 개념을 보여준다.
스마트 계약 개념

이더리움은 비탈릭 부테린이 개발한 블록체인 기반 스마트 계약 개발 지원 분산 플랫폼이다. 이더리움 화폐 단위는 이더(ETH)이다. 이더리움은 블록체인 기반 암호 화폐거래 기술을 스마트 계약(smart contract) 플랫폼으로 확장했다. 이런 이유로 전세계에 많은 컨소시엄이 만들어졌고, 블록체인 기반의 계약에 대한 관심을 크게 촉발시켰다. 현재, 스마트 계약과 관련된 많은 어플리케이션이 개발되고 있다.
블록체인 기반 스마트 계약 개념
이더리움 기반 투표 어플리케이션 예(Full Stack Hello World Voting Ethereum)

이더리움에서 스마트 계약을 개발하기 위해서는 솔리디티(solidity)와 LLL(Low-level Lisp-like Language)언어를 사용해야 한다. 이 부분은 차후에 좀 더 다뤄보기로 한다.

PPA(Personal Package Archives) 설치
이더리움 PPA는 다음과 같이 설치한다.
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum

설치 후 노드에 계정을 생성하기 위해 다음 명령을 실행할 수 있다. 
geth account new



이더리움 네트워크에 연결하기 위해 geth 명령을 실행한다. 

소스 코드 다운로드 및 빌드
다음과 같이 소스 코드를 다운르드한다.
git clone https://github.com/ethereum/go-ethereum

이더리움은 가상머신에서 동작하며, Go, C, Python과 같은 다양한 언어로 개발되었다.
작업이 쉬운 Go언어로 개발된 이더리움을 빌드하기 위해 Go, C 컴파일러를 설치한다.
sudo apt-get install -y build-essential golang

golang는 1.7버전 이상이 필요하다. 혹시, 제대로 설치되지 않으면, 링크(1.7)를 참고해 설치한다. 이제 다음과 같이 다운로드된 소스 폴더에서 빌드한다.
cd go-ethereum
make geth

이제 build/bin/geth 폴더에서 다음 명령을 실행할 수 있다.
geth

 

이더리움과 스마트 계약 개발 방식
이더리움은 이더리움 가상 머신(EVM) 기반으로 동작한다. 이 가상머신 기반으로 실제 스마트 계약 모델을 개발하는 방법은 사실 쉽지는 않다. 이런 이유로 솔리디티(solidity)가 개발되었다. 솔리디티 설치는 다음 링크를 참고한다.
솔리디티는 객체지향언어와 유사하다. 계약은 솔리디티 계약이나 이더리움 트랜잭션을 통해 외부에서 만들어 질 수 있다. 다음 그림은 스마트 계약 개발을 위해 사용되는 솔류션 조합의 예를 보여준다.
스마트 계약 개발을 위한 솔류션 조합(Distributing Business Processes using Finite State Machines in the Blockchain)

다음은 간단한 스마트 계약 클래스 정의 예이다.

contract SimpleStorage {
   uint storedData;
   function set(uint x) {
      storedData = x;
   }
   function get() constant returns (uint) {
      return storedData;
   }
}

다음 영상은 날씨에 따른 스마트 계약 개발의 예를 보여준다.

솔리디티 기반 계약 개발의 좀 더 자세한 방법은 아래 링크를 참고한다.
LLL은 리습과 유사한 언어고, 마찬가지로 스마트 계약 모델 개발 시 활용한다. 이 두가지 개발 언어는 작성된 계약 모델이 빌드되면 가상 머신 코드로 전환된다. 참고로, 솔리디티보다 LLL이 생성된 코드는 30% 효율적이다. 다음은 LLL 예시와 관련 튜토리얼 영상이다.

(def 'only-node-owner (node)
  (when (!= (caller) (get-owner node))
    (panic)))


Remix(리믹스)와 같은 도구를 이용해 개발할 수도 있다. 이더리움에서 프로그래밍으로 계약 개발하는 방식은 JavaScript API web3.js 사용 방법이 있다. web3.eth.Contract를 사용한다.

이더리움 스마트 계약에 대한 좀 더 상세한 내용은 아래 링크를 참고한다.

레퍼런스

2018년 2월 22일 목요일

비트코인 소스 코드 빌드, 사용 및 블록체인 코드 구조 분석

얼마전 BIM principle에 올린 블록체인과 BIM - 스마트 계약을 위한 블록체인 기술에 대한 기고 요청이 있었다. 이 글은 4차 산업혁명의 핵심 키워드로 알려진 블록체인 응용인 비트코인 정체와 내부 메커니즘을 좀 더 깊이 확인하고 설명하기 위해, 개발용 소스 빌드, 설치 및 사용 과정을 수행하고, 블록체인 핵심 구조 및 코드에 대한 분석 내용을 간단히 요약한다. 이 과정을 통해, 블록 체인 개념과 실제 구현을 이해할 수 있고, 기술을 제대로 응용할 수 있을 것이다.
스마트 계약 개발 시 주로 많이 활용되는 이더리움에 대해서는 아래 글을 참고하길 바란다.


블록체인의 핵심 개념은 중앙에서 거래(트랜잭션)의 신뢰성과 추적성을 관리하는 것이 아니라, 거래 참여들이 트랜잭션 정보를 분산 저장하여, 신뢰성과 추정성을 확보하는 것이다.
참여자간 거래 내역을 블록체인으로 보관(MIT Technology Review)

이를 위해, 각 참여자들은 블록을 연결해, 트랜잭션의 변화를 관리한다.
Blockchain & Transaction Hash (Wikipedia)

블록체인을 이용한 비트코인 기본 동작 과정은 다음과 같다. 참고로, 사토시가 쓴 논문(한글버전)과 이더리움 위키을 읽으면 전체 개념을 알기 쉽다.
1. A가 B에게 송금
2. 블록(장부)가 생성됨
3. 생성된 블록이 블록체인 참여자들에게 전파됨
4. 참여자들이 해당 거래의 신뢰성을 체크함
5. 신뢰성이 확보되면, 해당 블록은 기존 블록체인에 추가됨
6. 양쪽의 거래 완료

여기서는 구글링을 통해 발견한 비트코인 빌드 관련 가장 잘 설명되어 있는 링크1링크2를 참고한다. 비트코인 프로토콜은 여기를 참고한다. 클래스 멤버 설명은 비트코인 doxygen 위키를 참고한다. 설치 과정은 다음과 같다.

블록체인 소스 빌드
블록체인 소스 빌드를 위해 우분투 운영체계를 미리 준비한다. 만약, 윈도우에서 우분투 설치하려면, Hyper-V, VirtualBox, VMware 등 가상머신 위에서 처리해도 된다. 여기에서는 우분투 16.04를 사용하였다.

개발용 소스 빌드 설치 시스템 업그레이드를 한다.
sudo apt-get update
sudo apt-get upgrade

아래 패키지를 설치한다. 디펜던시 에러가 알 수 있다. 에러는 로그를 확인해 해결하도록 한다. 
sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev
sudo apt-get install libboost-all-dev
sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler
sudo apt-get install libqrencode-dev autoconf openssl libssl-dev libevent-dev
sudo apt-get install libminiupnpc-dev

Bitcoin 소스를 다운로드 한다.
cd ~
git clone https://github.com/bitcoin/bitcoin.git

Bitcoin 은 버클리 데이터베이스 4.8을 사용한다.

이를 설치한다. 단, 경로 지정시 theusername 부분은 로그인한 계정 이름과 소스 설치 경로를 고려해 수정하라. 참고로, 버클리 데이터베이스는 메모리 상에서 계산 처리하는 방식을 취해 처리 속도가 매우 빠르다.
cd ~
mkdir bitcoin/db4/
cd bitcoin/db4
wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz'
tar -xzvf db-4.8.30.NC.tar.gz
cd db-4.8.30.NC
mkdir build_unix
cd build_unix
../dist/configure --enable-cxx --disable-shared --with-pic --prefix=/home/theusername/bitcoin/db4/
make install

Bitcoin, Berkley DB 4.8 을 컴파일한다.
cd ~/bitcoin/
./autogen.sh

디펜던시 에러가 나면, 아래 명령을 실행해 본다.
./configure LDFLAGS="-L/home/theusername/bitcoin/db4/lib/" CPPFLAGS="-I/home/theusername/bitcoin/db4/include/"

그리고 다시 /autogen.sh 를 실행한다.  이제 컴파일을 한다.
make -s -j5

제대로 빌드되었다면, 다음 화면을 볼 수 있다. 

아래 폴더에 바이너리 파일이 있다면 성공한 것이다.
cd ~/bitcoin/
./src/bitcoind
./src/qt/bitcoin-qt
./src/bitcoin-cli

블록체인 사용
블록체인은 일반적인 블록체인 네트워크와 테스트용 네트워크를 제공한다.

1. 일반 네트워크 서버 실행
\빌드된 블록체인을 서비스하는 서버를 실행해 본다.
$ ./bitcoind -daemon
Bitcoin server start

그리고, 다음 명령을 이용해 동기화된 블록수를 확인해 본다.
$ ./bitcoin-cli getblockchaininfo

그럼 다음과 같이 표시되고, 블록수가 출력된다.

백그라운드로 실행되고 있는 bitcoin-d를 다음 명령으로 프로세스 번호를 확인한다.
$ ps -ef | grep bitcoin

확인된 프로세스를 다음과 같이 실행 종료 시킨다.
$ kill -process_number

2.  테스트 네트워크 서버 실행
블록체인 테스트 네트워크 망에서 거래를 테스트해보자. 이를 위해 다음 명령을 실행한다.
$ ./bitcoind -regtest -daemon

3. 블록 생성
101개 블록을 생성한다. 거래는 이 블록에 이력 기록된다.
$ ./bitcoin-cli -regtest generate 101

블록 수를 확인해 본다.
$ ./bitcoin-cli -regtest getblockcount
101

4. 타 계좌 생성
계좌를 생성한다(ktw를 사용하고 싶은 다른 이름을 변경한다).
$ ./bitcoin-cli -regtest getnewaddress ktw
2N8Bm2d2mGFAF7z2FZSRHvdpSNUt39zWa5X

기본 잔고 BTC를 확인해 본다.
$ ./bitcoin-cli -regtest getbalance
50.00000000

앞서 생성한 계좌의 잔고를 확인해 본다.
$ ./bitcoin-cli -regtest getbalance ktw
0.00000000

5. 송금 
10 BTC 송금하기 위해 송금처, 송금액을 지정해 트랜잭션을 발생한다. 이 결과로 트랜잭션 식별번호(txid)가 리턴된다.
$ ./bitcoin-cli -regtest sendtoaddress [앞에서 생성한 계좌번호] 10

트랜잭션을 확인해 본다.
$ ./bitcoin-cli -regtest listunspent
[
]

미확정된 트랜잭션을 다시 확인해 본다.
$ ./bitcoin-cli -regtest listunspent 0

송금자의 잔고를 다시 확인해 본다.
$ ./bitcoin-cli -regtest getbalance
49.99996240

미확정 트랜잭션을 확정하기 위해 채굴을 실행한다. 이 결과로 블록체인에는 채굴로 인한 트랜잭션이 블록에 저장되고, 트랜잭션이 블록에 저장되어 송금이 확정된다.
$ ./bitcoin-cli -regtest generate 1
[
 "36254b11d6c28434b0e14a2a84d633d38e46177d9298a56e132346a3d340be0c"
]

송금 확정되었는 지 다시 확인해 본다.
$ ./bitcoin-cli -regtest listunspent

이런식으로 거래 이력이 블록에 기록되고, 참여자간 거래 정보가 공유된다. 블록에 기록된 정보가 참여자간에 다르면, 누군가 정보를 위조한 것이다.

6. 잔고 확인
잔고를 확인해 본다.
$ ./bitcoin-cli -regtest getbalance ktw
10.00000000

UI기반 비트코인 도구 사용
UI기반 비트코인을 사용하기 위해 빌드된 /src/qt/bitcoin-qt 를 실행해 보자.
다음과 같이, Bitcoin Core가 실행될 것이다.

아직은 비트코인 지갑에 아무것도 없다. 메뉴에서 Options 를 선택하고, 언어를 다음과 같이 한국어로 설정한다.


프로그램을 종료하고 다시 실행다면, 다음과 같이 한글 인터페이스를 볼 수 있다. 이제 지갑을 만들고, 거래를 하면 된다.

참고로, UI QT메뉴에서 호출되는 기능을 담당하는 모듈은 다음과 같다.

소스코드 분석 과정
이제 제대로 동작되고 있으니, 핵심적인 소스코드를 분석해, 동작 방식을 좀 더 상세히 확인해 본다. 참고로, 다른 괜찬은 코드 분석 사례를 여기에서 참고할 수 있다. 그리고, 비트코인 doxygen 위키에서 관련 클래스의 설명을 확인할 수 있다. 사토시가 쓴 논문(한글버전)을 읽으면 전체 개념을 알기 쉽다. 소스코드와 기본적인 문서를 확인하였으니, 이제 소스 코드의 역공학을 통해 동적 실행 및 정적 구조를 분석해본다. 비트코인 소스코드는 C++로 개발되어 있다. 비트코인 문서를 보면, 비트코인 어플리케이션 클래스 간 참조 그래프를 확인할 수 있다.

정적 모델 구조
정적 모델 구조는 주로 데이터, 구조체, 클래스 구조를 주로 확인한다. 가장 기본적인 몇 가지 구조를 살펴보자. 사토시 나카모토가 비트코인 개발 할 때 가장 핵심이 되는 구조는 primitives, wallet 패키지에 담겨져 있다. 패키지 모듈 간 의존성 그래프를 보면, 다음과 같이 primitives 정보를 wallet이 의존하고 있는 것을 알 수 있다.
그외 중요한 패키지는 다음과 같다.
  • RPC: 블록체인 네트워크 참여자간 명령이나 데이터를 주고 받음
  • consensus:  머클트리(merkle) 트리를 관리하고, 참여자간 컨센서스를 처리함. 머클트리는 트랜잭션을 요약해 암호화한 해쉬값을 관리함

1. primitive 패키지
primitives 패키지는 블록체인의 핵심이 되는 구조인 블록, 트랜잭션 구조가 정의되어 있다. 블록체인과 트랜잭션 정보를 관리한다.

블록들을 연결하는 블록체인 인덱스는 CBlockIndex 클래스에 다음과 같이 정의된다. 


CBlockIndex는 CBlock의 베이스 클래스이고, 블록의 체인을 연결하는 구조는 다음 클래스 다이어그램과 같이 블록 정보를 가지고 있는 해쉬맵과 블록 인덱스를 이용해 관리된다. 실제 블록 체인 데이터는 디스크에 저장되고, 필요할 때 메모리로 serialization된다.

블록 정보의 신뢰성과 추적성을 확보하는 방식은 해쉬와 트랜잭션 이력을 블록 체인이 담아두는 구조에 있다. 해쉬 생성은 다음 호출 그래프와 같이 SHA256함수를 사용한다.

블록마다 트랜잭션 이력 정보가 다음과 같이 리스트 형식으로 관리된다. 트랜젹션은 입금 CTxIn, 출금 CTxOut 클래스를 리스트로 관리하고 있다. 출금은 출금 BTC를 저장하는 nValue를 가지며, 최대 BTC 는 사토시가 정의한 21000000 이다. 입금은 입금 트랜잭션 해쉬를 관리하는 COutPoint를 보관한다. 각 입출금 트랜잭션은 트랜잭션 시나리오가 정의된 CScript를 가지고 있어, 다양한 트랜젹션 시나리오 계산을 지원한다. CScript는 바이트 연산자를 처리하는 가상머신이며, 트랜잭션 계산에 특화되어 있다.

2. wallet 패키지
wallet(지갑. 계정)을 관리한다. 데이터는 CDB클래스를 통해 저장된다. 이를 활용하기 쉽게 CWalletDB를 정의하고 있다. DB를 사용하는 CWallet은 거래를 위한 개인키, 공개키를 지갑에 설정하여, 트랜잭션 시 보안을 지원한다. 지갑은 트랜잭션 정보가 관리되는 블록체인과 연결되며, 거래되는 계정 장부(address book)를 관리한다.
wallet 주요 클래스 구조 

지금까지 분석된 비트코인 정보 모델 구조를 매우 간략하게 요약하면, 다음과 같다.
동적 실행 모델 구조
비트코인 전체 동작을 기술하는 것은 지면한계상 어려우니, 핵심적인 블록체인 처리 부분만 실행 구조를 분석해 보자.

1. 비트코인 서버 실행
비트코인 서버 메인인 bitmaind.cpp를 분석해 본다.

int main(int argc, char* argv[])
{
    SetupEnvironment();   // 비트코인 환경 설정
    noui_connect();           // 비트코인 서버 기능 처리 핸들러 등록


    return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);  // 서버 시작
}


bool AppInit(int argc, char* argv[]) 함수는 bitmaind 서버 옵션에 따라 필요한 함수를 호출한다. 이 함수은 다음과 같은 구조이다.
bool AppInit(int argc, char* argv[])
{
        AppInitBasicSetup();   // 어플리케이션 기본 설정
        fRet = AppInitMain();  // 메인 초기화
}

AppInitMain()이 호출되는 부분을 grep -r "AppInitMain" ./* 으로 확인해 본다.

AppInitMain가 코딩된 init.cpp를 확인한다. 주석에 Satoshi Nakamoto 2009 카피라이트를 발견할 수 있다. 라이센스는 MIT이다.
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.


bool AppInitMain()
{
    RegisterAllCoreRPCCommands(tableRPC);
    RegisterWalletRPC(tableRPC);

    bool fLoaded = false;
    while (!fLoaded && !fRequestShutdown) {

        do {
                LoadBlockIndex(chainparams);       // 블록 인덱스 로딩
                LoadGenesisBlock(chainparams);   // 최초 블록 제너시스 블록 로딩
                pcoinsdbview->Upgrade();              // 비트코인 뷰 업그레이드
                ReplayBlocks(chainparams, pcoinsdbview.get());  
                RPCNotifyBlockChange(true, tip);   // 블록 변경시 변경 공지함
        }
    }

    OpenWallets();   // 지급 열기
}

이 중 관심이 가는 Load다GenesisBlock() 을 확인한다. validation.cpp에 있다.
bool CChainState::LoadGenesisBlock(const CChainParams& chainparams)
{
    LOCK(cs_main);   // 쓰레드 동기화를 위한 락 처리

    if (mapBlockIndex.count(chainparams.GenesisBlock().GetHash()))  // 이미 블록 맵에 제네시스 블록이 등록되어 있으면, 굳이 로딩할 필요 없이 리턴함.
        return true;

        CBlock &block = const_cast<CBlock&>(chainparams.GenesisBlock());  // 블록 생성
        CDiskBlockPos blockPos = SaveBlockToDisk(block, 0, chainparams, nullptr); // 블록을 저장

        CBlockIndex *pindex = AddToBlockIndex(block); // 블록 인덱스에 블록 추가
        CValidationState state;
        ReceivedBlockTransactions(block, state, pindex, blockPos, chainparams.GetConsensus()); // 블록 트랜잭션 처리

    return true;
}

블록은 아래 함수를 통해 기존 블록 맵과 인덱스에 삽입되며, 입력된 해쉬값을 새로 생성된 해쉬값과 쌍으로 만들어, 다시 해쉬값을 생성한다. 각 블록의 해쉬가 일부 변경되면, 블록 체인의 모든 해쉬값은 재계산되어야 하고, 블록체인 참여자의 해쉬값도 모두 변경되어야 하므로, 위변조가 어렵다. 참고로, mapBlockIndex는 해쉬값을 생성하여, 해쉬값으로 객체를 관리하는 컨테이너인 unordered_map의 인스턴스이다.
CBlockIndex* CChainState::AddToBlockIndex(const CBlockHeader& block)
{
    uint256 hash = block.GetHash();   // 입력된 블럭 해쉬값 획득
    CBlockIndex* pindexNew = new CBlockIndex(block);   // 블럭을 생성하고 인덱스를 획득
    pindexNew->nSequenceId = 0;
    BlockMap::iterator mi = mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first;
    pindexNew->phashBlock = &((*mi).first);    // 새로운 블럭의 해쉬값 생성 후 할당

    BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock);  // 이전 블럭 인덱스 획득
    if (miPrev != mapBlockIndex.end())   // 이전 블럭이 있으면
    {
        pindexNew->pprev = (*miPrev).second;   // 새로운 블럭의 이전 블록을 찾은 이전 블록과 체인 연결

        pindexNew->nHeight = pindexNew->pprev->nHeight + 1;  // 깊이 증가
        pindexNew->BuildSkip();
    }
    pindexNew->nTimeMax = (pindexNew->pprev ? std::max(pindexNew->pprev->nTimeMax, pindexNew->nTime) : pindexNew->nTime);   // nTimeMax 타임스탬프 갱신
    pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew);
    pindexNew->RaiseValidity(BLOCK_VALID_TREE);  // Validity 플래그 마스크 설정
    if (pindexBestHeader == nullptr || pindexBestHeader->nChainWork < pindexNew->nChainWork)
        pindexBestHeader = pindexNew;

    setDirtyBlockIndex.insert(pindexNew);

    return pindexNew;
}


CBlockIndex * CChainState::InsertBlockIndex(const uint256& hash)
{
    BlockMap::iterator mi = mapBlockIndex.find(hash);  // 입력된 해쉬의 블록 획득
    if (mi != mapBlockIndex.end())  // 해쉬가 있으면 해당 블록 인덱스 리턴
        return (*mi).second;

    // Create new
    CBlockIndex* pindexNew = new CBlockIndex();   // 블록 인덱스 생성


    // 주어진 블록 해쉬와 새로 생성된 블록 해쉬를 합친후, 이에 대한 해쉬를 획득함
    mi = mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first;  
    pindexNew->phashBlock = &((*mi).first);

    return pindexNew;
}


2. 계좌 트랜잭션 처리
./bitcoin-cli 명령을 이용해 다양한 트랜잭션 처리를 할 수 있다.  명령은 rpcwallet.cpp에 CRPCCommand 구조체 형식의 명령 테이블로 정의되어 있다.

static const CRPCCommand commands[] =
{ //  category  name                    actor (function)        argNames
    //  --------------------- ------------------------          -----------------------         ----------
    { "rawtransactions",    "fundrawtransaction",   &fundrawtransaction,    {"hexstring","options","iswitness"} },
    { "hidden","resendwallettransactions",         &resendwallettransactions,      {} },
    { "wallet","abandontransaction",   &abandontransaction,    {"txid"} },
       ...
    { "wallet","getaddressinfo",        &getaddressinfo,        {"address"} },
    { "wallet","getbalance",             &getbalance,            {"account","minconf","include_watchonly"} },
    { "wallet","getnewaddress",        &getnewaddress,         {"account","address_type"} },
       ...
    { "wallet","gettransaction",        &gettransaction,        {"txid","include_watchonly"} },
       ...
    { "wallet","listlockunspent",      &listlockunspent,       {} },
       ...
    { "wallet","sendtoaddress",        &sendtoaddress,        
       ...
    { "wallet","rescanblockchain",     &rescanblockchain,      {"start_height", "stop_height"} },
    { "generating",         "generate",             &generate,              {"nblocks","maxtries"} },
};

주요 bitcoin-cli 명령 처리 과정을 살펴보자.
generate 명령을 수행하면, 등록된 generate함수가 호출된다.  generate() 함수는 generateBlocks() 함수를 호출하며, 다음과 같은 블록 로직을 수행한다.

UniValue generateBlocks(std::shared_ptr<CReserveScript> coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript)
{
   int nHeightEnd = 0;
   int nHeight = 0;
   {   
       nHeight = chainActive.Height();        // 체인 높이 획득
       nHeightEnd = nHeight+nGenerate;
   }
   unsigned int nExtraNonce = 0;
   UniValue blockHashes(UniValue::VARR);
   while (nHeight < nHeightEnd)             // 추가할 체인 높이가 될때까지 체인 추가
   {
       CBlock *pblock = &pblocktemplate->block;
       ++nHeight;                                 // 체인 높이 증가
       blockHashes.push_back(pblock->GetHash().GetHex());   // 블록 해쉬를 블록해쉬맵에 추가함
   }
   return blockHashes;
}

sendtoaddress 명령 수행과정을 살펴보자. 이 명령은 다음 같은 옵션을 가진다. 
$ ./bitcoin-cli -regtest sendtoaddress [앞에서 생성한 계좌번호] 10

이를 수행하면, sendtoaddress() 함수가 실행된다. 먼저 request 파라메터에서 계좌번호에 해당하는 CWallet pwallet 객체와 송금할 금액 CAmount nAmount 변수를 얻는다. 송금계좌를 CTXDestination dest 객체에 넣고, 계좌에 대한 트랜잭션 처리를 위해, CWalletTX wtx를 준비한다. 이제 SendMoney() 함수를 호출해 송금한다. 그리고, 송금 트랜잭션에 대한 해쉬값을 얻어 리턴한다. SendMoney() 함수는 트랜잭션(거래) 객체를 생성하여, CommitTransaction() 함수에서 트랜잭션 이력 관리를 위한 링크를 만들고, 거래 사건을 브로드케스팅를 준비한다. 
아래 코드는 이 거래의 핵심적인 코드만 추려 보인 것이다.

UniValue sendtoaddress(const JSONRPCRequest& request)
{
    CWallet * const pwallet = GetWalletForJSONRPCRequest(request);     // 입력 파라메터 정보 획득

    // Make sure the results are valid at least up to the most recent block
    // the user could have gotten from another RPC command prior to now
    pwallet->BlockUntilSyncedToCurrentChain();

    CTxDestination dest = DecodeDestination(request.params[0].get_str());    // 송금 목적지 획득
    CAmount nAmount = AmountFromValue(request.params[1]);                // 송금액 획득
    CWalletTx wtx;
    SendMoney(pwallet, dest, nAmount, fSubtractFeeFromAmount, wtx, coin_control);   // 송금
    return wtx.GetHash().GetHex();       // 트랜잭션 해쉬값 리턴
}


static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew, const CCoinControl& coin_control)

{

    CScript scriptPubKey = GetScriptForDestination(address);   // 송금 계좌 주소 파싱

    CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};    // 송금 영수증 정보 생성

    vecSend.push_back(recipient);
    pwallet->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError, coin_control);     // 트랜잭션 생성
    pwallet->CommitTransaction(wtxNew, reservekey, g_connman.get(), state);   // 트랜잭션 처리
}

bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state)
{
    AddToWallet(wtxNew);   // wallet에 트랜잭션 객체를 추가해 거래 이력정보를 관리하도록 함
    for (const CTxIn& txin : wtxNew.tx->vin)
    {
         CWalletTx &coin = mapWallet[txin.prevout.hash];   // 이전 트랜잭션 해쉬를 통해, 트랜잭션 객체 획득
         coin.BindWallet(this);                                        // 획득한 트랜잭션 객체와 링크 연결함
         NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
    }
    CWalletTx& wtx = mapWallet[wtxNew.GetHash()];        // 생성된 트랜잭션 객체 획득
    if (fBroadcastTransactions)  // 트랜잭션 브로드캐스트함
         wtx.AcceptToMemoryPool(maxTxFee, state); // 브로드캐스트 메모리풀에 추가. 거래 이력 전파.
    return true;
}


마무리
이 글에서는 비트코인 분석을 위해 소스를 빌드하고, 동작 방식을 확인해 보았다. 코드를 분석해 보면, 복잡하기는 하지만 블록체인 개념에 새로운 기술을 사용한 것은 아니다. 공개키/개인키 암호화, 해쉬함수, 블록과 인덱스 관리 구조, 트랜잭션 이력관리 리스트, 데이터베이스 처리 등은 이미 기존에 많이 활용하던 기술이다. 코드는 깔끔하고, 크게 군더더기가 없어 보이는 데, 트랜잭션 처리에 간단한 가상머신을 만들어, 거래 시나리오를 사용자화할 수 있는 확장성을 지원한 개념이 좋았다.

비트코인에서 사용한 블록체인이 사회적으로 크게 이슈화 된 이유는, 기존 시스템의 신뢰성 확보 방안인 중앙집중식 관리가 네트웍 및 보안 기술의 발달로 분산처리화되면서, 기존 시스템의 기득권과 게임의 법칙이 변화하고 있는 부분에 있다.

컨텐츠의 신뢰성, 무결성, 추적성을 통제하는 모든 시스템에 블록체인 기술을 활용할 수 있다. 스마트 계약(contract)을 구현하기 위해 블록체인을 응용하는 경우가 많아지고 있다. 참고로, 이더리움은 계약과 관련된 정보를 사용자화하여, 블록으로 관리할 수 있는 플랫폼을 제공한다. 이더리움의 많은 개념은 비트코인에서 가져왔다.

블록체인이 만능이 아님은 여러 해킹 뉴스를 통해 접할 수 있다. 이는 기술 활용 전에 사회적, 제도적 준비가 되어 있어야 한다고 생각한다. 아울러, 블록체인을 제대로 활용하기 위해서는 기술에 대한 근본적인 이해가 필요할 것이다.

기타 레퍼런스

2018년 2월 17일 토요일

지속가능한 도심 재생 개발과 메이커 시티

이 글은 지속가능한 도시 재생과 개발 관점에서 메이커 시티 책을 소개합니다.


소비하는 도시에서 생산하는 도시로!
삶의 질 개선을 향한 4차 산업혁명 시민 참여 인프라, 메이커 시티


메이커 시티는 시민 중심 4차 산업혁명 실천 전략, 도심 재생, 스마트 시티와 같은 지속가능 시민참여형 도시 개발과 재생, 첨단 제조 도시, 스타트업 컴퍼니와 메이커, 교육자를 위한 책입니다. 이 책에 포함된 기술, 정책, 사례는 어느 도시에도 적용할 수 있으며, 궁극적으로 시민 삶 개선과 지역 사회 발전에 초점이 맞춰져 있습니다.

이 책은 미국 행정부가 추진한 다양한 메이커 시티, 메이커와 스타트업 육성, 메이커 교육 사례를 인터뷰하고 조사 분석한 내용이 포함되어 있습니다.

Maker Cities (IFTF)

Make Media 설립자 및 CEO로 유명한 데일 도허티(Dale Dougherty)는 메이크 메거진 발행, 세계 최초 메이커 페어 설립/시작한 메이커 운동의 아버지입니다. 저자 피터 허시버그(Peter Hirshberg)는 도시 혁신 재단, Re: Imagine Group 설립자이며, 애플, 소니 등 전사 마케팅 전략 수립, 샌프란시스코 도시 정책, MIT 미디어랩 자문, 도시 혁신 프로젝트를 수행하였으며, TED, CeBIT 등 강연한 유명인사입니다. 저자 마샤 카다노프(Marcia Kadanoff)는 도시 혁신 재단(미) CSO(Chief Strategy Officer)이며, 애플, 마이크로소프트 등 마케팅 전략을 개발하고, 여성 리더 200 멤버로 선정되었습니다. 샌프란시스코 도시 재생 위원입니다.

역자인 강태욱, 유만선, 조춘익은 모두 국내 메이커 운동 초창기 멤버로 메이커 문화에 관심을 갖고 참가하며, 책을 저술하거나 과학 교육 정책 등을 개발한 경험이 있습니다. 이 책은 역자의 메이커 운동 참여 경험도 함께 부록으로 포함하고 있습니다.

주요 내용은 다음과 같습니다.

  1. 메이커 운동 정신과 역사를 이야기한다. 
  2. 메이커 시티를 만들기 위한 생태계 구축 및 활성화 방안을 설명한다.
  3. 메이커 운동과 학습 공동체를 구성하고 활성화하는 방법을 이야기한다.
  4. 전통적인 방법과는 다른 각자 재능을 고려한 메이커 시티를 만드는 방법을 설명한다.
  5. 미국 도시제조동맹의 견해를 들어보고, 메이커 커뮤니티에 대한 모범 사례로서 살펴본다.
  6. 러스트 벨트 지역이 성공적인 메이커 시티로 거듭나게 된 과정을 설명한다.
  7. 샌프란시스코 메이드, 뉴욕 메이드, 버닝맨 등 다양한 성공 사례를 살펴본다.
  8. 도시 부동산 개발 전략을 다룬다. 도시 재생, 혁신 도시와 센터, 공간 계획, 특별 도시 구획 전략을 살펴본다.
  9. 시민 해커톤(hackathons), 프로토타이핑, DIY city, 도시 문제 중심의 청소년과 성인 교육 전략과 사례를 제공한다.
  10. 메이커 시티가 어떻게 시민 참여형 열린 도시로 진화할 수 있는 지를 설명하고, 미래 메이커 시티 운동 의미가 무엇인지를 이야기한다.

책의 목차는 다음과 같습니다.

  1. PREFACE 메이커 국가 건설 
  2. 소개와 행동 
  3. 메이커 운동과 도시 
  4. 개방형 생태로서 메이커 시티 
  5. 교육 
  6. 노동력 개발 
  7. 선진화된 제조업과 공급 체인 
  8. 사례연구 도시 제조 동맹 
  9. 도시 공간 부동산 개발 
  10. 사례연구 메이커 대도시 
  11. 메이커 시티에서의 시민 참여 
  12. 메이커 시티의 미래 

Maker Cities (makezine.com)

이 책은 단순히 메이커 기술이 아닌, 메이커 운동, 오픈소스 문화, 정책과 조직 등 메이커 생태계 개발에 초점을 맞춰 다양한 사례와 인터뷰 내용을 담고 있습니다. 메이커 운동을 활용하여 도시 시민들이 삶의 질 개선과 경제적 기회를 창출할 수 있는 통찰을 제공하고 공유하는 것이 이 책의 목표입니다. 이 책이 4차 산업혁명과 메이커 운동에 관련된 많은 이슈에 대한 좋은 길잡이가 되길 바랍니다.

2018년 2월 3일 토요일

미래 혁신을 위한 연구소 IFTF

IFTF(Institute For The Future)는 캘리포니아 팔로 알토에 기반을 두고 있는 도시 미래 혁신 연구 싱크탱크이며, 독립적인 비영리 연구 기관이다. 이 기관은 1968년 RAND사에서 분사된 조직이다. IFTF는 직업과 교육, 식량, 기술, 산업, 신기술 등 미래예측과 도시와 시민 삶의 질에 관련된 모든 부분을 다룬다.

IFTF는 우리에게 영향을 미치는 모든 것들에 대한 미래 변화 시나리오를 예측하고, 솔류션과 아이디어를 제안하고 있다.
Who we are and what we do (IFTF)

초기에 연구소는 미래 예측을 위해 델파이 방법을 주로 사용하였고, 이후 통계적 방법으로 발전해 나갔다. 이후, 수학적 모델을 통한 사회 모델링을 시도하였다. 이런 노력을 통해, 미래 분석과 예측에서 세계적으로 좋은 평판을 쌓아왔다. IFTF의 훌륭한 보고서는 선물 시장 예측과 기업의 미래 투자 계획에도 활용되었다. 

IFTF는 연간 보고서인 Future Now를 꾸준히 발간하고 있다. 최근 몇년은 생명공학, 디지털 트랜스포메이션, 도시 지속가능성, 스마트시티, 메이커 시티, 인간과 기계의 공생 관계에 대한 연구 내용도 공개하고 있다. 

메이커 시티

연구소는 다양한 지역 커뮤니티, 대학, 산업계 전문가 등 네트워크와 연결되어 있으며, 워크샵, 파트너쉽, 연구 내용 발간 및 언론 보도 등 다양한 활동을 하고 있다. 




정부 프로그램을 위한 데이터 드리븐 혁신 플랫폼 소크라타

이 글은 정부 프로그램을 위한 데이터 드리븐(data driven) 혁신 플랫폼인 소크라(socrata)를 간략히 소개한다. 소크라타는 2007년 케빈 메티트에 의해 설립되었다. 소크라타는 도시 사회 개선을 위해, 정부 데이터를 오픈하는 기술을 지원하는 플랫폼 회사이다.

도시 시민이 정부 데이터를 검색 가능하게 하고, 사용할 수 있도록, 공공기관에게 데이터 플랫폼과 클라우드 서비스를 제공한다. 이를 통해, 공공부문은 데이터 중심 운영이 가능하고, 획기적 비용 절감이 가능하다.

이 기술은 AWS(아마존 웹 서비스)의 공공 부문 클라우드에 최적화된 방법을 제공한다.
Public Data as Utility

소크라타에서 제공된 오픈 데이터는 메이커들이 O2O 서비스 제공 스타트업을 만든다던지, 시민들이 도시 문제나 삶의 질을 개선하기 위해 아이디어나 솔류션을 제공할 때 유용할 수 있다. 이외에 예상하지 않은 사회적 가치를 오픈 데이터를 통해 얻을 수 있다.

1871 프로젝트

시카고에서 1930년대 건설된 머천다이즈 마트 쇼핑몰은 메이커 시티의 인큐베이터 및 혁신 허브인 1871 프로젝트 본거지다.

1871-Chicago's Digital Startup Hub

창립자는 하워드 툴먼(Howard Tullman)이며, 미국에서 가장 큰 인큐베이터를 운영한다. 이곳은 50,000평만피트 이며, 매일 2,000명이 넘는 사람들이 일한다. 이 공간은 벤처 기업을 유치하고, 스타트업을 위한 멘토링, 교육을 제공한다.






서비스로서의 제조업

우버와 같은 공유경제 모델을 제조업(Manufacturer) 분야에 적용하는 업체가 있다.
Nick Pinkstone(닉 핑크스톤)이 만든 Plethora(플레소라)는 온라인상에서 제공되는 3D프린팅, CNC 소프트웨어를 이용해, 치수, 모양을 디자인한 후 도면을 보내면, Plethora 공장에서 가공된 제품을 택배로 배달해 준다.

New Dimensions to 3D printing





2018년 1월 28일 일요일

에어 풍선 기반 데이터 취득 키트 DIY 키트

다양한 실험용 키트를 우주에 보내는 영상이 뉴스 (#1#2)에 나온적이 있다. 이 글은 이를 위한 에어 풍선 기반 데이터 취득 키트 DIY 키트에 대한 레퍼런스를 소개한다.


1. Sent into Space
우주에 물건, 인공위성, 카메라를 보내는 프로젝트 사이트이다.

아래에 이와 관련된 키트를 판매하고 있다.



2. High Altitude Science
고고도 과학 데이터 취득 및 연구를 위한 사이트이다.

기상 관측용 풍선 키트를 판매하고 있다.


이 글은 에어 풍선 기반 카메라 데이터 취득을 위한 장치 개발 방법을 자세히 설명하고 있다. 
Send a camera to space (인스트럭터블)


오픈소스 기반 사운딩 로켓(Sounding Rocket)

이 글은 오픈소스 기반 사운딩 로켓에 대한 몇몇 괜찬은 레퍼런스를 정리한다.

1. 오픈소스 기반 로켓 시뮬레이션 개발 레퍼런스
헬싱키 대학에서 로켓 시뮬레이션 소프트웨어 개발을 위해 연구한 내용이다.
로켓 비행 단계
시뮬레이션 소프트웨어 구조(UML)
테스트 로켓과 로켓 시뮬레이션 결과

2. Rocketry 
아마추어 로켓 개발자 블로그이다. 많은 내용과 아이디어가 정리되어 있다. 
3. Hobby Space
취미로 로켓을 개발하는 사람들이 소프트웨어, 디자인 등 리소스를 구할 수 있는 곳이다. 
로켓 엔진
4. Arocketry
로켓 개발에 사용되는 소프트웨어, 지침 등을 모아둔 사이트이다. 
5. Sirius Rocketry
로켓 KIT 판매 사이트이다. 
6. Rocketarium
전문 로켓 KIT 판매 사이트이다. 
7. JonRocket
로켓 KIT 판매 사이트이다. 
주요 사운딩 로켓 제작과 관련된 레퍼런스들을 살펴보았다. 다만, 사운딩 로켓을 테스트하기 위한 장소가 별로 없는 국내에서는 관련 연구 개발이 제약적인게 아쉽다.