일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 자료구조 #알고리즘
- 미쉬킨의화폐와금융 #미쉬킨 #화폐금융론 #화폐와금융 #경제학 #교양 #경제지식 #경제공부
- #경제상식 #화폐 #금융 #화폐금융론 #경제학 #경제기본 #경제지식 #경제근육 #투자지식 #경제공부 #경제학전공 #금융이란 #화폐란 #금융시장 #금융시장역할 #화폐역할 #화폐역기능 #금융역기능 #
- 페이스북유니버시티 #마케팅교육 #마케팅캠프
- #국제채권시장 #유로본드 #유로커런시 #유로달러 #외국채 #금융중개기관 #간접금융 #거래비용#다우존스공업평균지수 #나스닥종합지수 #FTSE100 #DAX #CAC40 #straittimes #항생지수 #거래비용 #유동성 #위
- 블록체인 #layer2 #레이어2 #이더리움스케일링
- vp #vc #did #신원인증 #블록체인
- html #js #parsing
Archives
- Today
- Total
평행우주 : world 1
[실습 | Solidity] 블록체인을 사용한 DID 백신 접종 인증서 개발 본문
텃밭 1 : BlockChain/SSI | DID
[실습 | Solidity] 블록체인을 사용한 DID 백신 접종 인증서 개발
parallelworlds 2022. 4. 7. 15:55
💁 SSI, DID가 매력적인 이유
우리는 신원과 식별자를 종종 혼동하는 경우가 있다.
우리가 신원하면 흔히 떠올리는 신분증, 여권, 인증서 등은 신원이 아닌 식별자다.
신원은 보다 더 개인적이고, 자기주권적 인간인 내 자신의 통제하에 있는 것이다.
문제는, 우리의 신원과 관련된 대부분의 것들이 조직의 관리 편리성을 위한 방법대로
우리 자신의 통제가 없는 상태에서 이뤄지고 있다는 것이다.
우리는 우리의 신원을 통제할 필요가 있다
SSI의 발전은 바로 그 시작점이다
✍🏻 SSI, DID에 대한 짧은 정리글
🧑🏽💻 만들어 볼 것 : 백신 접종 증명서
코로나 19 백신 접종을 받았음을 검증 가능한 자격 증명을 DID로 구현해보자
W3C의 권고사항에 따르면 다음과 같은 사항을 설계 시 참고해야 한다
>> 발급자가 선택적 공개를 지원하는 소프트웨어가 없는 경우에도,
선택적 공개를 지원하는 검증가능한 크리덴셜을 발급할 수 있는 수단 제공
>> 발급자는 선택적 공개를 지원하는 검증가능한 크리덴셜을 발급 가능
검증은 어떤 발급자에게도 검증자의 신원을 공개하지 않아야 함
>> issuanceDate
크리덴셜이 유효한 날짜와 시간을 나타내는 문자열 값
>> proof
변조를 감지하고 크리덴셜 또는 프레젠테이션의 소유권을 확인하는 데 사용할 수 있는 암호화 프루프
>> credentialStatus
id , type 등이 포함되어야 한다
이보다 더더 많은데,, 일단 도전해볼 수 있을만한 것들만 추려보았다.
일단 이번에는 위의 참고사항도 다 포함하지 않은
아주 간단한 DID 개발을 해볼 예정이다
👀 코드 분석
OwnerHelper
// Owner만 실행할 수 있는 컨트랙트
abstract contract OwnerHelper {
address private owner;
event OwnerTransferPropose(address indexed _from, address indexed _to);
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
// 함수 호출 시 owner = msg.sender로 자동 설정
constructor() {
owner = msg.sender;
}
// owner 권한을 가진 자가 다른 주소로 권한 위임
function transferOwnership(address _to) public onlyOwner {
require(_to != owner);
require(_to != address(0x0));
owner = _to;
emit OwnerTransferPropose(owner, _to);
}
}
IssuerHelper
// IssuerHelper는 Issuer을 추가 또는 삭제할 수 있다
// 그 기능은 onlyOwner로 제한되어 Owner만 제어 가능
abstract contract IssuerHelper is OwnerHelper {
mapping(address => bool) public issuers;
event AddIssuer(address indexed _issuer);
event DelIssuer(address indexed _issuer);
modifier onlyIssuer() {
require(isIssuer(msg.sender) == true);
_;
}
constructor() {
issuers[msg.sender] = true;
}
function isIssuer(address _addr) public view returns (bool) {
return issuers[_addr];
}
function addIssuer(address _addr) public onlyOwner returns (bool) {
require(issuers[_addr] == false);
issuers[_addr] = true;
emit AddIssuer(_addr);
return true;
}
function delIssuer(address _addr) public onlyOwner returns (bool) {
require(issuers[_addr] == true);
issuers[_addr] = false;
emit DelIssuer(_addr);
return true;
}
}
CredentialBox : mapping, struct
// Credential 발행, 확인
contract CredentialBox is IssuerHelper {
uint256 private idCount; // Credential이 한 주소에 하나씩만 발급받게 한다
mapping(uint8 => string) private vaccineEnum; // 백신 종류
mapping(uint8 => string) private statusEnum; // 접종 상태 (횟수)
// VC를 구현하기 위한 구조체
struct Credential {
uint256 id; // index 순서 표기하는 idCount
address issuer; // 발행자
uint8 vaccineType; // 백신 증명서 타입
uint8 statusType; //접종 상태 (횟수)
string value; // 크리덴셜에 포함되어야 하는 암호화된 정보.
// 중앙화된 서버에서 제공하는 신원, 서명 등이 JSON 형태로 저장됨
uint256 createDate;
}
// 주소값으로 발급된 크리덴셜 확인
mapping(address => Credential) private credentials;
CredentialBox : constructor
constructor() {
idCount = 1;
vaccineEnum[0] = "미접종 권고 대상자"; //약물알러지, 기저질환 등
vaccineEnum[1] = "PFI"; //화이자
vaccineEnum[2] = "JOH"; //얀센
vaccineEnum[3] = "AST"; //아스트라제네카
vaccineEnum[4] = "NOV"; //노바백스
vaccineEnum[5] = "MOD"; //모더나
statusEnum[0] = "미접종"; // 접종 상태 (횟수)
statusEnum[1] = "1회차";
statusEnum[2] = "2회차";
statusEnum[3] = "3회차";
statusEnum[4] = "4회차";
}
CredentialBox : claimCredential
// claimCredential 함수로 Credential 발행
function claimCredential(
address _vaccineAddress,
uint8 _vaccineType,
uint8 _vaccineStatusType,
string calldata _value
) public onlyIssuer returns (bool) {
Credential storage credential = credentials[_vaccineAddress];
// credential의 id가 0일 경우에만 함수 작동
require(credential.id == 0);
credential.id = idCount;
credential.issuer = msg.sender;
credential.vaccineType = _vaccineType;
credential.statusType = 0;
credential.value = _value;
credential.createDate = block.timestamp; //block.timestamp를 활용해 크리덴셜을 클레임한 시간 저장
idCount += 1;
return true;
}
CredentialBox : getCredential, addStatusType, changeStatus
// getCredential 함수로 Credential을 발행한 주소에서 VC확인
function getCredential(address _vaccineAddress)
public
view
returns (Credential memory)
{
return credentials[_vaccineAddress];
}
function addVaccineType(uint8 _type, string calldata _value)
public
onlyIssuer
returns (bool)
{
require(bytes(vaccineEnum[_type]).length == 0);
vaccineEnum[_type] = _value;
return true;
}
function getVaccineType(uint8 _type) public view returns (string memory) {
return vaccineEnum[_type];
}
// bytes로 변환하여 길이로 String이 null인지 검사
// 내부 statusEnum의 Type이 중복되는 타입이 존재하는지 검사
function addStatusType(uint8 _type, string calldata _value)
public
onlyIssuer
returns (bool)
{
require(bytes(statusEnum[_type]).length == 0);
statusEnum[_type] = _value;
return true;
}
function getStatusType(uint8 _type) public view returns (string memory) {
return statusEnum[_type];
}
// 특정 사용자의 상태 변경
// statusType의 값을 가져와 변경한다
function changeStatus(address _vaccine, uint8 _type)
public
onlyIssuer
returns (bool)
{
require(credentials[_vaccine].id != 0);
require(bytes(statusEnum[_type]).length != 0);
credentials[_vaccine].statusType = _type;
return true;
}
}
🧩 전체 코드
'텃밭 1 : BlockChain > SSI | DID' 카테고리의 다른 글
[SSI | DID] DID Document 구성요소 : id (0) | 2022.03.31 |
---|---|
[SSI | DID] DID(Decentralized IDentifier) 구성요소, 생성과 사용과정 (0) | 2022.03.31 |
[SSI | DID] SSI 자기주권 신원증명 인증 (0) | 2022.03.31 |
Comments