[GoLang 에서 json 사용하기]


* struct 구조체 선언시 변수명의 첫글자는 반드시 대문자여야 합니다.

* omitempty 입력 시 앞 쉼표 사이에 빈칸은 넣지 않으며 (넣으면 단순 경고 표시 발생)

  설정하게 되면 json 객체를 생성할때 해당 필드에 값이 없을 경우에만 필드를 변환하지 않고 건너뜁니다.

* `json:"-"` 설정 시 해당 필드는 무조건 변환되지 않습니다.



[예제 소스]


package main

import (
    "encoding/json"
    "fmt"
)

// Data is data
type Data struct {
    Name string `json:"Name"`
    Age int `json:"Age"`
    Etc1 string `json:"Etc1,omitempty"`
    Etc2 string `json:"Etc2,omitempty"`
    Temp string `json:"-"`
}

func main() {

    var jobj = Data{Name: "aaa", Age: 19, Etc1: "bbb", Etc2: "", Temp: "1123123"}
    jstrbyte, _ := json.Marshal(jobj)
    fmt.Println("---- jobj")
    fmt.Println(jobj)
    fmt.Println()
    fmt.Println("---- jstrbyte")
    fmt.Println(jstrbyte)
    fmt.Println()
    fmt.Println("---- string(jstrbyte)")
    fmt.Println(string(jstrbyte))
    fmt.Println()

    var jobj2 Data
    err := json.Unmarshal(jstrbyte, &jobj2)
    if err != nil {
        fmt.Println(err.Error())
    }
    fmt.Println("---- jobj2")
    fmt.Println(jobj2)
    fmt.Println()
    fmt.Println("---- jobj2.Name, jobj2.Age, jobj2.Etc1, jobj2.Etc2")
    fmt.Println(jobj2.Name, jobj2.Age, jobj2.Etc1, jobj2.Etc2)
    fmt.Println()

}



[결과]


* "omitempty", "-" : 두 설정 결과


---- jobj
{aaa 19 bbb 1123123}

---- jstrbyte
[123 34 78 97 109 101 ...... 98 98 98 34 125]

---- string(jstrbyte)
{"Name":"aaa","Age":19,"Etc1":"bbb"}

---- jobj2
{aaa 19 bbb }

---- string(jstrbyte)
{"Name":"aaa","Age":19,"Etc1":"bbb"}

---- jobj2.Name, jobj2.Age, jobj2.Etc1, jobj2.Etc2
aaa 19 bbb


[express-ipfilter]

- winston daily log 와 같이 사용할 경우 error 라고 해서 uncaughtException 로그에 남지는 않는다.

- npm install express-ipfilter

- 다른 라우터보다 위에 위치해야 합니다.



var ipfilter = require('express-ipfilter').IpFilter;
var IpDeniedError = require('express-ipfilter').IpDeniedError;

// 차단, 허용할 특정 아이피 목록
var ips = ['192.168.0.10', '192.168.0.11'];

// 범위 사용 예시
// 192.168.0.10 ~ 192.168.0.20 안의 범위와 192.168.0.100 차단 or 허용, 
// var ips = [['192.168.0.10', '192.168.0.20'], '192.168.0.100'];

// ips 목록의 ip들만 허용
app.use(ipfilter(ips, {mode: 'allow'}));

// ips 목록의 ip들 차단
// app.use(ipfilter(ips));

app.use(function(err, req, res, _next) {
    //console.log('Error handler', err);
    res.send('Access Denied');                     // page view 'Access Denied'
    if(err instanceof IpDeniedError){
      res.status(401).end();
    }else{
      res.status(err.status || 500).end();
    }
    // res.render('error', {
    //   message: 'You shall not pass',
    //   error: err
    // });
});

..........

app.get('/', function(req, res){
    res.send('allowed IP');
});


'Programming > Node.js' 카테고리의 다른 글

[Node.js] winston Daily 로그 남기기  (0) 2018.05.21

[Node.js Daily 로그 남기기]


- 인터넷에서 검색해서 적용해 봤는데 모듈이 업데이트 되면서 약간 바뀌었는지 filename , datePattern 부분이 제대로 적용이 되지 않았음.

- 나머지 부분은 다른게 없고 filename , datePattern 두 부분만 바뀌었음.


var winston = require('winston'); // 로그 처리 모듈 var winstonDaily = require('winston-daily-rotate-file'); // 로그 일별 처리 모듈

// Date Format 선택
// moment 모듈 설치 필요
function timeStampFormat() {
    return moment().format('YYYY-MM-DD HH:mm:ss.SSS ZZ'); // '2018-01-01 12:12:12.500 +0900'
};

// 그냥 
const tsFormat = () => (new Date()).toLocaleTimeString();      // '2018-01-01'

// 로그 설정
var logger = new (winston.Logger)({
    transports: [
        new (winstonDaily)({                                              // 로그 파일 설정
                name: 'info-file',
                filename: './logs/app_%DATE%.log',                  // 파일 이름 (아래 설정한 날짜 형식이 %DATE% 위치에 들어간다)
                datePattern: 'YYYY-MM-DD',                           // 날짜 형식 (대문자여야 적용된다.)
                colorize: false,
                maxsize: 50000000,                                       // 로그 파일 하나의 용량 제한
                maxFiles: 1000,                                             // 로그 파일 개수 제한
                level: 'info', // info이상 파일 출력                      // 로그 레벨 지정
                showLevel: true,
                json: false,
                timestamp: timeStampFormat                          // 저장될 시간 형식
            }),
        new (winston.transports.Console)({                            // 콘솔 출력
                name: 'debug-console',
                colorize: true,
                level: 'debug', // debug이상 콘솔 출력
                showLevel: true,
                json: false,
                timestamp: timeStampFormat
        })     
    ],
    exceptionHandlers: [                                                  // uncaughtException 발생시 처리
        new (winstonDaily)({
                name: 'exception-file',
                filename: './logs/exception_%DATE%.log',
                datePattern: 'YYYY-MM-DD',
                colorize: false,
                maxsize: 50000000,
                maxFiles: 1000,
                level: 'error',
                showLevel: true,
                json: false,
                timestamp: timeStampFormat
        }),
        new (winston.transports.Console)({
                name: 'exception-console',
                colorize: true,
                level: 'debug',
                showLevel: true,
                json: false,
                timestamp: timeStampFormat
        })     
    ]
});


// 원하는 위치에 로그 삽입
...................
logger.info('Hello, World');
...................


* ./logs/ 위치에
app_2018-05-21.log
exception_2018-05-21.log

형식으로 로그 파일이 생성됨

출력 내용은 아래와 같은 형태.
2018-05-21 15:59:38.764 +0900 - info: Hello, World




'Programming > Node.js' 카테고리의 다른 글

[Node.js] express-ipfilter IP필터 모듈 사용하기  (2) 2018.05.23

[fabcar 예제 오류 발생]


* (2018.05.08) 새로 fabric-samples 프로젝트를 받아서 fabcar 예제를 진행할 경우 아래와 같은 오류가 발생합니다.


* startFabric.sh 실행 -> node enrollAdmin.js 실행 시 오류!


[user@localhost fabcar]$ node enrollAdmin.js module.js:549 throw err; ^ Error: Cannot find module './api.js' at Function.Module._resolveFilename (module.js:547:15) at Function.Module._load (module.js:474:25) at Module.require (module.js:596:17) at require (internal/module.js:11:18) at Object.<anonymous> (/home/user/go/src/github.com/hyperledger/fabric-samples/fabcar/node_modules/fabric-ca-client/lib/FabricCAClientImpl.js:19:11) at Module._compile (module.js:652:30) at Object.Module._extensions..js (module.js:663:10) at Module.load (module.js:565:32) at tryModuleLoad (module.js:505:12) at Function.Module._load (module.js:497:3)



[원인 파악 및 해결]


* 이유는 fabric-ca-client 의 FabricCAClientImpl.js 에서 api.js 를 사용하는데

  해당 위치 (./fabcar/node_modules/fabric-ca-client/lib/) 에 api.js 파일이 없습니다.


* fabric-ca-client 패키지를 확인해보니 최신버전이 1.1.0 -> 1.1.1 로 업데이트 되면서 내용이 약간씩 바뀌었으며 그로인해 필요한 파일들이 누락된듯 합니다.


* 따라서 저는 기존 1.1.0 버전 모듈로 다시 설치해서 문제를 해결했습니다.



<fabcar 폴더 안의 package.json 내용>

{ "name": "fabcar", "version": "1.0.0", "description": "Hyperledger Fabric Car Sample Application", "main": "fabcar.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { "fabric-ca-client": "~1.1.0", "fabric-client": "~1.1.0", "grpc": "^1.6.0" }, "author": "Anthony O'Dowd", "license": "Apache-2.0", "keywords": [ "Hyperledger", "Fabric", "Car", "Sample", "Application" ] }


*fabcar 폴더 안에서 npm install --unsafe-perm 을 통해 package.json 에 입력된 모듈들을 자동으로 설치하게 됩니다.

* dependencies 항목에 fabric-ca-client 버전의 경우 틸드형식으로 지정되어 표시된 버전 마지막 자리의 최신버전으로 설치되게 됩니다.
(즉 현재 저상태로 실행하면 fabric-ca-client 버전은 1.1.1 이 설치됩니다.)

* 틸드형식을 제거하고 고정 버전을 설치하면 정상적으로 fabcar 예제를 테스트 하실 수 있습니다.
(node_modules 폴더를 삭제한 후 진행)

"name": "fabcar", "version": "1.0.0", "description": "Hyperledger Fabric Car Sample Application", "main": "fabcar.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { "fabric-ca-client": "1.1.0", "fabric-client": "~1.1.0", "grpc": "^1.6.0" }, "author": "Anthony O'Dowd", "license": "Apache-2.0", "keywords": [ "Hyperledger", "Fabric", "Car", "Sample", "Application" ] }


[user@localhost fabcar]$ npm install --unsafe-perm ....... [user@localhost fabcar]$ node enrollAdmin.js

* 추후에 fabric-ca-client 모듈이 안정화 되면 신경쓰지 않으셔도 될 듯 합니다.


* 기존 모듈에서 api.js 파일을 복사해 와도 가능할 것으로 보이지만 그 외 어떤 다른파일이 누락되어 있을지 알 수 없어서

  이전버전을 설치하는 방향으로 진행했습니다.



--------------------------------------------------------------

(English)


['fabcar' example error]


* (2018.05.08) If you take a new fabric-samples project and proceed with the fabcar example, the following error occurs.


* Run 'startFabric.sh' -> error when running 'node enrollAdmin.js'


[user@localhost fabcar]$ node enrollAdmin.js module.js:549 throw err; ^ Error: Cannot find module './api.js' at Function.Module._resolveFilename (module.js:547:15) at Function.Module._load (module.js:474:25) at Module.require (module.js:596:17) at require (internal/module.js:11:18) at Object.<anonymous> (/home/user/go/src/github.com/hyperledger/fabric-samples/fabcar/node_modules/fabric-ca-client/lib/FabricCAClientImpl.js:19:11) at Module._compile (module.js:652:30) at Object.Module._extensions..js (module.js:663:10) at Module.load (module.js:565:32) at tryModuleLoad (module.js:505:12) at Function.Module._load (module.js:497:3)


[Cause & Solution]


* There is no api.js file in that location (./fabcar/node_modules/fabric-ca-client/lib/).


* Checking the fabric-ca-client package shows that the latest version has been updated with 1.1.0 -> 1.1.1, and the contents have been slightly changed, so that the necessary files are missing.


* So I reinstalled it with the existing 1.1.0 version module and solved the problem.


<'package.json' contents in fabcar folder>

{ "name": "fabcar", "version": "1.0.0", "description": "Hyperledger Fabric Car Sample Application", "main": "fabcar.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { "fabric-ca-client": "~1.1.0", "fabric-client": "~1.1.0", "grpc": "^1.6.0" }, "author": "Anthony O'Dowd", "license": "Apache-2.0", "keywords": [ "Hyperledger", "Fabric", "Car", "Sample", "Application" ] }


* 'npm install --unsafe-perm' inside the 'fabcar' folder will automatically install the modules in package.json. * Dependencies item will be installed with the latest version of fabric-ca-client(1.1.1). (by tiled version range : ~1.1.0)
* If you remove the tilde format and install the fixed version, you can test the fabcar example normally.    (proceed after deleting the node_modules folder)

{ "name": "fabcar", "version": "1.0.0", "description": "Hyperledger Fabric Car Sample Application", "main": "fabcar.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { "fabric-ca-client": "1.1.0", "fabric-client": "~1.1.0", "grpc": "^1.6.0" }, "author": "Anthony O'Dowd", "license": "Apache-2.0", "keywords": [ "Hyperledger", "Fabric", "Car", "Sample", "Application" ] }


[user@localhost fabcar]$ npm install --unsafe-perm ....... [user@localhost fabcar]$ node enrollAdmin.js

* If the 'fabric-ca-client' module stabilizes later, you do not need to worry about it.


* It seems possible to copy the 'api.js' file from the existing module(1.1.0), but I could not figure out what other files were missing, so i proceeded to install the previous version.


[SourceTree 에서 GitLab 연결하기]


1. Clone




2. GitLab 프로젝트의 URL 복사


* 프로젝트 페이지에서 SSH -> HTTPS 로 바꾸고 URL을 복사한다.




* 복사한 URL 을 소스경로 위치에 붙여넣고 다른 위치(목적지 경로나 이름에 해당하는 칸)를 클릭하면 자동으로 연결시도를 한다.





3. GitLab 프로젝트 아이디로 로그인





4. 해당 프로젝트 파일을 Clone 해놓을 Local 위치를 지정합니다.


* 복사해서 새로 만드는 것이므로 만들려는 폴더 이름이 기존에 존재하면 안됩니다.


* 브랜치는 그대로 두셔도 무방합니다.





5. Clone 완료


* 이후 작업을 시작합니다.






* 이후 깃 사용방법은 따로 정리할....지도...

'Programming > GIT' 카테고리의 다른 글

Git 사용법 정리  (0) 2018.10.15

[출처]

http://cyberx.tistory.com/70

http://www.bloter.net/archives/209318

https://olis.or.kr/license/introduction.do


1. GPL ( General Public License )

자유소프트웨어재단에서 만든 라이선스로 GNU 프로젝트로 배포하는 소프트웨어에 적용하기 위하여 리처드스톨만이 만들었습니다. 오픈 소스들 중에서 많이 알려져 있고 의무사항들도 다른 오픈 소스 라이선스에 비해 엄격한 편입니다. GPL프로그램은 어떤 목적으로, 어떤 형태로든 사용할 수 있지만 사용하거나 변경된 프로그램을 배포하는 경우 무조건 동일한 라이선스로 공개해야 하며. ”본 제품(SW)은 GPL 라이선스 하에 배포되는 SW인 ○○○ (사용한 GPL SW 이름)를 포함합니다”와 같은 문구를 매뉴얼 혹은 그에 준하는 매체에 포함시키고, GPL 전문을 첨부해야 합니다.

2. AGPL ( Affero General Public License )

GPL을 기반을 만든 라이선스로 버전 1, 2는 Affero, 버전 3은 자유소프트웨어재단에 의해 개발됐습니다. 이 라이선스는 수정한 소스코드를 서버에서만 사용하는 개발자가 그 프로그램을 배포하지 않을 경우 사용자는 소스코드를 가질 수가 없는 문제를 해결하기 위해 마련됐습니다. 서버에서 프로그램을 실행해 다른 사용자들과 통신하면, 실행되고 있는 프로그램의 소스코드를 사용자들이 다운로드 할 수 있게 해야 한다는 조항을 담고 있습니다.

3. LGPL ( Lesser General Public License )

LGPL은 자유소프트웨어재단이 일부 라이브러리(Library)에 대하여 GPL보다 소스코드의 공개 정도를 다소 완화된 형태로 사용할 수 있도록 만든 라이선스입니다. 상용 라이브러리와 동일한 기능을 제공하는 오픈 소스 라이브러리에 GPL과 같은 엄격한 라이선스를 적용하면 소스코드를 공개해야 하기 때문에 개발자들이 사용을 꺼려할 것이기 때문에 이를 막고 오픈 소스의 사용을 장려하기 위해 만들어 졌습니다. LGPL이 적용된 라이브러리는 원 프로그램의 소스코드를 공개하지 않고 이에 사용된 오픈 소스의 소스코드만 공개하면 됩니다. 원래는 한정된 라이브러리에만 적용하려는 의도로 Library GPL이라는 이름을 붙였으나, 모든 라이브러리에 적용된다는 오해를 사 Lesser GPL로 2.1버전에서 변경되었습니다.

4. BSD ( Berkeley Software Distribution )

BSD는 버클리의 캘리포니아 대학에서 배포하는 공개 SW라이선스로 SW의 소스코드를 공개하지 않아도 되는 대표적인 오픈 소스 SW의 라이선스 중 하나입니다. 이렇게 BSD의 라이선스의 허영범위가 넓은 이유는 BSD라이선스로 배포되는 프로젝트가 미국 정부에서 제공한 재원으로 운영되었기 때문입니다. 즉, SW에 대한 대가를 미국 국민의 세금으로 미리 지불했기 때문에 사람들에게 그들이 원하는 방식으로 SW를 사용하거나 만들도록 허가된 것입니다. 따라서 BSD라이선스의 소스코드를 이용하여 새로운 프로그램을 개발하여도 새로운 프로그램의 소스코드를 공개하지 않고 BSD가 아닌 다른 라이선스를 적용하여 판매할 수 있습니다.

5. MPL ( Mozilla Public License )

MPL은 Netscape브라우저의 소스코드를 공개하기 위해 개발된 라이선스로 공개하여야 할 소스코드의 범위를 좀 더 명확하게 정의하고 있습니다. 즉 GPL에서는 링크되는 SW의 소스코드를 포함하여 공개하여야 할 소스코드의 범위가 모호하게 정의되어 있지만 MPL에서는 링크 등의 여부에 상관없이 원래의 소스코드가 아닌 새로운 파일에 작성된 소스코드에 대해서는 공개의 의무가 발생하지 않습니다. 따라서 MPL SW 그 자체는 어떻게 하든 공개를 해야 하지만 원래 소스코드에 없던 새로운 파일들은 공개할 의무가 발생하지 않습니다.

6. Apache

Apache License는 아파치 웹 서버를 포함한 아파치 재단(Apache Software Foundation)의 모든 SW에 적용되는 라이선스로 BSD라이선스와 비슷하여 소스코드 공개 등의 의무가 발생하지 않습니다. 다만 "Apache"라는 이름에 대한 상표권을 침해하지 않아야 한다라는 조항이 명시적으로 들어가 있고, 특허권에 대한 내용이 포함되어 있습니다. 아파치 라이선스 소스코드를 수정해 배포하는 경우 아파치 라이선스 버전 2.0을 꼭 포함시켜야 하며 아파치 재단에서 만든 소프트웨어임을 밝혀야 합니다.

7. MIT

MIT는 미국 Massachusetts Institute of Technology에서 해당 대학 SW 공학도들을 돕기 위해 개발한 라이선스 입니다. 라이선스와 저작권 관련 명시만 지켜주면 되는 라이선스로, BSD라이선스를 기초로 작성되었으며 소스코드를 수정하여 배포 시에도 반드시 오픈 소스로 배포해야 한다는 규정이 없어 GPL등의 엄격함을 피하려는 사용자들에게 인기가 많습니다.

8. 기타

WTFPL (Do What The Fuck You Want To Public License) 당신이 하고 싶은 대로 마음 것 하라는 라이선스

Beerware 마음대로 사용하고 SW가 마음에 들었다면 언젠가 만났을 때 맥주나 한잔 사달라는 라이센스


  1. GPL
  • 수정한 소스코드 혹은 GPL소스코드를 활용한 소프트웨어 모두 GPL로 공개
  • 라이선스 및 저작권 명시
  • 변경사항 안내
  1. AGPL
  • 수정한 소스코드 혹은 AGPL소스코드를 활용한 소프트웨어 모두 AGPL로 공개
  • 라이선스 및 저작권 명시
  • 변경사항 안내
  • 네트워크상 소프트웨어 사용자에게 소스코드 공개
  1. LGPL
  • 수정한 소스코드 LGPL로 공개 ( 단순 활용시 공개 의무 없음 )
  • 라이선스 및 저작권 명시
  1. BSD
  • 라이선스 및 저작권 명시
  1. MPL
  • 수정한 소스코드 MPL로 공개( 단순 활용시 공개 의무 없음)
  • 라이선스 및 저작권 명시
  • 특허기술이 구현된 프로그램의 경우 관련 사실을 'LEGAL'파일에 기록하여 배포
  • 상표권 침해 금지
  1. Apache
  • 라이선스 및 저작권 명시
  • 변경사항 안내
  • 상표권 침해 금지
  1. MIT
  • 라이선스 및 저작권 명시





 라이선스

특이 사항 

 GPL

  • 수정한 소스코드 혹은 GPL소스코드를 활용한 소프트웨어 모두 GPL로 공개
  • 라이선스 및 저작권 명시
  • 변경사항 안내 

 AGPL

  • 수정한 소스코드 혹은 AGPL소스코드를 활용한 소프트웨어 모두 AGPL로 공개
  • 라이선스 및 저작권 명시
  • 변경사항 안내
  • 네트워크상 소프트웨어 사용자에게 소스코드 공개 

 LGPL

  • 수정한 소스코드 LGPL로 공개 ( 단순 활용시 공개 의무 없음 )
  • 라이선스 및 저작권 명시

 BSD

  • 라이선스 및 저작권 명시

 MPL

  • 수정한 소스코드 MPL로 공개( 단순 활용시 공개 의무 없음)
  • 라이선스 및 저작권 명시
  • 특허기술이 구현된 프로그램의 경우 관련 사실을 'LEGAL'파일에 기록하여 배포
  • 상표권 침해 금지

 Apache

  • 라이선스 및 저작권 명시
  • 변경사항 안내
  • 상표권 침해 금지

 MIT

  •  라이선스 및 저작권 명시




[주의사항]

* 도커는 기본적으로 root 권한이 필요합니다. 사용자 계정으로 sudo 없이 사용하려면 해당 사용자를 docker 그룹에 추가해야 합니다.

* 설치도중 또는 설치 후 fabric 샘플 소스를 실행할 때 root 권한이 맞는지 잘 확인해주세요.

* 특정 사용자 계정으로 진행할 경우 아래 모든 명령어들은 사용자 계정 및 root 계정 모두 지정된 버전으로 실행되어야 합니다.


[특정 사용자를 docker 그룹에 추가 (추천)]

sudo usermod -aG docker 사용자계정


[CentOS 7 - 환경 구축]

# 2018.04.24 # DNS 8.8.8.8 # KT DNS 주소로 진행했더니 # 도커 이미지를 제대로 못받는 경우가 발생함 (정확하지는 않음) ######################################
# 선행 조건 - fabric 공식 문서(Prerequisite 항목)에서 확인 # 각 오픈소스별 버전 매우 중요 # Python(2.7 버전만, 3.x는 안 됨) # Docker(17.06-ce 이상, Ubuntu (docker.io 설치 시) 는 1.13 이상) # Docker compose(1.14 이상) # Go(1.9 이상) # Node.js(8.9 이상 9.0 미만 - 8.11 추천) # NPM(5.6.0 이상) # repository 및 epel 업데이트 sudo yum -y update sudo yum -y install epel-release # 설치가 안되어 있다면 설치할 것. # curl, git, wget, python2.7 #sudo yum -y install curl git sudo yum -y install wget # docker (17.06-ce 이상) 설치 sudo yum -y install yum-utils device-mapper-persistent-data lvm2 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum makecache fast sudo yum -y install docker-ce # docker-compose (1.14 이상) 설치 sudo yum -y install python-pip sudo pip install docker-compose # docker-compose 설치 다른방법 (root 로그인 후 실행) curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose # docker 서버 실행 및 자동실행 설정 추가 systemctl start docker systemctl enable docker # n (최신), nodejs (8.9 이상 9.0 미만 - 8.11 추천), npm (5.6.0 이상) 설치 sudo yum -y install npm nodejs sudo npm install -g n sudo n 8.11.1 sudo ln -sf /usr/local/n/versions/node/8.11.1/bin/node /usr/bin/node sudo npm install -g npm sudo npm install --global grpc --unsafe # go 1.95 버전 다운로드 cd ~ wget https://dl.google.com/go/go1.9.5.linux-amd64.tar.gz sudo tar -zxvf go1.9.5.linux-amd64.tar.gz -C /usr/local/ (이후 아래 환경변수 설정 후에 go 명령어 사용 가능합니다.) ###################################################


[도커 이미지 다운로드]

# HyperLedger Fabric 도커 이미지 및 바이너리 다운로드 cd ~ mkdir -p go/src/github.com/hyperledger cd go/src/github.com/hyperledger sudo curl -sSL https://goo.gl/6wtTN5 | sudo bash -s 1.1.0 (* docker 그룹에 사용자계정을 추가했을 경우 sudo 를 안써도 된다.) curl -sSL https://goo.gl/6wtTN5 | bash -s 1.1.0


* 도커 필수 이미지를 받는 스크립트의 경우 사용자 계정을 docker 그룹에 추가하지 않으면

  sudo 를 통해 실행해야 docker 명령어가 정상적으로 수행됩니다. 그러나 sudo 를 사용하면 다운받는 fabric-samples 폴더 소유자가 root 가 되어

  소유 및 권한을 다시 사용자계정으로 변경해 주거나 이후 샘플 폴더 안에서 실행할 작업들을 모두 sudo 로 진행해야 합니다.


* 사용자 계정을 docker 그룹에 추가 (sudo usermod -aG docker 사용자계정) 한 후 위 스크립트를 진행한다면 sudo 명령어를 빼고 실행해도 되며

  (curl -sSL https://goo.gl/6wtTN5 | bash -s 1.1.0) 이럴 경우 fabric-sample 폴더는 사용자계정 소유로 진행되고 추후 작업들도 sudo 없이 진행 가능합니다.


[환경변수 설정]

# go 환경변수 sudo vi /etc/profile # 프로필 맨 아래 추가 # GOPATH 는 golang 의 workspace 와 비슷하므로 원하는 곳으로 설정해도 괜찮습니다. export GOPATH=/home/사용자계정/go export PATH=/usr/local/go/bin:$PATH # 나중에 소스코드 실행 시 또는 Chaincode 수정시 peer, configtxgen, cryptogen 등 관련 명령어를 못찾는 오류가 생길 경우 export PATH=$HOME/go/src/github.com/hyperledger/fabric-samples/bin:$PATH source /etc/profile


# fabcar 예제 cd fabcar sudo npm install --unsafe-perm sudo ./startFabric.sh


[결과]
1. startFabric.sh 실행

[user@localhost fabcar]$ sudo ./startFabric.sh # don't rewrite paths for Windows Git Bash users export MSYS_NO_PATHCONV=1 docker-compose -f docker-compose.yml down Removing cli ... done Removing peer0.org1.example.com ... done Removing orderer.example.com ... done Removing ca.example.com ... done Removing couchdb ... done Removing network net_basic docker-compose -f docker-compose.yml up -d ca.example.com orderer.example.com peer0.org1.example.com couchdb Creating network "net_basic" with the default driver Creating orderer.example.com ... done Creating couchdb ... done Creating ca.example.com ... done Creating peer0.org1.example.com ... done # wait for Hyperledger Fabric to start # incase of errors when running later commands, issue export FABRIC_START_TIMEOUT=<larger number> export FABRIC_START_TIMEOUT=10 #echo ${FABRIC_START_TIMEOUT} sleep ${FABRIC_START_TIMEOUT} # Create the channel docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/users/Admin@org1.example.com/msp" peer0.org1.example.com peer channel create -o orderer.example.com:7050 -c mychannel -f /etc/hyperledger/configtx/channel.tx 2018-04-24 08:02:04.449 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized 2018-04-24 08:02:04.482 UTC [channelCmd] InitCmdFactory -> INFO 002 Endorser and orderer connections initialized 2018-04-24 08:02:04.685 UTC [main] main -> INFO 003 Exiting..... # Join peer0.org1.example.com to the channel. docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/users/Admin@org1.example.com/msp" peer0.org1.example.com peer channel join -b mychannel.block 2018-04-24 08:02:04.862 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized 2018-04-24 08:02:04.962 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel 2018-04-24 08:02:04.962 UTC [main] main -> INFO 003 Exiting..... Creating cli ... done 2018-04-24 08:02:05.666 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP 2018-04-24 08:02:05.666 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity 2018-04-24 08:02:05.666 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc 2018-04-24 08:02:05.666 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc 2018-04-24 08:02:05.666 UTC [chaincodeCmd] getChaincodeSpec -> DEBU 005 java chaincode disabled 2018-04-24 08:02:05.693 UTC [golang-platform] getCodeFromFS -> DEBU 006 getCodeFromFS github.com/fabcar/go 2018-04-24 08:02:05.783 UTC [golang-platform] func1 -> DEBU 007 Discarding GOROOT package bytes 2018-04-24 08:02:05.783 UTC [golang-platform] func1 -> DEBU 008 Discarding GOROOT package encoding/json 2018-04-24 08:02:05.783 UTC [golang-platform] func1 -> DEBU 009 Discarding GOROOT package fmt 2018-04-24 08:02:05.783 UTC [golang-platform] func1 -> DEBU 00a Discarding provided package github.com/hyperledger/fabric/core/chaincode/shim 2018-04-24 08:02:05.783 UTC [golang-platform] func1 -> DEBU 00b Discarding provided package github.com/hyperledger/fabric/protos/peer 2018-04-24 08:02:05.783 UTC [golang-platform] func1 -> DEBU 00c Discarding GOROOT package strconv 2018-04-24 08:02:05.783 UTC [golang-platform] GetDeploymentPayload -> DEBU 00d done 2018-04-24 08:02:05.783 UTC [container] WriteFileToPackage -> DEBU 00e Writing file to tarball: src/github.com/fabcar/go/fabcar.go 2018-04-24 08:02:05.787 UTC [msp/identity] Sign -> DEBU 00f Sign: plaintext: --- 2018-04-24 08:02:05.787 UTC [msp/identity] Sign -> DEBU 010 Sign: digest: --- 2018-04-24 08:02:05.817 UTC [chaincodeCmd] install -> DEBU 011 Installed remotely response:<status:200 payload:"OK" > 2018-04-24 08:02:05.817 UTC [main] main -> INFO 012 Exiting..... 2018-04-24 08:02:05.983 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP 2018-04-24 08:02:05.983 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity 2018-04-24 08:02:05.984 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc 2018-04-24 08:02:05.984 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc 2018-04-24 08:02:06.018 UTC [chaincodeCmd] getChaincodeSpec -> DEBU 005 java chaincode disabled 2018-04-24 08:02:06.019 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: --- 2018-04-24 08:02:06.019 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: --- 2018-04-24 08:02:06.293 UTC [msp/identity] Sign -> DEBU 008 Sign: plaintext: --- 2018-04-24 08:02:06.293 UTC [msp/identity] Sign -> DEBU 009 Sign: digest: --- 2018-04-24 08:02:06.294 UTC [main] main -> INFO 00a Exiting..... 2018-04-24 08:02:16.467 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP 2018-04-24 08:02:16.467 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity 2018-04-24 08:02:16.468 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc 2018-04-24 08:02:16.468 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc 2018-04-24 08:02:16.468 UTC [chaincodeCmd] getChaincodeSpec -> DEBU 005 java chaincode disabled 2018-04-24 08:02:16.469 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: --- 2018-04-24 08:02:16.469 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: --- 2018-04-24 08:02:16.476 UTC [msp/identity] Sign -> DEBU 008 Sign: plaintext: --- 2018-04-24 08:02:16.476 UTC [msp/identity] Sign -> DEBU 009 Sign: digest: --- 2018-04-24 08:02:16.477 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> DEBU 00a ESCC invoke result: version:1 response:<status:200 message:"OK" > payload:"\n L\373h\037A><&3\371c0\261\243d\245\3207\240\254\225 \201\201.\240vDH?\205\260\022\267\006\n\240\006\022\205\006\n\006fabcar\022\372\005\032J\n\004CAR0\032B{\"make\":\"Toyota\",\"model\":\"Prius\",\"colour\":\"blue\",\"owner\":\"Tomoko\"}\032G\n\004CAR1\032?{\"make\":\"Ford\",\"model\":\"Mustang\",\"colour\":\"red\",\"owner\":\"Brad\"}\032N\n\004CAR2\032F{\"make\":\"Hyundai\",\"model\":\"Tucson\",\"colour\":\"green\",\"owner\":\"Jin Soo\"}\032N\n\004CAR3\032F{\"make\":\"Volkswagen\",\"model\":\"Passat\",\"colour\":\"yellow\",\"owner\":\"Max\"}\032G\n\004CAR4\032?{\"make\":\"Tesla\",\"model\":\"S\",\"colour\":\"black\",\"owner\":\"Adriana\"}\032K\n\004CAR5\032C{\"make\":\"Peugeot\",\"model\":\"205\",\"colour\":\"purple\",\"owner\":\"Michel\"}\032H\n\004CAR6\032@{\"make\":\"Chery\",\"model\":\"S22L\",\"colour\":\"white\",\"owner\":\"Aarav\"}\032H\n\004CAR7\032@{\"make\":\"Fiat\",\"model\":\"Punto\",\"colour\":\"violet\",\"owner\":\"Pari\"}\032J\n\004CAR8\032B{\"make\":\"Tata\",\"model\":\"Nano\",\"colour\":\"indigo\",\"owner\":\"Valeria\"}\032M\n\004CAR9\032E{\"make\":\"Holden\",\"model\":\"Barina\",\"colour\":\"brown\",\"owner\":\"Shotaro\"}\022\026\n\004lscc\022\016\n\014\n\006fabcar\022\002\010\001\032\003\010\310\001\"\r\022\006fabcar\032\0031.0" endorsement:<endorser:"\-----BEGIN CERTIFICATE-----\---\n-----END CERTIFICATE-----\n" signature:"---" > 2018-04-24 08:02:16.478 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 00b Chaincode invoke successful. result: status:200 2018-04-24 08:02:16.478 UTC [main] main -> INFO 00c Exiting..... Total setup execution time : 25 secs ... Start by installing required packages run 'npm install' Then run 'node enrollAdmin.js', then 'node registerUser' The 'node invoke.js' will fail until it has been updated with valid arguments The 'node query.js' may be run at anytime once the user has been registered [user@localhost fabcar]$


2. enrollAdmin.js 실행

- admin 등록

[user@localhost fabcar]$ sudo node enrollAdmin.js Store path:$HOME/go/src/github.com/hyperledger/fabric-samples/fabcar/hfc-key-store Successfully enrolled admin user "admin" Assigned the admin user to the fabric client ::{"name":"admin","mspid":"Org1MSP","roles":null,"affiliation":"","enrollmentSecret":"","enrollment":{"signingIdentity":"*******************","identity":{"certificate":"-----BEGIN CERTIFICATE-----\n********************\n-----END CERTIFICATE-----\n"}}} [user@localhost fabcar]$ 


3. registerUser.js 실행

- 일반 유저 등록

[user@localhost fabcar]$ sudo node registerUser.js Store path:$HOME/go/src/github.com/hyperledger/fabric-samples/fabcar/hfc-key-store Successfully loaded admin from persistence Successfully registered user1 - secret:****** Successfully enrolled member user "user1" User1 was successfully registered and enrolled and is ready to intreact with the fabric network [user@localhost fabcar]$ 



4. query.js 실행

- 자동차 데이터 확인

[user@localhost fabcar]$ sudo node query.js Store path:$HOME/go/src/github.com/hyperledger/fabric-samples/fabcar/hfc-key-store Successfully loaded user1 from persistence Query has completed, checking results Response is [{"Key":"CAR0", "Record":{"colour":"blue","make":"Toyota","model":"Prius","owner":"Tomoko"}},{"Key":"CAR1", "Record":{"colour":"red","make":"Ford","model":"Mustang","owner":"Brad"}},{"Key":"CAR2", "Record":{"colour":"green","make":"Hyundai","model":"Tucson","owner":"Jin Soo"}},{"Key":"CAR3", "Record":{"colour":"yellow","make":"Volkswagen","model":"Passat","owner":"Max"}},{"Key":"CAR4", "Record":{"colour":"black","make":"Tesla","model":"S","owner":"Adriana"}},{"Key":"CAR5", "Record":{"colour":"purple","make":"Peugeot","model":"205","owner":"Michel"}},{"Key":"CAR6", "Record":{"colour":"white","make":"Chery","model":"S22L","owner":"Aarav"}},{"Key":"CAR7", "Record":{"colour":"violet","make":"Fiat","model":"Punto","owner":"Pari"}},{"Key":"CAR8", "Record":{"colour":"indigo","make":"Tata","model":"Nano","owner":"Valeria"}},{"Key":"CAR9", "Record":{"colour":"brown","make":"Holden","model":"Barina","owner":"Shotaro"}}] [user@localhost fabcar]$ 


* 특정 문자열은 임의로 가렸습니다.


[참고]

- HyperLedger Fabric

http://hyperledger-fabric.readthedocs.io/en/release-1.1/

https://github.com/hyperledger/fabric-samples


---




+ Recent posts