JavaScript[TS]

[JS] [블록체인] [코드리뷰] DID를 활용한 의료기록관리 - (上)

viviviviviid 2023. 12. 13. 20:26
 

DMRS 페이지 | Built with Notion

DMRS 프로젝트 : DID Medical Record System

noble-walker-465.notion.site

 

두개의 포스트로 분리되어 작성됩니다.
또한 코드 관련 내용만 들어가니 위 링크를 통해 세부사항을 확인하세요.
두개의 포스트는 프로젝트가 종료된 시점에서 작성하는 리뷰입니다.

 

1. 회원가입 / 신원 VC 발급

  1. 회원가입을 하면 협회에게 DID 식별자 생성을 요청합니다.
  2. 협회는 해당 유저에게 대응되는 지갑을 생성해줍니다.
  3. 생성된 지갑을 기반으로 DID 컨트랙트의 DID 식별자 생성 함수를 호출합니다.
  4. 컨트랙트의 반환값으로 DID 식별자를 받습니다.
  5. 생성한 DID 식별자와 유저의 회원정보를 DB에 저장합니다.
  6. 신원정보가 포함된 VC Payload를 구성합니다.
  7. 협회에 VC payload에 보내 발급을 요청합니다.
  8. 협회는 Payload에 서명을 하고, 체인에 발급기록을 남긴 후 JWT화를 진행합니다.
  9. JWT형태의 VC를 유저에게 전달합니다.

코드로 보자

 

(1~6번 과정)

const signUp = async (req, res) => {
  try {
  
    ⋮
  
    await axios.post(`http://${serverIP}:5002/did/register`, {userInfo: req.body})
    .then(res => {
       { jwt, wallet, SUBJECT_DID } = res.data;
       const userInfo = { name, email, birthday, phoneNumber, isDoctor, wallet, SUBJECT_DID };
       userRegister(userInfo); 
    })
    .catch(err => console.log(err))

    res.status(200).json({jwt:jwt, did:SUBJECT_DID});
  } catch (error) {
      return res.send(400).send(error);
  }
}

 

회원가입 버튼을 누르면 위 signUp 함수가 실행된다.

 

좀 더 자세히 살펴보면

await axios.post(`http://${serverIP}:5002/did/register`, {userInfo: req.body})

 

이 5002번은 진료기록협회 서버이다. VC 발급, VP 발급등을 진행해준다.

 

위 POST API를 통해 협회에게 DID 식별자 생성요청을 하게 된다.

const wallet = ethers.Wallet.createRandom()
const walletInfo = {
  address: wallet.address,
  privateKey: wallet.privateKey,
}

const SUBJECT_DID = new EthrDID({
  identifier: walletInfo.address,
  chainNameOrId
})

협회는 위와 같이 해당 유저 대상으로 지갑을 생성해주고, 방금 생성된 지갑을 기반으로 DID 식별자를 생성해 전달해준다.

 

전달받은 지갑과 DID 식별자를 받아 환자의 회원가입 정보와 함께 DB에 저장해준다.

await axios.post(`http://${serverIP}:5002/did/register`, {userInfo: req.body})
.then(res => {
    ({ jwt, wallet, SUBJECT_DID } = res.data);
    const userInfo = { name, email, birthday, phoneNumber, isDoctor, wallet, SUBJECT_DID };
    userRegister(userInfo); // DB에 저장
})
.catch(err => console.log(err))

 

 

(7~9번 과정)

 

협회는 DID 식별자를 생성해준 뒤, 곧바로 신원정보 VC 발급을 진행한다.

 const vcPayload = {
  sub: SUBJECT_DID,
  vc: {
    '@context': ['https://www.w3.org/2018/credentials/v1'],
    type: ['VerifiableCredential'],
    credentialSubject: {
      issuer: {
        name: 'Medical Record Management Association',
        address: process.env.ISSUER_ADDRESS,
      },
      userInfo: {
        name: data.name,
        email: data.email,
        birthday: data.birthday,
        phoneNumber: data.phoneNumber,
        isDoctor: data.isDoctor,
        address: walletInfo.address,
      },
      doctorLicense: false,
    }
  }
}

const vcJwt = await createVcJwtWithPayload(vcPayload);

우선 VC 내용물을 구성해준다. 들어가는 내용으로는 환자에게 배정된 DID 식별자와 회원가입 정보, 그리고 발급자인 협회의 DID 정보가 들어간다.

 

내용물 구성이 완료되었다면 아래의 함수를 호출해준다.

const createVcJwtWithPayload = async (vcPayload) => {
  const { kp, txHash } = await did.ISSUER_DID.createSigningDelegate(
    DelegateTypes.veriKey, 
    3600, // expiresIn : 3600s
  )

  // 대리 서명자의 DID 생성
  const DELEGATE_ISSUER_DID = new EthrDID({
    identifier: kp.address,
    privateKey: kp.privateKey,
    provider: did.issuerSigner.provider, 
    chainNameOrId
  });

  // VC JWT 생성
  const vcJwt = await createVerifiableCredentialJwt(vcPayload, DELEGATE_ISSUER_DID);

  return vcJwt;
}

VC의 유효기간을 설정해주고, JWT화 한 뒤, 협회 DID로 서명해준다. 그 뒤 VC 발급 함수에 담아 요청하면, 블록체인상에 VC를 발급해줬다는 기록이 남게 되어, 추후 VC 검증시 이용할 수 있게 된다.

 

협회의 기록 트랜잭션 기록들은 아래와 같이 이더스캔에서 확인 가능하다. 

 

트랜잭션은 DID Registry 컨트랙트의 함수를 호출한 내용들이다.

DID Registry 컨트랙트는 다음과 같다. (0xdCa7EF03e98e0DC2B855bE647C39ABe984fcF21B)

 

 

이렇게 VC를 발급했다는 기록을 남긴 후, 환자에게 전달하면 회원가입 / 신원 VC 발급 시나리오가 마무리된다.