Monthly Archives: July 2018

Intel rapid storage Raid1 하드 확장

인텔 마더보드에는 Raid 컨트롤러가 포함되어 있다.(아마도 대부분 포함되어 있을 것이다.) 이것을 사용하여 Raid1 설정으로 잘 사용하고 있었는데 두번의 하드디스크 고장으로 하드가 1테라에서 2테라가 되었는데 Raid로 복구하다 보니 여전히 1테라만 사용할수 밖에 없어서 이것을 해결해 보기로 하고 도움말을 찾아 보니 아래 링크에 설명이 잘 되어 있다.

RAID1 볼륨을 늘리는 법

방법은 간단하다. Bios에서 ctrl-I 눌러서 RAID설정에 들어간다음 Reset Disks to Non-RAID 를 선택하여 RAID 디스크를 해제한다. 즉 일반 디스크로 만든다. 둘다 일반으로 만든다. 이과정에서 데이터가 다 지워진다고 경고하는데 RAID1의 경우는 지워지지 않는다. 불안하면 일단 하나만 RAID를 해제한다.

윈도우 부팅이 완료되면 이제 일반 하드가 되었으므로 파티션을 키울수 있다. 파티션을 최대 크기로 키운다.

Intel Rapid Storage 드라이버 및 프로그램을 다운 받는다. 글을 쓰는 현재 최신버전은 16.5.1.1030이다.

설치를 다 하고 RAID설정을 하는데 알수없는 오류가 난다면서 안된다. 이것때문에 5시간을 헤멨다. 시스템 부팅을 20번쯤 했나보다. 아무리 검색해도 원인을 찾을 수가 없다. 이리저리 해보다가 원인을 찾았다. Intel RAID 설정을 하기 위해서 하드디스크 일부를 사용한다. 뭐 당연하다. 그런데 위에서 볼륨을 최대로 늘려 놨기 때문에 RAID설정을 저장할 장소가 없는 것이다. 다시 볼륨을 축소하고 RAID설정을 하니 잘 된다. RAID설정이 되면 볼륨을 다시 최대로 늘리면 된다.

RAID1으로 PC를 사용한 이후로 위에서 이야기 했듯이 하드가 두번이나 깨졌다. 그래도 고장난 하드빼고 새하드 끼우기만 하면 알아서 척척 해준다. 꼭 쓰기를 권장한다.

Firebase, Node server + Android

android studio,

firebase 홈페이지>프로젝트선택>프로젝트설정>일반에서 google-services.json을 다운로드 하여 프로젝트에 추가

project gradle에 아래 내용추가

apply plugin: 'com.google.gms.google-services'
...
implementation 'com.google.firebase:firebase-core:16.0.1'
implementation 'com.google.firebase:firebase-messaging:17.1.0'
implementation 'com.google.firebase:firebase-auth:16.0.2'

android, onStart

FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( new OnSuccessListener<InstanceIdResult>() {
    @Override
    public void onSuccess(InstanceIdResult instanceIdResult) {
        deviceToken = instanceIdResult.getToken();
    }
});

node.js

var admin = require('firebase-admin');
var serviceAccount = require('./smallet-27f86-firebase-adminsdk-7vwqg-b48b172508.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: 'https://smallet-27f86.firebaseio.com/'
});

여기서 사용되는 json file은 firebase 홈페이지>프로젝트선택>프로젝트설정>서비스계정>새 비공개 키 생성 에서 만들어야 한다. 위에서 만든 google-services.json을 쓰면 안된다.(이것만 헛갈리고 대부분 그냥 절차대로 하면 됨)

서버에서 메시지를 특정 device에 보낼때는 아래 예제와 같이 한다. message 안의 data부분은 알아서 만들면된다. 중요한건 token이고 token은 위 안드로이드 예제에서 저장된  deviceToken을 사용하면 된다.

function sendNotification(tokenId, _receipt) {
  var message = {
    data: {
      transactionHash: _receipt.transactionHash,
      gasUsed: _receipt.gasUsed + "",
      to: _receipt.to + "",
      status: _receipt.status + ""
    },
    token: tokenId
  };
  (async () => {
    console.log(message);
    admin.messaging().send(message)
      .then((response) => {
        // Response is a message ID string.
        console.log('Successfully sent message:', response);
      })
      .catch((error) => {
        console.log('Error sending message:', error);
      });
  })();
}

안드로이드쪽에서 이 메시지를 수신하려면 서비스를 만들면 되고, 포그라운드이든 백그라운드이든 onMessageReceived는 호출되므로 백그라운드에서는 노티피케이션을, 포그라운드에서는 보여지는 액티비티에서 적절히 처리 하면 되겠다.

public class FirebaseService extends FirebaseMessagingService {
    String TAG = "wallet";

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.d(TAG, "From: " + remoteMessage.getFrom());

        // Check if message contains a data payload.
        if (remoteMessage.getData().size() > 0) {
            Log.d(TAG, "Message data payload: " + remoteMessage.getData());
            Bundle bundle = new Bundle();
            for (Map.Entry<String, String> entry : remoteMessage.getData().entrySet()) {
                bundle.putString(entry.getKey(), entry.getValue());
            }
            if (MainActivity.isActivityVisible()) {
                Message msg = new Message();
                msg.what = Constants.RECEIVE_TX_RECEIPT;
                msg.setData(bundle);
                MainActivity.mHandle.sendMessage(msg);
            } else {
                sendNotification(bundle);
            }
        }

    }

    private void sendNotification(Bundle data) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtras(data);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);
        String channelId = getString(R.string.default_notification_channel_id);
        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        String title = data.getString("status").equals("true") ? "Transaction Success" : "Transaction Fail";
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, channelId).setSmallIcon(R.drawable.ic_notification)
                        .setContentTitle(title)
                        .setContentText(String.format("to %s", data.getString("to")))
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        // Since android Oreo notification channel is needed.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId,
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        }

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
}

 

 

ropsten testnet용 faucet을 만들다-1

스몰렛 베타 버전을 내려고 보니 테스트를 위한 Ether가 필요한데, ropsten faucet이 잘 동작하지를 않는다. 아무래도 오류인듯 한것이 신청자가 한명도 없을때도 이더를 주지 않는다. 이래서야 테스트를 할 수가 없다.

이리저리 궁리하다가 그냥 테스터 이더를 주는 faucet을 직접하나 만들면 어떨까 싶다. 실제도 아니고 test넷의 채굴 난이도야 얼마나 되겠는가. 까짓거 채굴해서 직접 나눠주는 방법을 해보기로 한다.

geth에서 CPU채굴로 해보니 거의 채굴이 안된다. 역시 POW채굴은 그래픽 카드가 있어야 한다. geth CPU채굴은 간단하다. 여기 모든 예제는 ropsten testnet 기준이다. OS는 ubuntu 16.04 이다.

geth –testnet console
>miner.start(10)

start안에 들어가는 숫자는 채굴을 실행할 thread의 갯수이다. 아무튼 이건 거의 채굴 안된다.

GPU채굴을 하려면 설치를 좀 해야 한다. 먼저 OpenCL부터,

sudo apt-get install nvidia-cuda-toolkit clinfo

clinfo를 실행하여 NVIDIA어쩌구 하는 내용이 쭉 나오면 설치 성공이다.  인터넷에 보면 여러가지 OpenCL설치 방법이 있는데 NVIDA드라이버를 NVIDA사이트에서 받아서 설치하는 방법이 표준 답으로 되어 있는데 내 경우는 이렇게 하니 ubuntu desktop이 망가져 버려서 툴킷만 따로 설치하는 방법으로 하였다.

다음은 채굴기 설치. 채굴기는 cpp-ethereum을 설치하면 그 안에 ethminer가 들어 있다.

sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum

설치가 되었으면 이제 실행을 한다. 메인넷은 ethminer만 있으면 그냥 하면 되는데 testnet은 geth를 사용해서 했다. 다른 방법이 있을지도 모르지만 geth에서 해야 지갑도 쓰기 편하고 여러가지로 편하다.

geth –rpc –rpccorsdomain localhost –datadir /your/geth/datadir –testnet
ethminer -G

이렇게 하면 ethminer가 geth에 rpc로 연결해서 마이닝 결과를 넘겨준다. geth에는 반드시 채굴 보상을 받을 계정을 만들어 둬야 한다. geth에 연결할 일이 있을때는,

geth attach ipc://your/geth/datadir/geth.ipc

이렇게 연결하면 geth console을 열어서 다양한 정보를 관찰할 수 있다.

하룻밤을 돌렸더니 1,000 이더가 모였다. 뭐 이정도면 스몰렛 테스터용 이더 모으는데는 별 문제가 없겠다. 이제 이더 신청 받아서 나눠주는 모듈을 만들어야 하겠다. 이건 파트 2 에서.

메인넷과 ropsten을 같이 동작하게 하려면 포트를 서로 다르게 하면 된다.

geth –rpc –rpcport 8546 –rpccorsdomain localhost –datadir /your/data/dir –port 30304

이더리움 스몰렛 베타 테스터 신청 안내.

이더리움 스몰렛은 스몰렛 네트웍스에서 앞으로 나올 다양한 가상화폐 지갑 중에서 가장 먼저 발표되는 것입니다. 스몰렛은 하나의 키 보관소 앱(스몰렛 키 볼트)이 다양한 가상화폐의 키를 한 곳에서 보관하고 지갑 앱들이 이를 공유하는 개념입니다. 모든 가상화폐 키를 하나의 마스터 키에 의해서 관리하는 것을 목표로 하고 있습니다.

베타 테스트에 참가 하는 테스터 여러분들 중 1,000분을 선발하여 SILC재단에서 배포하는 SILC 토큰을 1,000개씩 드릴 예정입니다. 활동이 활발하신 분들께는 더 많은 SILC 토큰을 배포할 예정입니다.

테스터 참가 방법은 다음과 같습니다.

우선 아래 링크 두개를 눌러서 베타 테스터 신청을 합니다. 두개의 앱으로 구성되어 있으므로 반드시 둘다 신청해야 합니다.

키 볼트 베타 테스터 신청

이더리움 스몰렛 베타 테스터 신청

신청이 완료되면 아래 링크로 들어가거나 구글 플레이에서 “스몰렛”을 검색하여 이더리움 스몰렛을 다운 받습니다. 알파 테스트나 기타 이유로 이전 버전이 설치된 분들은 앱을 모두삭제하고 다시 설치하시기 바랍니다. 삭제전에 마스터 시드를 백업 하는것을 잊지 마세요.

구글 플레이 이더리움 스몰렛 다운로드

 

설치 후 이더리움 스몰렛을 실행하면 위 화면과 같이 키 볼트 설치 안내가 나옵니다.  확인을 눌러서 설치 페이지로 이동하여 스몰렛 키 볼트를 설치 합니다.

설치 후 다시 이더리움 스몰렛으로 돌아오면 위 화면과 같은 메시지가 나옵니다. 스몰렛 키 볼트에 아직 마스터 시드가 생성되지 않았기 때문에 마스트 시드를 생성하라는 메시지입니다. “실행”을 눌러서 스몰렛 키볼트를 실행 합니다.

 

스몰렛 키 볼트 화면은 붉은색입니다. 필요시 키볼트로 이동할때가 있으므로 어느 앱에 있느지 확인 하는데 좋습니다. 이 화면에서 패스워드를 입력하고 “새 마스터 시드 생성”을 누르면 새로운 12단어의 마스터 시드가 생성됩니다. BIP39 표준의 마스터 시드를 가지고 있으면 “마스터 시드 가져오기” 버튼을 눌러서 가져 올 수 도 있습니다. 베타 테스트 동안은 새로 생성한 시드를 사용하시기를 추천 합니다.

생성된 마스터 시드는 안전한곳에 반드시 보관하시기 바랍니다. 베타 테스트에 사용된 이 마스터 시드에서 생성된 주소로 SILC 토큰이 배분 되므로 절대 잃어 버리면 안됩니다.

“마스터 시드 백업 완료”를 누르면 첫번째 이더리움 계정이 생성되고 이더리움 스몰렛 앱이 다시 열립니다.

앱이 열리면 상단의 탭 바로 아래에 있는 “Main Network”를 눌러서 “Ropsten Test Network”로 바끕니다. 그 다음 “컨트랙트 탭을 누릅니다.

컨트랙트 탭으로 가면 기본으로 “SILC Test Contribution”이라는 컨트랙트가 선택되어 있습니다. 이 스마트 컨트랙트는 Ropsten Test Network에 존재하는 스마트 컨트랙트로 이곳에서 테스트용 SILC 토큰을 받게 됩니다. “SILC Test Contribution” 우측의 “전송” 버튼을 누릅니다.

 

그러면 위 화면과 같이 다시 이더리움 탭으로 돌아오면서 받을 주소에 컨트랙트 주소가 자동으로 입력 됩니다. 이제 이 SILC Test Contribution 스마트 컨트랙트로 이더를 전송해야 하는데 이더가 없습니다. 그러니 Faucet에 가서 이더를 받아와야 합니다. 화면 우측 상단의 수도꼭지를 누릅니다. 그림 과 같이 “1 ether 요청에 성공하였습니다” 메시지가 나오면 곧 1 이더가 현재 계정으로 입금 됩니다. 요청은 24시간에 한번씩만 가능합니다.

이더가 들어오면 수량에 0.1 이상을 쓰고 “사인 & 전송” 버튼을 누릅니다.

 

“사인 & 전송” 버튼을 누르면 위 화면과 같이 키 볼트에서 사인을 하게 됩니다. “지불확인”을 누릅니다. 전송이 완료되면 아래쪽에 전송되었다는 메시지가 나옵니다. 메시지를 터치하면 etherscan.io에서 최종 전송 결과를 확인 할 수 있습니다.

전송이 잘 되었으면 “토큰” 탭으로 갑니다. 토큰 탭에서 “시가총액 순 500개 토큰 검색”을 누릅니다. 화면처럼 SILCTEST 토큰이 들어와 있으면 성공입니다. 이 테스트 토큰을 받으신 분들에게 베타테스트 마감시에 실제 SILC토큰을 드리게 됩니다.

스몰렛 월렛을 기반으로 하는 SILC 에코시스템에 대한 기여 행사도 테스트가 진행중입니다. 자세한 사항은 아래 링크를 참고 하세요.

SILC Contribution

 

이더리움 스몰렛 베타 오픈

베타테스터 신청은 아래 링크에서.

키 볼트 베타 테스터 신청

이더리움 스몰렛 베타 테스터 신청

토큰을 등록하고 전송 할 수 있게 되었으며 컨트랙트 함수도 실행이 가능하다. 이전 버전이 설치된 경우에는 마스터 시드를 백업하고 키볼트 및 이더리움 스몰렛 모두 삭제 후 재설치가 필요하다.

Android O service

안드로이드 앱을 테스트 하다보면 주로 낮은 버전의 기계가 문제가 많으므로 상위버전 OS 테스트는 잘 안하게 되는데 최신 버전인 안드로이드 O버전(API 26)에서 서비스관련 내용이 바뀌었다. 조금 바뀐것이 아니라 정책이 바뀌어서 예전 방식으로는 동작을 안했다.

다른 앱의 Service를 호출 할때 startService를 사용하는데 안드로이드 O이상에서는 이렇게 부르면 다른앱이 실행중이 아닌경우 서비스 호출을 실패한다. 안드로이드 O 문서에 보면 아래와 같은 내용이 나온다.

Android 8.0 이전에 포그라운드 서비스를 생성하는 일반적인 방법은 백그라운드 서비스를 생성한 후 이 서비스를 포그라운드로 승격시키는 것이었습니다. Android 8.0에서는 좀 복잡하며, 시스템은 백그라운드 앱이 백그라운드 서비스를 생성하는 것을 허용하지 않습니다. 이 때문에 Android 8.0에서는 새 서비스를 포그라운드에서 시작하는 새로운 메서드 Context.startForegroundService()를 소개합니다. 시스템이 서비스를 생성한 후, 앱은 5초 이내에 해당 서비스의 startForeground() 메서드를 호출하여 새 서비스의 알림을 사용자에게 표시해야 합니다. 앱이 이 시간 한도 내에 startForeground()를 호출하지 않으면 시스템이 서비스를 중단하고 이 앱을 ANR로 선언합니다.

복잡한 이야기인데 결론적으로 startForegroundService를 호출 하지 않으면 백그라운드 앱은 백그라운드 서비스를 생성하지 못한다는 것이다. 그러므로 백그라운드에 있더라도 서비스가 호출 되어야 한다면 startForegroundService를 사용해야 한다. 이 경우 위 설명에 있는 바와 같이 호출된 서비스는 startForground를 반드시 실행해야한다. startForground는 노티피케이션을 동반하므로 조용히 실행될 수는 없다. 이렇게 한 이유는 정확히 실행되는 서비스들을 사용자에게 보여주기 위함일 것이다.

안드로이드 P(API 28)에서는 이부분이 좀 더 강화 되어 startForegroundService를 사용하려면 별도 퍼미션까지 요구한다고 한다. 그렇지만 실제로 해보니 퍼미션 요구는 안하는데 좀 더 들여다 봐야 할 것 같다.

여담으로 안드로이드 P를 테스트 하기 위해서 에뮬레이터(Pixel XL)를 설치 했는데 에뮬레이터 상태에서도 정말 빠르다. 에뮬레이터에서 개발하는 분들에게는 이 버전을 추천한다.

 

Smallet Key Vault, Ethereum Smallet 0.3 release

이 버전은 내 손을 떠나는 첫번째 버전이다. 개발하면서는 버전코드를 한번도 안 올렸으니 버전코드 1번이다.

현재 나와 있는 가상화폐들의 종류가 매우 다양하여 모든 가상화폐를 한 지갑 앱에 담는 것은 무모하다. 특히 최근의 가상화폐들은 단순하게 화폐를 전송하고 받는 기능을 넘어 스마트컨트랙트나 기타 유사한 DApp을 사용할 수 있게 됨에 따라 지갑의 기능이 계속 부가될 수 밖에 없다. 그러므로 비트코인 종류의 단순 화폐기능을 가지고 있고 프로토콜이 유사한 것들을 합쳐서 비트코인류 지갑으로 만들고, 이더리움은 수많은 토큰들이 이미 존재하므로 이들도 같이 관리하고 DApp도 처리가 가능한 지갑을 별도로 만들었다. 모든 앱들의 아이콘에는 SILC아이콘을 포함시켜 한 식구 임을 쉽게 알 수 있도록 하였다.

향후 통합장부(ICMP)에서 이러한 지갑들의 입출금 상황을 통합관리 하게 될것이다.

기본적으로 모든 지갑은 Key Vault에 키를 저장한다. 즉 지갑앱들은 개인키를 보관하지 않으며 모든 키는 Key Vault 앱에서 관리한다.

 

Key Vault는 색상을 붉은 색으로 하였다. 키를 생성할때 월렛과 Key Vault화면을 오가게 되고, 전문을 사인할때도 키 볼트에서 하게 되므로 사용자가 확실히 어느 앱에 있는지를 확인하기 쉽게 하기 위해서 이다. 각 월렛들도 다른 색상의 Theme를 사용하여 구분이 쉽도록 하였다. 현재로서는 키 볼트는 BIP39 마스터 시드로 생성한 키만을 생성하거나 다른 곳에서 가져와서 사용할 수 있다. 개별 키의 Import를 지원할지 아직 결정하지 못했다. 개별키를 가져오게 될 경우 복잡도가 높아져서 사용자들이 관리하기 힘들어 질 것이다.

모든 코인은 12개 이상의 단어로 이루어진 Master Seed로 부터 생성된다. HD키(Hierarchical, Deterministic)를 지원하므로 이 Master Seed만 있으면 모든 지갑 주소는 그대로 복원된다. 물론 이걸 잃으면 모두 다 잃는다.

실크에코시스템 백서에 나와 있듯이 키 볼트를 지갑에서 분리한 이유는 보안때문이다. 기능이 점점 많이 지면서 코드가 복잡해지고 다양한 권한을 가질 수 밖에 없는 지갑에서 분리하여 단순한 코드를 유지하고 아무런 OS권한도 사용하지 않음으로서 원천적으로 해킹을 막는 것이다. 코드가 복잡해지면 해킹을 막기가 그만큼 어려워진다. 또한 키 볼트 부분은 완전한 오픈소스여야 하므로 더욱더 코드를 단순하고 읽기 쉽게 하여 누구든 보안에 위협이 되는 사항을 확인하고 볼 수 있도록 하므로 복잡한 지갑 코드와의 분리는 필수 적이다.

즉 앱 자체가 인터넷 접근권한이 없으므로 네크웍을 통한 해킹은 루팅된 상태가 아닌다음에는 불가능 하다고 봐야한다. 월렛과의 통신은 서비를 통해서 하는데 월렛과 키 볼트 사이에서만 호출이 가능하다. 이 또는 앱사인에 의한 방어 이므로 OS자체의 앱 사인을 해킹하지 못한다면 다른 앱이 이 통신에 끼어 들기는 어렵다.

마스터 시드와 프라이비트 키는 안드로이드 키 스토리지를 사용하여 보관되며 모든 소스를 본다해도 이를 복원 할 방법은 없다.

이제 부터는 모든 지갑들이 다 가진 기능들이다.

  

이더리움 지갑 화면이다. QR코드 읽기, 보여주기를 지원하고 30여가지 화폐 단위로 잔고를 보여준다. 배경 색상은 이더리움 색상을 기본으로 하였다.

  

메인넷 외에도 3가지 테스트넷을 제공한다. 초보자들은 돈 많이 드는 메인넷을 사용하기 전에 테스트넷을 이용하여 충분히 기능을 사용해 볼 수 있다. Ropsten을 추천한다. 테스트용 돈 받기가 쉽다. 설정에서 개발자 모드를 켜면 Ropsten Faucet 화면에 바로가서 테스트용 이더를 받을 수 있다.

화면을 보면 다른 지갑과 달리 사인과 전송을 분리하고 있다.

  

사인화면을 보면 붉은색이다. 즉 월렛이 아니라 키 볼트에서 사인을 한다. 프라이비트 키를 키 볼트만 가지고 있으니 당연하다. 사인이 되면 아래쪽에 사인된 전문이 보인다. 사인을 분리한 이유는 완전한 오프라인 사인을 가능하게 하기 위해서다. 즉 사인버튼을 누르기 전에 항공기 모드를 켜거나 하는 방법으로 완전히 네트웍을 차단하고 사인을 할 수 있다. 사인된 전문이 오면 네트웍을 켜고 전송 버튼을 누르면 된다. 계정 추가를 통해서 계정은 몇개든 추가 할 수 있으며 따로 운영이 된다.

구글플레이에 등록 했으니 곧 노출될 것이다.

스몰렛 키볼트

이더리움 스몰렛