Skip to content

Commit

Permalink
feat: 增加凭证注册的内容
Browse files Browse the repository at this point in the history
  • Loading branch information
Cishoon committed Jul 15, 2024
1 parent 0aadff2 commit 17bdd87
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 8 deletions.
2 changes: 0 additions & 2 deletions chaincode/src/NFTicket/NFTicketContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ export class NFTicketContract extends Contract
return results;
}



private async getDIDDocumentFromDIDContract(ctx: Context, did: string): Promise<DIDDocument>
{
const didContractName = 'DIDContract'; // Name of the deployed DIDContract
Expand Down
20 changes: 20 additions & 0 deletions chaincode/src/did/DIDContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Context, Contract, Info, Returns, Transaction } from 'fabric-contract-a
import { DIDDocument } from './DIDDocument';
import stringify from 'json-stringify-deterministic';
import sortKeysRecursive from 'sort-keys-recursive';
import shajs from 'sha.js';

@Info({ title: 'DID', description: 'Smart contract for DID' })
export class DIDContract extends Contract
Expand Down Expand Up @@ -71,6 +72,25 @@ export class DIDContract extends Contract
return didDocumentBytes && didDocumentBytes.length > 0;
}

@Transaction()
public async registerCredential(ctx: Context, issuerDid: string, credential: string): Promise<void>
{
if (issuerDid !== 'did:example:vcissuer') {
throw new Error(`Issuer DID ${issuerDid} is not allowed to issue credentials`);
}

const credentialHash = shajs("sha256").update(credential).digest('hex');
// Store the credential
await ctx.stub.putState(credentialHash, Buffer.from(issuerDid));
}

@Transaction(false)
@Returns("boolean")
public async checkCredential(ctx: Context, issuerDid: string, credential: string): Promise<boolean>
{
const credentialHash = shajs("sha256").update(credential).digest('hex');
const issuerDidBytes = await ctx.stub.getState(credentialHash);
return issuerDidBytes && issuerDidBytes.length > 0 && issuerDidBytes.toString() === issuerDid;
}

}
1 change: 0 additions & 1 deletion client/src/components/NavBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
import router from "../router";
import { Message } from "@arco-design/web-vue";
const didDocument = ref();
const privateKey = ref();
Expand Down
1 change: 1 addition & 0 deletions client/src/utils/vc/vc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ async function anonymousVC(oldVc: VerifiableCredential, assertBirthYear: string)
const newCredentialSubject = {
id: credentialSubject.id,
assert: assertBirthYear,
dataIndex: dataIndex,
salt: merkleTree.getSalts()[dataIndex],
merklesibling: merklesibling,
merkleTreeRoot: credentialSubject.birthYearAssert.merkleTreeRoot,
Expand Down
2 changes: 1 addition & 1 deletion server/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ app.post('/api/vc/birthday_merkle/apply', async (req, res) =>
const keyPair = JSON.parse(result.toString());
const privateKey = keyPair.privateKey;

const vc = await createBirthYearCredentialByMerkleTree("did:example:vcissuer", did, birthyear, privateKey);
const vc = await createBirthYearCredentialByMerkleTree("did:example:vcissuer", did, birthyear, privateKey, contract);
res.json(vc);
})

Expand Down
14 changes: 11 additions & 3 deletions server/src/utils/vc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ async function createBirthYearCredential(issuerDID: string, subjectDID: string,


// 通过Merkle Tree创建VC
async function createBirthYearCredentialByMerkleTree(issuerDID: string, subjectDID: string, birthYear: number, privateKey: string): Promise<VerifiableCredential>
async function createBirthYearCredentialByMerkleTree(issuerDID: string, subjectDID: string, birthYear: number, privateKey: string, contract: Contract): Promise<VerifiableCredential>
{
const min = 1900;
const max = 2020;
Expand All @@ -71,6 +71,7 @@ async function createBirthYearCredentialByMerkleTree(issuerDID: string, subjectD

// 给树根签名
const rootSignature = await signData(merkleTreeRoot, privateKey);
contract.submitTransaction("registerCredential", issuerDID, merkleTreeRoot);

let description;
if (birthYear < min) {
Expand Down Expand Up @@ -176,7 +177,7 @@ async function checkBirthYearMerkeTreeProof(contract: Contract, credentialSubjec
{
const min = 1900;
console.log("credentialSubject", credentialSubject);
const { assert, salt, merklesibling, merkleTreeRoot, rootSignature, signer } = credentialSubject;
const { assert, dataIndex, salt, merklesibling, merkleTreeRoot, rootSignature, signer } = credentialSubject;

// 先验证merkleTreeRoot的签名
const signerDID = signer.split('#')[0];
Expand All @@ -191,9 +192,16 @@ async function checkBirthYearMerkeTreeProof(contract: Contract, credentialSubjec
console.error("rootSignature verification failed");
return false;
}
const hasRegistedString = await contract.evaluateTransaction("checkCredential", signerDID, merkleTreeRoot)
const hasRegisted = Buffer.from(hasRegistedString).toString('utf-8') === "true";
if (!hasRegisted) {
console.error("merkleTreeRoot not registed");
return false;
}

// 判断声明和数据是否匹配
const index = parseInt(assert.split(':')[0]) - min + 1;
// const index = parseInt(assert.split(':')[0]) - min + 1;
const index = dataIndex;
const leaf = assert.split(':')[1];

// 验证默克尔路径是否正确
Expand Down
2 changes: 1 addition & 1 deletion server/wallet/vcissuer.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"publicKey":"zrRM874aALTgDBCL9y5V3mcH3vcMaAorKhZ4f74cca4R3","privateKey":"zKI5m8ObcxC4S8JX0+likuNtHwieSsEiXt3Tmgn4eS4="}
{"publicKey":"zqqJgEpCWWhpoScWdXTJMHbgBYro3fYme6z4RrB85sCJD","privateKey":"dzTkh91rLE3thenO+PzibE6B18smDcmFdvzNketS5hs="}

0 comments on commit 17bdd87

Please sign in to comment.