체인코드 개발자 입장에서 채널에서 체인코드를 배포하고 관리하는 방법에 대해 알아보쟈~~
체인코드란?
: 애플리케이션에서 제출한 트랜잭션을 통해 원장 상태를 초기화하고 관리
- 규정된 인터페이스를 구현하는 Go , Node.js 또는 Java 로 작성된 프로그램
- 보증 피어 프로세스와 격리된 보안 Docker 컨테이너에서 실행
- 일반적으로 "스마트 계약"이라고 봐도됨 ^^ : 네트워크 구성원이 동의한 비즈니스 로직을 처리하므로
- 체인코드에 의해 생성된 원장 업데이트는 해당 체인코드로만 범위가 지정 = 다른 체인코드에 직접 액세스X
- but 동일 네트워크 내에서 적절한 권한이 부여된 체인코드는 해당 state 접근을 위해 다른 체인코드 호출 가능
체인코드 배포
- Fabric 체인코드 라이프사이클은 체인코드 사용 전, 작동 방식에 대해 여러 조직에서 동의할 수 있는 프로세스
- 네트워크 운영자는 패브릭 수명 주기를 사용하여 다음 작업을 수행 (아래 글 목차)
- 체인코드 설치 및 정의
- 체인코드 업그레이드
- 배포 시나리오
- 새로운 Fabric 수명 주기로 마이그레이션
체인코드 설치 및 정의
- 조직이 이름, 버전, 체인코드 승인 정책과 같은 체인코드를 정의하는 매개변수에 동의해야 함.
**채널 구성원 합의 과정(모든 조직이 할 필요x)**
1. 체인코드 패키징: 한 조직 또는 각 조직에서 완료
- 피어에 체인코드 설치: 체인코드를 사용하여 트랜잭션을 승인하거나 원장에 쿼리하는 모든 조직에서 완료
- 조직에 대한 체인코드 정의 승인: 체인코드를 사용할 모든 조직에서 완료
- 체인코드 정의를 위해 채널에서 체인코드를 시작하기 전, 충분한 수의 조직에서 승인을 받아야 함.
- 체인코드 정의를 채널에 커밋: 채널에서 필요한 수의 조직이 승인되면 한 조직에서 커밋 트랜잭션을 제출
- 제출자는 먼저 승인한 조직의 충분한 피어로부터 보증을 수집 -> 트랜잭션을 제출 -> 체인코드 정의 커밋
1단계: 스마트 컨트렉트 패키징
체인코드를 tar 파일로 패키징
2단계: 피어에 체인코드 설치
- 트랜잭션을 실행하고 승인할 모든 피어에 체인코드 패키지를 설치
- CLI를 사용하든 SDK를 사용하든 Peer Administrator를 사용하여 피어에 체인코드 설치
- 피어 : 체인코드가 설치된 후 체인코드를 빌드하고 체인코드에 문제가 있는 경우 빌드 오류를 반환
- 조직 : 체인코드를 한 번만 패키징한 다음 조직에 속한 모든 피어에 동일한 패키지 설치(권장)
- 체인코드 실행 확인 : 한 조직에서 체인코드를 패키징하여 대역 외 다른 채널 구성원에게 전송
- 성공적 설치 output = 패키지 해시, 결합된 패키지 레이블인 체인코드 패키지 식별자 반환
- 패키지 식별자 : 피어에 설치된 체인코드 패키지를 조직에서 승인한 체인코드 정의와 연결하는 데 사용
- 식별자 저장 : Peer CLI를 사용하여 피어에 설치된 패키지 쿼리 -> 패키지 식별자 찾기 가능
ex
- Org1 및 Org2의 피어 관리자는 채널에 가입된 피어에 체인코드 패키지 MYCC_1을 설치
- 체인코드 패키지를 설치하면 체인코드가 빌드되고 MYCC_1:hash의 패키지 식별자가 생성
3단계: 조직에 대한 체인코드 정의 승인
- 체인코드는 체인코드 정의에 의해 관리된다.
- 체인코드 정의는 체인코드 매개변수에 대한 조직의 투표를 통해 채널 구성원이 정한다.
- 승인된 조직 정의는 채널 사용전에 채널 구성원이 체인코드의 사용 동의를 허가한다.
- 체인코드 정의에 필요한 매개변수
- 이름: 애플리케이션이 체인코드를 호출할 때 사용할 이름
- 버전: 주어진 체인코드 패키지와 관련된 버전 번호 또는 값
- 체인코드 바이너리를 업그레이드하는 경우 체인코드 버전도 변경
- 시퀀스: 채널에서 체인코드가 정의된 횟수
- 정수이며 체인코드 업그레이드를 추적하는 데 사용
- ex) 채널에서 체인코드 정의를 처음 승인하고 커밋할 때 시퀀스 번호를 1로 설정
-> 다음에 체인코드를 업그레이드하거나 체인코드 정의를 업데이트할 때 시퀀스 번호를 2로 증가
- 피어는 모든 조직이 승인하고 커밋하는 체인코드 정의와 관련하여 동기화 상태를 유지하도록 할때, 시퀀스 사용
- 보증 정책: 트랜잭션 출력을 실행하고 검증해야 하는 조직에서 필요
- CLI에 전달되는 문자열로 표현되거나 채널 구성에서 정책을 참조 가능
- 기본적으로 보증 정책은
Channel/Application/Endorsement
로 설정
- 기본적으로 채널에 있는 대부분의 조직이 트랜잭션을 보증하도록 요구
- 컬렉션 구성: 체인코드와 연결된 개인 데이터 컬렉션 정의 파일의 경로
- ESCC/VSCC 플러그인: 해당 체인코드에서 사용할 사용자 지정 보증 또는 유효성 검사 플러그인의 이름
- 초기화: Fabric Chaincode Shim API에서 제공하는 저수준 API를 사용하는 경우, 체인코드에 체인코드를 초기화하는 데 사용되는 함수
Init
가 포함되어야 한다.
- 체인코드 인터페이스에 필요하지만, 애플리케이션에서 반드시 호출할 필요는 없다.
- Init체인코드 정의를 승인할 때, 호출 전에 호출해야 하는지 여부 지정 가능
- 필수면 Fabric은
Init
함수가 체인코드의 다른 함수보다 먼저 호출되고 한 번만 호출되도록 보증
- Fabric 피어 CLI를 사용하는 경우, 체인코드 정의를 승인하고 커밋할 때 새 체인코드 버전을 초기화하기 위해
Init
함수를 호출하기위해 --init-required
플래그를 사용할수 있음
- Fabric 피어 CLI를 사용하여
Init
을 호출하려면 peer chaincode invoke
명령을 사용하고 --isInit
플래그를 전달해라
- Init Fabric 계약 API를 사용하는 경우 체인코드에 메서드를 포함할 필요가 없지만
--init-required
플래그를 사용하여 응용 프로그램에서 호출하여 체인코드를 초기화하도록 요청 가능하다.
--init-required
플래그를 사용하는 경우, 체인코드 버전을 증가시킬 때마다 체인코드를 초기화하기 위해 --isInit
플래그 또는 매개변수를 체인코드 호출에 전달해야 한다.
--isInit
전달하고, 체인코드의 함수를 사용하여 체인코드를 초기화할 수 있다.
- 대부분의 시나리오에서 위에서 설명한 체인코드 수명 주기 메커니즘을 사용하는 대신 체인코드에 초기화 논리를 포함 권고
- 체인코드 함수는 종종 기존 상태에 대해 검사를 수행하며 초기화 상태는 다른 체인코드 상태처럼 구현될 수 있으며 후속 체인코드 함수 호출에서 확인 가능
- 단일 초기화 함수로 제한되지 않고 초기화 로직을 완전히 제어가능
- 애플리케이션에서 상태를 초기화하는 자체 함수 호출가능
- 체인코드 정의에는 패키지 식별자도 포함 : 체인코드를 사용하려는 각 조직의 필수 매개변수
- 패키지 ID는 모든 조직에서 동일할 필요X
- 조직은 체인코드 패키지를 설치하거나 정의에 식별자를 포함하지 않고 체인코드 정의를 승인 가능
- 체인코드를 사용하려는 각 채널 구성원은 조직에 대한 체인코드 정의를 승인해야 한다.
- 승인은 ordering 서비스에 제출 -> 이후 모든 동료에게 분배
- 승인은 Organization Administrator가 제출 -> 승인된 정의는 조직의 모든 동료가 사용할 수 있는 컬렉션에 저장 => 피어가 여러 개인 경우에도 조직에 대한 체인코드를 한 번만 승인하면 됨.
ex
- Org1 및 Org2의 조직 관리자가 해당 조직에 대한 MYCC의 체인코드 정의를 승인
- 체인코드 정의에는 다른 필드 중에서 체인코드 이름, 버전 및 보증 정책 포함
- 두 조직 모두 체인코드를 사용하여 트랜잭션을 보증 -> 두 조직에 대한 승인된 정의에는 packageID가 포함되어야 함.
4단계: 체인코드 정의를 채널에 커밋
- 충분한 수의 채널 구성원이 체인코드 정의를 승인하면 한 조직이 정의를 채널에 커밋할 수 있음
checkcommitreadiness
명령 : 피어 CLI를 사용하여 채널에 정의를 커밋하기 전, 해당 명령어를 사용하여 어떤 채널 구성원이 정의를 승인했는지에 따라 체인코드 정의 커밋이 성공해야 하는지 여부 확인 가능
- 조직에 대해 승인된 체인코드 정의 질의 -> 조직이 승인한 경우, 정의를 보증하는 채널 구성원의 동료에게 커밋 트랜잭션 제안 전송 -> 트랜잭션이 ordering service에 제출 -> 체인코드 정의가 채널
- 커밋 정의 트랜잭션은 Organization Administrator로 제출해야 함.
- 채널에 성공적으로 커밋되기 전, 정의를 승인해야 하는 조직의 수는
Channel/Application/LifecycleEndorsement
정책에 따라 결정
Channel/Application/LifecycleEndorsement
정책 : 채널 내 대부분의 조직이 트랜잭션 보증 요구
- LifecycleEndorsement 정책은 체인코드 보증 정책과 별개
- 체인코드 보증 정책이 하나 또는 두 개의 조직의 서명만 요구하더라도 대부분의 채널 구성원은 여전히 기본 정책에 따라 체인코드 정의 승인
- 채널 정의를 커밋할 때 LifecycleEndorsement 정책을 충족하기 위해 채널에서 충분한 피어 조직을 대상으로 지정해야 함.
- Channel/Application/LifecycleEndorsement 정책을 서명 정책으로 설정하고 체인코드 정의를 승인할 수 있는 채널의 조직 세트를 명시적으로 지정할 수도 있음
- 선택된 수의 조직이 체인코드 관리자 역할을 하고, 채널에서 사용되는 비즈니스 논리를 관리하는 채널 생성 가능
- 채널에 체인코드 정의를 승인, 보증할 수 없는 많은 Idemix 조직이 있는 경우, 서명 정책을 사용 가능
=> 채널이 majority에 도달하지 못하게 막는다.
ex
- Org1 또는 Org2의 한 조직 관리자가 체인코드 정의를 채널에 커밋
- 채널의 정의에는 packageID가 포함X
- 조직은 체인코드 패키지를 설치하지 않고 체인코드 정의를 승인 가능
- 조직에서 체인코드를 사용할 필요가 없는 경우, 패키지 식별자 없이 체인코드 정의를 승인하여 Lifecycle 보증 정책이 충족되도록 할 수 있음.
- 체인코드 정의가 채널에 커밋된 후, 체인코드 컨테이너는 체인코드가 설치된 모든 피어에서 시작되어 채널 구성원이 체인코드 사용을 시작할 수 있음.
- Init 체인코드 정의를 사용하여 체인코드를 초기화하기 위해 함수 호출을 요구 가능
- 이 경우, 체인코드의 첫 번째 호출은 Init 함수 호출이어야 함.
- 함수의 호출은 Init 체인코드 승인 정책의 적용을 받는다.
- MYCC가 채널에 정의되면 Org1 및 Org2는 체인코드를 사용하여 시작할 수 있습니다. 각 피어에서 체인코드를 처음 호출하면 해당 피어에서 체인코드 컨테이너가 시작됩니다.
체인코드 업그레이드
- 체인코드 바이너리를 업그레이드하거나 체인코드 정책만 업데이트 가능
- 체인코드 재패키징: 체인코드 바이너리를 업그레이드하는 경우에만 이 단계를 완료
- 체인코드 재패키징
- Org1 및 Org2는 체인코드 바이너리를 업그레이드하고 체인코드를 다시 패키징함.
- 두 조직 모두 다른 패키지 레이블을 사용
- 피어에 새 체인코드 패키지 설치: 다시 한 번 체인코드 바이너리를 업그레이드하는 경우에만 이 단계를 완료
- 새 체인코드 패키지를 설치하면 새 체인코드 정의에 전달해야 하는 패키지 ID가 생성
- 수명 주기 프로세스에서 체인코드 바이너리가 업그레이드되었는지 추적하는 데 사용되는 체인코드 버전을 변경해야 함.
- Org1 및 Org2는 피어에 새 패키지를 설치 -> 설치 시 새 packageID가 생성
- 새 체인코드 정의 승인:
- 체인코드 바이너리를 업그레이드하는 경우, 체인코드 정의에서 체인코드 버전 및 패키지 ID를 업데이트해야 함
- 체인코드 바이너리를 다시 패키징하지 않아도 체인코드 보증 정책을 업데이트 가능
- 채널 구성원은 새 정책으로 정의를 승인만 하면 됨.
- 새 정의는 정의의 시퀀스 변수를 1씩 증가시켜야 함.
- Org1 및 Org2의 조직 관리자는 해당 조직에 대한 새 체인코드 정의를 승인 -> 새 정의는 새 packageID를 참조하고 체인코드 버전을 변경 -> 시퀀스를 1에서 2로 증가합
- 채널에 정의 커밋: 충분한 수의 채널 구성원이 새 체인코드 정의를 승인하면, 한 조직에서 새 정의를 커밋 -> 체인코드 정의를 채널로 업그레이드 가능
- 수명 주기 프로세스의 일부로 별도의 업그레이드 명령 없음
- Org1 또는 Org2의 조직 관리자가 새 체인코드 정의를 채널에 커밋
- 체인코드 정의를 커밋하면 업그레이드된 체인코드 바이너리의 코드로 새 체인코드 컨테이너가 시작됨.
- 체인코드 정의에서 Init 함수 실행을 요청한 경우 : 새 정의가 성공적으로 커밋 -> Init 함수 재호출
=> 업그레이드된 체인코드 초기화
- 체인코드 버전을 변경하지 않고 체인코드 정의를 업데이트한 경우 : 체인코드 컨테이너는 동일하게 유지되며 Init 함수를 호출할 필요X.
- 새 정의가 채널에 커밋되면 각 피어는 자동으로 새 체인코드 컨테이너를 시작
- 체인코드 정의의 시퀀스를 사용하여 업그레이드를 추적
- 모든 채널 구성원은 시퀀스 번호를 1씩 증가 + 체인코드를 업그레이드하기 위한 새 정의를 승인
- 버전 매개변수는 체인코드 바이너리를 추적하는 데 사용되며 체인코드 바이너리를 업그레이드할 때만 변경해야 함
배포 시나리오
: Fabric 체인코드 수명 주기를 사용하여 채널 및 체인코드를 관리하는 방법을 보여줍니다.
채널 가입
- 새 조직은 체인코드가 이미 정의된 채널에 가입 가능
- 체인코드 패키지를 설치 -> 채널에 이미 커밋된 체인코드 정의 승인 -> 체인코드 사용을 시작
- Org3은 채널에 참여하고 이전에 Org1 및 Org2가 채널에 커밋한 것과 동일한 체인코드 정의를 승인
- 체인코드 정의를 승인 -> 새 조직은 패키지가 피어에 설치 -> 체인코드 사용을 시작
- 정의를 다시 커밋할 필요X
- 보증 정책이 대부분의 채널 구성원의 보증을 요구하는 기본 정책으로 설정된 경우, 보증 정책은 새 조직을 포함하도록 자동으로 업데이트 됨.
- 체인코드 컨테이너는 Org3 피어에서 체인코드를 처음 호출한 후에 시작됨.
보증 정책 업데이트
- 체인코드 정의를 사용하여 체인코드를 다시 패키지하거나 다시 설치할 필요 없이 보증 정책을 업데이트 가능
- 채널 구성원은 새로운 보증 정책으로 체인코드 정의를 승인하고 채널에 커밋 가능
- Org1, Org2 및 Org3은 세 조직 모두가 트랜잭션을 보증하도록 요구하는 새로운 보증 정책을 승인
- 정의 시퀀스를 1에서 2로 증가시키지만 체인코드 버전을 업데이트할 필요는 X
- 새 보증 정책은 새 정의가 채널에 커밋된 후에 적용
- 채널 구성원은 보증 정책을 업데이트하기 위해 체인코드를 호출하거나 Init 함수를 실행하여 체인코드 컨테이너를 다시 시작할 필요 X
- 한 조직은 보증 정책을 업데이트하기 위해 새 체인코드 정의를 채널에 커밋
체인코드를 설치하지 않고 정의 승인
- 체인코드 패키지를 설치하지 않고 체인코드 정의를 승인 가능
- -> 트랜잭션을 승인하거나 원장을 쿼리하는 데 체인코드를 사용하지 않으려는 경우에도, 채널에 커밋되기 전에 체인코드 정의를 승인 가능
- 채널의 다른 구성원과 동일한 매개변수를 승인해야 하지만 체인코드 정의의 일부로 packageID를 포함할 필요는 없음
- Org3는 체인코드를 설치X :
- Org3는 체인코드 패키지를 설치X => 체인코드 정의의 일부로 packageID를 제공X
- ㄴ but Org3는 여전히 채널에 커밋된 MYCC의 정의를 승인 가능
한 조직이 체인코드 정의에 동의하지 않습니다.
- 채널에 커밋된 체인코드 정의를 승인하지 않는 조직은 체인코드를 사용X
- 체인코드 정의를 승인하지 않았거나 다른 체인코드 정의를 승인한 조직은 동료에서 체인코드를 실행 X
- Org3는 체인코드에 동의하지 않음 :
- Org3은 Org1 및 Org2와 다른 보증 정책으로 체인코드 정의를 승인
=> Org3는 채널에서 MYCC 체인코드를 사용X
- Org1 또는 Org2는 정의를 채널에 커밋하고 체인코드를 사용하기에 충분한 보증 받기 가능
- 조직은 모든 시퀀스 번호 또는 버전을 사용하여 새 체인코드 정의를 승인 가능
=> 이를 통해 채널에 커밋된 정의를 승인하고 체인코드 사용을 시작 가능
- 체인코드를 승인하거나 패키징하는 과정에서 발생한 실수를 수정하기 위해 새 체인코드 정의를 승인 가능
채널이 체인코드 정의에 동의하지 않습니다.
- 채널의 조직이 체인코드 정의에 동의하지 않으면 정의를 채널에 커밋할 수 X
- 어떤 채널 구성원도 체인코드를 사용할 수 X.
- 다수가 체인코드에 동의하지 않는 상황
- Org1, Org2 및 Org3은 모두 서로 다른 체인코드 정의를 승인
=> 결과적으로 채널의 어떤 구성원도 체인코드 정의를 채널에 커밋할 만큼 충분한 보증 X
=> 어떤 채널 구성원도 체인코드를 사용할 수 X
조직은 다른 체인코드 패키지를 설치(다른 체인코드 바이너리 사용)
- 각 조직은 체인코드 정의를 승인할 때 다른 packageID를 사용O
=> 이를 통해 채널 구성원은 동일한 보증 정책을 사용하고 동일한 체인코드 네임스페이스에서 데이터를 읽고 쓰는 다른 체인코드 바이너리를 설치 가능
- 조직은 이 기능을 사용하여 조직에 특정한 비즈니스 논리가 포함된 스마트 컨트랙트을 설치O
- 각 조직의 스마트 컨트렉트에는 동료가 트랜잭션을 승인하기 전에 조직에서 요구하는 추가 검증이 포함될 수 있음
- 각 조직은 스마트 계약을 기존 시스템의 데이터와 통합하는 데 도움이 되는 코드를 작성할 수도 있습니다.
다른 체인코드 바이너리 사용
- Org1 및 Org2는 각각 해당 조직에 특정한 비즈니스 로직을 포함하는 MYCC 체인코드 버전을 설치
하나의 패키지를 사용하여 여러 체인코드 생성
- 하나의 체인코드 패키지를 사용하여 여러 체인코드 정의를 승인하고 커밋하여 채널에 여러 체인코드 인스턴스 생성O
- 각 정의는 다른 체인코드 이름을 지정해야 함
=> 채널에서 스마트 계약의 여러 인스턴스를 실행할 수 있지만 계약에 다른 보증 정책이 적용되도록 할 수 O
- Org1 및 Org2는 MYCC_1 체인코드 패키지를 사용하여 두 개의 서로 다른 체인코드 정의를 승인하고 커밋
- 결과적으로 두 피어 모두 피어에서 실행되는 두 개의 체인코드 컨테이너를 가짐
- MYCC1에는 1/2의 보증 정책이 있고 MYCC2에는 2/2의 보증 정책이 있습니다.
출처 : Fabric chaincode lifecycle