ㅐ
바이트 수준의 프로토콜 버퍼 데이터 구조 해석
CentOS 하이퍼레저 패브릭 예제 설치
2
$ sudo usermod -aG docker xeraph
# yum -y install yum-utils
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# yum -y install docker-ce
# yum -y install python-pip
# pip install docker-compose
# yum update openssl
# curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
# yum -y install nodejs golang gcc-c++
# curl -sSL http://bit.ly/2ysbOFE | bash -s 1.2.0
fabcar 예제 구동
3
fabcar 도커 네트워크 구성
4
dev-peer0.org1.example.com-fabcar-1.0
cli hyperledger/fabric-tools
peer0.org1.example.com hyperledger/fabric-peer
ca.example.com hyperledger/fabric-ca
orderer.example.com hyperledger/fabric-orderer
couchdb hyperledger/fabric-couchdb
chaincode 실행
7051/tcp, 7053/tcp
7054/tcp
7050/tcp
4369/tcp, 9100/tcp, 5984/tcp
fabric 쉘
peer0 도커 컨테이너 디렉터리 구조
5
/var/hyperledger/production/
chaincodes/
fabcar.1.0/
ledgersData/
000001.log, CURRENT, LOCK, LOG, MANIFEST-000000
bookkeeper/
chains/
chains/
mychannel/
blockfile_000000
index/
000001.log, CURRENT, LOCK, LOG, MANIFEST-000000
configHistory/
historyLeveldb/
ledgerProvider/
pvtdataStore/
000001.log, CURRENT, LOCK, LOG, MANIFEST-000000
000001.log, CURRENT, LOCK, LOG, MANIFEST-000000
000001.log, CURRENT, LOCK, LOG, MANIFEST-000000
000001.log, CURRENT, LOCK, LOG, MANIFEST-000000
오늘의 주제
leveldb 파일
leveldb 파일
leveldb 파일
leveldb 파일
leveldb 파일
leveldb 파일
간단한 바이너리 파일 탐색
6
$ strings blockfile_000000
본격적으로 파일 분석을 시작하기 전에 Fabric SDK를
통해 조회했던 문자열 조각들이 존재함을 확인
하이퍼레저 패브릭 소스 다운로드
7
https://github.com/hyperledger/fabric
fabric-release-1.2.zip 18MB (압축 해제시 42MB)
전체 블록 구조
8
blockfile_mgr.go
func (mgr *blockfileMgr) addBlock(block *common.Block) error {
...
blockBytesLen := len(blockBytes)
blockBytesEncodedLen := proto.EncodeVarint(uint64(blockBytesLen))
totalBytesToAppend := blockBytesLen + len(blockBytesEncodedLen)
...
//append blockBytesEncodedLen to the file
err = mgr.currentFileWriter.append(blockBytesEncodedLen, false)
if err == nil {
//append the actual block bytes to the file
err = mgr.currentFileWriter.append(blockBytes, true)
}
• 블록 길이를 먼저 쓰고 블록 데이터를 쓰는 코드를 보면 가변 블록 구조임을 파악할 수 있음
• EncodeVarint 는 프로토콜 버퍼의 정수 인코딩이므로, 단지 gRPC 뿐 아니라 블록 파일에서도 프로토콜 버퍼를 광범위하게 사용할 것이라는
사실을 이 시점에서 추정 가능
프로토콜 버퍼 인코딩
9
https://developers.google.com/protocol-buffers/docs/encoding
메모리의 정수 표현 디스크, 네트워크 입출력 시 정수 표현
int16
int32
int64
1 2
1 2 3 4
1 2 3 4 5 6 7 8
varint 0000 00011 =
300 = 1010 1100 0000 0010
10 0101100(2) = 300(10)
• 메모리에서는 일반적으로 고정 길이 공간을 사용하여 수치형을 표현합니다.
• 디스크, 네트워크 전송 시에는 I/O 대역폭 및 저장 공간 점유를 최소화하기 위해 가변 길이 인코딩을 일반적으로 사용합니다.
• VarInt (Variable-length Integer) 는 고전적인 가변 길이 인코딩 방식으로, 가장 앞 비트 (MSB)를 뒷 바이트가 이어진다는 신호로 사용하고
7비트를 이어 붙여서 전체 데이터를 표현합니다.
• 패브릭 프로토콜 버퍼는 Little Endian 기준이라 7비트 그룹을 역순으로 조립해야 합니다.
- 예를 들어 정수 300은 000 0010 010 1100 처럼 이어붙여서 해석합니다.
프로토콜 버퍼 인코딩
10
https://developers.google.com/protocol-buffers/docs/encoding
타입별 인코딩 방식
타입번호 의미 타입 매핑
0 VarInt int32, int64, uint64, sint32, sint64, bool, enum
1 64비트 fixed64, sfixed64, double
2 길이 지정 string, bytes, embedded message, packed repeated fields
3 그룹 시작 groups (폐기됨)
4 그룹 끝 groups (폐기됨)
5 32비트 fixed32, sfixed32, float
길이 지정 인코딩 예시 (문자열)
복합 메시지 예시
07 74 65 73 74 69 6e 67"testing"
7글자 t e s t i n g
message Test2 {
optional string b = 2;
}
07 74 65 73 74 69 6e 67
7글자 t e s t i n g
12
메타
00010 010
2번 필드 2번 타입
• 아쉽게도 message (complex type)와
bytes, string 의 타입 구분이 안 되어서
메타데이터 정의 없이 파싱하는 것은
원천적으로 불가능
• 필드 번호를 지정하므로 optional 구현
은 간단하고 효율적임.
1번 블록 구조
11
{
"header": {
"channel_header": {
"type": 1,
"channel_id": "mychannel",
"timestamp": "2018-08-20 01:12:48+0900"
}
"signature_header": {
"creator": {
"mspid": "OrdererMSP",
"id_bytes": "-----BEGIN CERTIFICATE-----
nMIICDDCCAbOgAwIBAgIRAK30hdRcBxQJYNPqPkiFo3IwCgYIKoZIzj0EAwIwaTELnMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGncmFuY2lzY
28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRcwFQYDVQQDEw5jYS5leGFtncGxlLmNvbTAeFw0xNzA4MzEwOTE0MzJaFw0yNzA4MjkwOTE0MzJaMFgxCzAJBgNVnBAYTAlVTMRMwEQ
YDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpnc2NvMRwwGgYDVQQDExNvcmRlcmVyLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYInKoZIzj0DAQcDQgAE
UOJGzpasxjS5EJmbFIe/GtOJJAo6mhJqLyYT9PBvVSdaQ/TQnlMNlqLEZgFP6wc9CtrUp/WDnZ/M2zLpoDPjkcqNNMEswDgYDVR0PAQH/BAQDAgeAnMAwGA1UdEwEB/wQCMAAwKwYD
VR0jBCQwIoAgoGBqSoYKHjHJCiN4jabztrdJJe0NnIwYa9ImUCbpGrmowCgYIKoZIzj0EAwIDRwAwRAIgHsU1f4jzuul6zYGY/Xn/H5X5ngDe7/u8dZxJfWwXOGNsCICbXt6yezSzacOFQDkvAP
z5/3OYI5YKLSTl+Wilfa/qyn-----END CERTIFICATE-----n"
},
"nonce": "ef86bebfe565f8aed0c60994bd480fd013bd77808f65a554"
},
},
"data": "..미 해석 영역.."
}
헤더 타입 ENUM 설명
0 MESSAGE 서명된 메시지이나 데이터 구조가 알려지지 않은 것
1 CONFIG 채널 설정 메시지
2 CONFIG_UPDATE 채널 설정 업데이트 트랜잭션
3 ENDORSER_TRANSACTION Endorser 기반 트랜잭션 제출 (SDK에서 사용)
4 ORDERER_TRANSACTION Orderer가 사용하는 관리용 메시지
5 DELIVER_SEEK_INFO Deliver API의 Envelope 메시지 탐색 제어용
6 CHAINCODE_PACKAGE 설치 시 체인코드 패키징에 사용
8 PEER_ADMIN_OPERATION Peer에서 수행되는 관리적 작업 호출
HeaderType 정의 (protos/common/common.proto)
체인코드 트랜잭션 수행 흐름 proposal.proto 참조
12
Client Endorser
Client Endorser
1
2
Client Orderer
3
이 proposal에 대한 action
전체 응답 페이로드에 대한 Endorser의 서명들
action을 요청한 proposal의 페이로드
action을 요청한 proposal의 헤더
헤더의 creator가 Transaction 에 대해 수행한 서명
전체 응답 페이로드에 대한 Endorser의 서명
이 proposal에 대한 action
이 proposal에 대한 action (생략 가능)
이 proposal의 페이로드
이 proposal의 헤더
헤더의 creator가 proposal 에 대해 수행한 서명
• 클라이언트는 1개 이상의 proposal을 모아서 하나의 트랜잭션 메
시지를 생성하고 이를 orderer에게 전송합니다.
• orderer는 여러 개의 트랜잭션을 배치 단위로 commiting peer에게
전달(deliver)합니다. committing peer는 검증 후 원장에 반영합니
다.
• 트랜잭션은 1개 이상의 action으로 구성되고, 각각 헤더, 제안
(proposal) 페이로드, 서명된 응답 페이로드 (response)를 포함합니
다.
• 응답은 성공/실패 코드, 응답 페이로드, 응답 페이로드에 대한
서명으로 구성됩니다.
• 응답 페이로드는 요청 (proposal)에 대한 해시를 포함합니다.
이는 특정 요청에 대한 응답을 안전하게 매핑할 목적입니다.
• proposal은 체인코드를 실행해달라는 요청입니다.
- 체인코드의 상태 변경 및 원장에 데이터 반영
• proposal은 헤더와 페이로드로 구성됩니다.
- 헤더: 타입, 실행요청자, 시각, 체인ID, Nonce
- 페이로드: 체인코드ID, 호출 매개변수
2번 블록 구조 - 헤더
13
{
"header": {
"channel_header": {
"type": 3,
"timestamp": "2018-08-20 01:12:51+0900",
"channel_id": "mychannel",
"tx_id": "bc395ae86abbc9b75aa41b998bf2d0f4cf4e78af2bd59c20a455965d498675c2",
"extension": "120612046c736363"
},
"signature_header": {
"creator": {
"mspid": "Org1MSP",
"id_bytes": "-----BEGIN CERTIFICATE-----
nMIICGDCCAb+gAwIBAgIQFSxnLAGsu04zrFkAEwzn6zAKBggqhkjOPQQDAjBzMQswnCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZynYW5
jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eunb3JnMS5leGFtcGxlLmNvbTAeFw0xNzA4MzEwOTE0MzJaFw0yNzA4MjkwOTE0MzJanMFsxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TnYW4gRnJhbmNpc2NvMR8wHQYDVQQDDBZBZG1pbkBvcmcxLmV4YW1wbGUuY29tMFkwnEwYHKoZIzj0C
AQYIKoZIzj0DAQcDQgAEV1dfmKxsFKWo7o6DNBIaIVebCCPAM9C/nsLBt4pJRre9pWE987DjXZoZ3glc4+DoPMtTmBRqbPVwYcUvpbYY8p6NNMEswDgYDnVR0PAQH/BAQDAgeAMAwG
A1UdEwEB/wQCMAAwKwYDVR0jBCQwIoAgQjmqDc122u64nugzacBhR0UUE0xqtGy3d26xqVzZeSXwwCgYIKoZIzj0EAwIDRwAwRAIgXMy26AEUn/GUMPfCMs/nQjQME1ZxBHAYZtKEu
RR361JsCIEg9BOZdIoioRivJC+ZUzvJUnkXuno2HkWiuxLsibGxtEn-----END CERTIFICATE-----n"
},
"nonce": "998d2b96865a56bda70c0e09a2acefa6e9cad8015ee17d6a"
}
},
"tx_actions": [ .... ]
}
헤더 타입 ENUM 설명
0 MESSAGE 서명된 메시지이나 데이터 구조가 알려지지 않은 것
1 CONFIG 채널 설정 메시지
2 CONFIG_UPDATE 채널 설정 업데이트 트랜잭션
3 ENDORSER_TRANSACTION Endorser 기반 트랜잭션 제출 (SDK에서 사용)
4 ORDERER_TRANSACTION Orderer가 사용하는 관리용 메시지
5 DELIVER_SEEK_INFO Deliver API의 Envelope 메시지 탐색 제어용
6 CHAINCODE_PACKAGE 설치 시 체인코드 패키징에 사용
8 PEER_ADMIN_OPERATION Peer에서 수행되는 관리적 작업 호출
HeaderType 정의 (protos/common/common.proto)
2번 블록 구조 - 트랜잭션 목록
14
{
"tx_actions": [
"header": "...미 해석 영역.."
"payload": {
"chaincode_proposal_payload": {
"chaincode_invocation_spec": {
"chaincode_spec": {
"type": 1,
"chaincode_id": {
"name": "lscc"
},
"chaincode_input": {
"args": [
"deploy", "..매개변수2..", "..매개변수3..", "매개변수4"
]
}
}
}
},
"action": {
.. 뒷장에 이어짐 ..
}
}
]
}
message ChaincodeActionPayload (transaction.proto)
message ChaincodeProposalPayload (proposal.proto)
message ChaincodeInvocationSpec (chaincode.proto)
message ChaincodeSpec (chaincode.proto)
message ChaincodeID (chaincode.proto)
message ChaincodeInput (chaincode.proto)
2번 블록 구조 - 트랜잭션 목록
15
{
"tx_actions": [
"action": {
"proposal_response_payload": {
"proposal_hash": "8f7e3b4609e63d358b354b1895eaa44169dad45776085902dcafc7597e51df4e"
"extension": {
"results": {
"ns_rwset": {
"namespace": "lscc",
"rwset": {
"reads": [ { "key": "fabcar" } ],
"writes": [ { "key": "fabcar", "value": "0a06666162636172120331..." } ]
}
}
},
"response": {
"payload": "0a0666616263617...",
"status": 200
},
"chaincode_id": "12046c7363631a05312e322e30"
}
},
"endorsements": [
{
"signature": "304502210083c6c0ca3263f71bfb8...",
"endorser": "0a074f7267314d53501296062d2d2d2d2..."
}
]
}
}
]
}
message ProposalResponsePayload (proposal_response.proto)
message ProposalResponsePayload (transaction.proto)
message ChaincodeAction (proposal.proto)
message TxReadWriteSet (rwset.proto)
message NsReadWriteSet (rwset.proto)
message KVRWSet (kv_rwset.proto)
message KVRead (kv_rwset.proto)
message KVWrite (kv_rwset.proto)
message ChaincodeEndorsedAction (transaction.proto)
ㅐ
감사합니다
서울특별시 마포구 새창로 7 SNU장학빌딩 1601호 (도화동 565)
02-6730-7249 contact@logpresso.com

하이퍼레저 패브릭 데이터 구조

  • 1.
    ㅐ 바이트 수준의 프로토콜버퍼 데이터 구조 해석
  • 2.
    CentOS 하이퍼레저 패브릭예제 설치 2 $ sudo usermod -aG docker xeraph # yum -y install yum-utils # yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # yum -y install docker-ce # yum -y install python-pip # pip install docker-compose # yum update openssl # curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash - # yum -y install nodejs golang gcc-c++ # curl -sSL http://bit.ly/2ysbOFE | bash -s 1.2.0
  • 3.
  • 4.
    fabcar 도커 네트워크구성 4 dev-peer0.org1.example.com-fabcar-1.0 cli hyperledger/fabric-tools peer0.org1.example.com hyperledger/fabric-peer ca.example.com hyperledger/fabric-ca orderer.example.com hyperledger/fabric-orderer couchdb hyperledger/fabric-couchdb chaincode 실행 7051/tcp, 7053/tcp 7054/tcp 7050/tcp 4369/tcp, 9100/tcp, 5984/tcp fabric 쉘
  • 5.
    peer0 도커 컨테이너디렉터리 구조 5 /var/hyperledger/production/ chaincodes/ fabcar.1.0/ ledgersData/ 000001.log, CURRENT, LOCK, LOG, MANIFEST-000000 bookkeeper/ chains/ chains/ mychannel/ blockfile_000000 index/ 000001.log, CURRENT, LOCK, LOG, MANIFEST-000000 configHistory/ historyLeveldb/ ledgerProvider/ pvtdataStore/ 000001.log, CURRENT, LOCK, LOG, MANIFEST-000000 000001.log, CURRENT, LOCK, LOG, MANIFEST-000000 000001.log, CURRENT, LOCK, LOG, MANIFEST-000000 000001.log, CURRENT, LOCK, LOG, MANIFEST-000000 오늘의 주제 leveldb 파일 leveldb 파일 leveldb 파일 leveldb 파일 leveldb 파일 leveldb 파일
  • 6.
    간단한 바이너리 파일탐색 6 $ strings blockfile_000000 본격적으로 파일 분석을 시작하기 전에 Fabric SDK를 통해 조회했던 문자열 조각들이 존재함을 확인
  • 7.
    하이퍼레저 패브릭 소스다운로드 7 https://github.com/hyperledger/fabric fabric-release-1.2.zip 18MB (압축 해제시 42MB)
  • 8.
    전체 블록 구조 8 blockfile_mgr.go func(mgr *blockfileMgr) addBlock(block *common.Block) error { ... blockBytesLen := len(blockBytes) blockBytesEncodedLen := proto.EncodeVarint(uint64(blockBytesLen)) totalBytesToAppend := blockBytesLen + len(blockBytesEncodedLen) ... //append blockBytesEncodedLen to the file err = mgr.currentFileWriter.append(blockBytesEncodedLen, false) if err == nil { //append the actual block bytes to the file err = mgr.currentFileWriter.append(blockBytes, true) } • 블록 길이를 먼저 쓰고 블록 데이터를 쓰는 코드를 보면 가변 블록 구조임을 파악할 수 있음 • EncodeVarint 는 프로토콜 버퍼의 정수 인코딩이므로, 단지 gRPC 뿐 아니라 블록 파일에서도 프로토콜 버퍼를 광범위하게 사용할 것이라는 사실을 이 시점에서 추정 가능
  • 9.
    프로토콜 버퍼 인코딩 9 https://developers.google.com/protocol-buffers/docs/encoding 메모리의정수 표현 디스크, 네트워크 입출력 시 정수 표현 int16 int32 int64 1 2 1 2 3 4 1 2 3 4 5 6 7 8 varint 0000 00011 = 300 = 1010 1100 0000 0010 10 0101100(2) = 300(10) • 메모리에서는 일반적으로 고정 길이 공간을 사용하여 수치형을 표현합니다. • 디스크, 네트워크 전송 시에는 I/O 대역폭 및 저장 공간 점유를 최소화하기 위해 가변 길이 인코딩을 일반적으로 사용합니다. • VarInt (Variable-length Integer) 는 고전적인 가변 길이 인코딩 방식으로, 가장 앞 비트 (MSB)를 뒷 바이트가 이어진다는 신호로 사용하고 7비트를 이어 붙여서 전체 데이터를 표현합니다. • 패브릭 프로토콜 버퍼는 Little Endian 기준이라 7비트 그룹을 역순으로 조립해야 합니다. - 예를 들어 정수 300은 000 0010 010 1100 처럼 이어붙여서 해석합니다.
  • 10.
    프로토콜 버퍼 인코딩 10 https://developers.google.com/protocol-buffers/docs/encoding 타입별인코딩 방식 타입번호 의미 타입 매핑 0 VarInt int32, int64, uint64, sint32, sint64, bool, enum 1 64비트 fixed64, sfixed64, double 2 길이 지정 string, bytes, embedded message, packed repeated fields 3 그룹 시작 groups (폐기됨) 4 그룹 끝 groups (폐기됨) 5 32비트 fixed32, sfixed32, float 길이 지정 인코딩 예시 (문자열) 복합 메시지 예시 07 74 65 73 74 69 6e 67"testing" 7글자 t e s t i n g message Test2 { optional string b = 2; } 07 74 65 73 74 69 6e 67 7글자 t e s t i n g 12 메타 00010 010 2번 필드 2번 타입 • 아쉽게도 message (complex type)와 bytes, string 의 타입 구분이 안 되어서 메타데이터 정의 없이 파싱하는 것은 원천적으로 불가능 • 필드 번호를 지정하므로 optional 구현 은 간단하고 효율적임.
  • 11.
    1번 블록 구조 11 { "header":{ "channel_header": { "type": 1, "channel_id": "mychannel", "timestamp": "2018-08-20 01:12:48+0900" } "signature_header": { "creator": { "mspid": "OrdererMSP", "id_bytes": "-----BEGIN CERTIFICATE----- nMIICDDCCAbOgAwIBAgIRAK30hdRcBxQJYNPqPkiFo3IwCgYIKoZIzj0EAwIwaTELnMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGncmFuY2lzY 28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRcwFQYDVQQDEw5jYS5leGFtncGxlLmNvbTAeFw0xNzA4MzEwOTE0MzJaFw0yNzA4MjkwOTE0MzJaMFgxCzAJBgNVnBAYTAlVTMRMwEQ YDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpnc2NvMRwwGgYDVQQDExNvcmRlcmVyLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYInKoZIzj0DAQcDQgAE UOJGzpasxjS5EJmbFIe/GtOJJAo6mhJqLyYT9PBvVSdaQ/TQnlMNlqLEZgFP6wc9CtrUp/WDnZ/M2zLpoDPjkcqNNMEswDgYDVR0PAQH/BAQDAgeAnMAwGA1UdEwEB/wQCMAAwKwYD VR0jBCQwIoAgoGBqSoYKHjHJCiN4jabztrdJJe0NnIwYa9ImUCbpGrmowCgYIKoZIzj0EAwIDRwAwRAIgHsU1f4jzuul6zYGY/Xn/H5X5ngDe7/u8dZxJfWwXOGNsCICbXt6yezSzacOFQDkvAP z5/3OYI5YKLSTl+Wilfa/qyn-----END CERTIFICATE-----n" }, "nonce": "ef86bebfe565f8aed0c60994bd480fd013bd77808f65a554" }, }, "data": "..미 해석 영역.." } 헤더 타입 ENUM 설명 0 MESSAGE 서명된 메시지이나 데이터 구조가 알려지지 않은 것 1 CONFIG 채널 설정 메시지 2 CONFIG_UPDATE 채널 설정 업데이트 트랜잭션 3 ENDORSER_TRANSACTION Endorser 기반 트랜잭션 제출 (SDK에서 사용) 4 ORDERER_TRANSACTION Orderer가 사용하는 관리용 메시지 5 DELIVER_SEEK_INFO Deliver API의 Envelope 메시지 탐색 제어용 6 CHAINCODE_PACKAGE 설치 시 체인코드 패키징에 사용 8 PEER_ADMIN_OPERATION Peer에서 수행되는 관리적 작업 호출 HeaderType 정의 (protos/common/common.proto)
  • 12.
    체인코드 트랜잭션 수행흐름 proposal.proto 참조 12 Client Endorser Client Endorser 1 2 Client Orderer 3 이 proposal에 대한 action 전체 응답 페이로드에 대한 Endorser의 서명들 action을 요청한 proposal의 페이로드 action을 요청한 proposal의 헤더 헤더의 creator가 Transaction 에 대해 수행한 서명 전체 응답 페이로드에 대한 Endorser의 서명 이 proposal에 대한 action 이 proposal에 대한 action (생략 가능) 이 proposal의 페이로드 이 proposal의 헤더 헤더의 creator가 proposal 에 대해 수행한 서명 • 클라이언트는 1개 이상의 proposal을 모아서 하나의 트랜잭션 메 시지를 생성하고 이를 orderer에게 전송합니다. • orderer는 여러 개의 트랜잭션을 배치 단위로 commiting peer에게 전달(deliver)합니다. committing peer는 검증 후 원장에 반영합니 다. • 트랜잭션은 1개 이상의 action으로 구성되고, 각각 헤더, 제안 (proposal) 페이로드, 서명된 응답 페이로드 (response)를 포함합니 다. • 응답은 성공/실패 코드, 응답 페이로드, 응답 페이로드에 대한 서명으로 구성됩니다. • 응답 페이로드는 요청 (proposal)에 대한 해시를 포함합니다. 이는 특정 요청에 대한 응답을 안전하게 매핑할 목적입니다. • proposal은 체인코드를 실행해달라는 요청입니다. - 체인코드의 상태 변경 및 원장에 데이터 반영 • proposal은 헤더와 페이로드로 구성됩니다. - 헤더: 타입, 실행요청자, 시각, 체인ID, Nonce - 페이로드: 체인코드ID, 호출 매개변수
  • 13.
    2번 블록 구조- 헤더 13 { "header": { "channel_header": { "type": 3, "timestamp": "2018-08-20 01:12:51+0900", "channel_id": "mychannel", "tx_id": "bc395ae86abbc9b75aa41b998bf2d0f4cf4e78af2bd59c20a455965d498675c2", "extension": "120612046c736363" }, "signature_header": { "creator": { "mspid": "Org1MSP", "id_bytes": "-----BEGIN CERTIFICATE----- nMIICGDCCAb+gAwIBAgIQFSxnLAGsu04zrFkAEwzn6zAKBggqhkjOPQQDAjBzMQswnCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZynYW5 jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eunb3JnMS5leGFtcGxlLmNvbTAeFw0xNzA4MzEwOTE0MzJaFw0yNzA4MjkwOTE0MzJanMFsxCzAJBgNV BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TnYW4gRnJhbmNpc2NvMR8wHQYDVQQDDBZBZG1pbkBvcmcxLmV4YW1wbGUuY29tMFkwnEwYHKoZIzj0C AQYIKoZIzj0DAQcDQgAEV1dfmKxsFKWo7o6DNBIaIVebCCPAM9C/nsLBt4pJRre9pWE987DjXZoZ3glc4+DoPMtTmBRqbPVwYcUvpbYY8p6NNMEswDgYDnVR0PAQH/BAQDAgeAMAwG A1UdEwEB/wQCMAAwKwYDVR0jBCQwIoAgQjmqDc122u64nugzacBhR0UUE0xqtGy3d26xqVzZeSXwwCgYIKoZIzj0EAwIDRwAwRAIgXMy26AEUn/GUMPfCMs/nQjQME1ZxBHAYZtKEu RR361JsCIEg9BOZdIoioRivJC+ZUzvJUnkXuno2HkWiuxLsibGxtEn-----END CERTIFICATE-----n" }, "nonce": "998d2b96865a56bda70c0e09a2acefa6e9cad8015ee17d6a" } }, "tx_actions": [ .... ] } 헤더 타입 ENUM 설명 0 MESSAGE 서명된 메시지이나 데이터 구조가 알려지지 않은 것 1 CONFIG 채널 설정 메시지 2 CONFIG_UPDATE 채널 설정 업데이트 트랜잭션 3 ENDORSER_TRANSACTION Endorser 기반 트랜잭션 제출 (SDK에서 사용) 4 ORDERER_TRANSACTION Orderer가 사용하는 관리용 메시지 5 DELIVER_SEEK_INFO Deliver API의 Envelope 메시지 탐색 제어용 6 CHAINCODE_PACKAGE 설치 시 체인코드 패키징에 사용 8 PEER_ADMIN_OPERATION Peer에서 수행되는 관리적 작업 호출 HeaderType 정의 (protos/common/common.proto)
  • 14.
    2번 블록 구조- 트랜잭션 목록 14 { "tx_actions": [ "header": "...미 해석 영역.." "payload": { "chaincode_proposal_payload": { "chaincode_invocation_spec": { "chaincode_spec": { "type": 1, "chaincode_id": { "name": "lscc" }, "chaincode_input": { "args": [ "deploy", "..매개변수2..", "..매개변수3..", "매개변수4" ] } } } }, "action": { .. 뒷장에 이어짐 .. } } ] } message ChaincodeActionPayload (transaction.proto) message ChaincodeProposalPayload (proposal.proto) message ChaincodeInvocationSpec (chaincode.proto) message ChaincodeSpec (chaincode.proto) message ChaincodeID (chaincode.proto) message ChaincodeInput (chaincode.proto)
  • 15.
    2번 블록 구조- 트랜잭션 목록 15 { "tx_actions": [ "action": { "proposal_response_payload": { "proposal_hash": "8f7e3b4609e63d358b354b1895eaa44169dad45776085902dcafc7597e51df4e" "extension": { "results": { "ns_rwset": { "namespace": "lscc", "rwset": { "reads": [ { "key": "fabcar" } ], "writes": [ { "key": "fabcar", "value": "0a06666162636172120331..." } ] } } }, "response": { "payload": "0a0666616263617...", "status": 200 }, "chaincode_id": "12046c7363631a05312e322e30" } }, "endorsements": [ { "signature": "304502210083c6c0ca3263f71bfb8...", "endorser": "0a074f7267314d53501296062d2d2d2d2..." } ] } } ] } message ProposalResponsePayload (proposal_response.proto) message ProposalResponsePayload (transaction.proto) message ChaincodeAction (proposal.proto) message TxReadWriteSet (rwset.proto) message NsReadWriteSet (rwset.proto) message KVRWSet (kv_rwset.proto) message KVRead (kv_rwset.proto) message KVWrite (kv_rwset.proto) message ChaincodeEndorsedAction (transaction.proto)
  • 16.
    ㅐ 감사합니다 서울특별시 마포구 새창로7 SNU장학빌딩 1601호 (도화동 565) 02-6730-7249 contact@logpresso.com