Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/test for one time sbt.sol #217

Merged
merged 6 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions common/src/constants/contractConstants.ts
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same constants which is registered in the contract

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Constant Values in OneTimeSBT.sol
export const ATTRIBUTE_ISSUING_STATE_INDEX = 0;
export const ATTRIBUTE_NAME_INDEX = 1;
export const ATTRIBUTE_PASSPORT_NUMBER_INDEX = 2;
export const ATTRIBUTE_NATIONALITY_INDEX = 3;
export const ATTRIBUTE_DATE_OF_BIRTH_INDEX = 4;
export const ATTRIBUTE_GENDER_INDEX = 5;
export const ATTRIBUTE_EXPIRY_DATE_INDEX = 6;
export const ATTRIBUTE_OLDER_THAN_INDEX = 7;

export const PROVE_RSA_NULLIFIER_INDEX = 0;
export const PROVE_RSA_REVEALED_DATA_PACKED_INDEX = 1;
export const PROVE_RSA_OLDER_THAN_INDEX = 4;
export const PROVE_RSA_PUBKEY_DISCLOSED_INDEX = 6;
export const PROVE_RSA_FORBIDDEN_COUNTRIES_LIST_PACKED_DISCLOSED_INDEX = 38;
export const PROVE_RSA_OFAC_RESULT_INDEX = 40;
export const PROVE_RSA_COMMITMENT_INDEX = 41;
export const PROVE_RSA_BLINDED_DSC_COMMITMENT_INDEX = 42;
export const PROVE_RSA_CURRENT_DATE_INDEX = 43;
export const PROVE_RSA_USER_IDENTIFIER_INDEX = 49;
export const PROVE_RSA_SCOPE_INDEX = 50;

export const DSC_BLINDED_DSC_COMMITMENT_INDEX = 0;

111 changes: 111 additions & 0 deletions common/src/utils/unitTest/generateMockProof.ts
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the file to generate mock proof for verifier contract when I run test code

Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import {
PROVE_RSA_NULLIFIER_INDEX,
PROVE_RSA_REVEALED_DATA_PACKED_INDEX,
PROVE_RSA_OLDER_THAN_INDEX,
PROVE_RSA_PUBKEY_DISCLOSED_INDEX,
PROVE_RSA_FORBIDDEN_COUNTRIES_LIST_PACKED_DISCLOSED_INDEX,
PROVE_RSA_OFAC_RESULT_INDEX,
PROVE_RSA_COMMITMENT_INDEX,
PROVE_RSA_BLINDED_DSC_COMMITMENT_INDEX,
PROVE_RSA_CURRENT_DATE_INDEX,
PROVE_RSA_USER_IDENTIFIER_INDEX,
PROVE_RSA_SCOPE_INDEX,
DSC_BLINDED_DSC_COMMITMENT_INDEX
} from "../../constants/contractConstants";
import { Proof } from "../types";

export function generateMockRSAProveVerifierInputs({
nullifier = "1",
revealedData_packed = ["2", "3", "4"],
older_than = ["5", "6", "7"],
pubkey_disclosed = ["0", "0", "0", "0","0", "0", "0", "0","0", "0", "0", "0","0", "0", "0", "0","0", "0", "0", "0","0", "0", "0", "0","0", "0", "0", "0","0", "0", "0", "0"],
forbidden_contries_list_packed_disclose = ["8", "9"],
ofac_result = "10",
commitment = "11",
blinded_dsc_commitment = "12",
current_date = new Date(),
user_identifier = "13",
scope = "14",
}: {
nullifier?: string,
revealedData_packed?: string[],
older_than?: string[],
pubkey_disclosed?: string[],
forbidden_contries_list_packed_disclose?: string[],
ofac_result?: string,
commitment?: string,
blinded_dsc_commitment?: string,
current_date?: Date,
user_identifier?: string,
scope?: string,
}): Proof {

let pub_signals: string[] = [];

pub_signals[PROVE_RSA_NULLIFIER_INDEX] = nullifier;
pub_signals.splice(PROVE_RSA_REVEALED_DATA_PACKED_INDEX, 0, ...revealedData_packed);
pub_signals.splice(PROVE_RSA_OLDER_THAN_INDEX, 0, ...older_than);
pub_signals.splice(PROVE_RSA_PUBKEY_DISCLOSED_INDEX, 0, ...pubkey_disclosed);
pub_signals.splice(PROVE_RSA_FORBIDDEN_COUNTRIES_LIST_PACKED_DISCLOSED_INDEX, 0, ...forbidden_contries_list_packed_disclose);
pub_signals[PROVE_RSA_OFAC_RESULT_INDEX] = ofac_result;
pub_signals[PROVE_RSA_COMMITMENT_INDEX] = commitment;
pub_signals[PROVE_RSA_BLINDED_DSC_COMMITMENT_INDEX] = blinded_dsc_commitment;
pub_signals.splice(PROVE_RSA_CURRENT_DATE_INDEX, 0, ...getDateNum(current_date));
pub_signals[PROVE_RSA_USER_IDENTIFIER_INDEX] = user_identifier;
pub_signals[PROVE_RSA_SCOPE_INDEX] = scope;

let proof: Proof = {
proof: {
a: ["1", "1"],
b: [
["1", "2"],
["3", "4"]
],
c: ["5", "6"]
},
pub_signals: pub_signals
};
return proof;
}

export function generateMockDSCVerifierInputs({
blinded_dsc_commitment = "12",
}: {
blinded_dsc_commitment?: string,
}): Proof {

let pub_signals: string[] = [];

pub_signals[DSC_BLINDED_DSC_COMMITMENT_INDEX] = blinded_dsc_commitment;

let proof: Proof = {
proof: {
a: ["1", "1"],
b: [
["1", "2"],
["3", "4"]
],
c: ["5", "6"]
},
pub_signals: pub_signals
};
return proof;
}

function getDateNum(date: Date = new Date()): string[] {

const year = date.getUTCFullYear() % 100;
const month = date.getUTCMonth() + 1;
const day = date.getUTCDate();

const dateNum = [
Math.floor(year / 10),
(year % 10),
(Math.floor(month / 10)),
(month % 10),
(Math.floor(day / 10)),
(day % 10),
];

return dateNum.map(num => num.toString());
}
126 changes: 63 additions & 63 deletions contracts/contracts/OneTimeSBT.sol
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small changes, include bug fix

Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ contract OneTimeSBT is ERC721Enumerable {
error UNEQUAL_BLINDED_DSC_COMMITMENT();
error INVALID_PROVE_PROOF();
error INVALID_DSC_PROOF();
error SBT_CAN_BE_TRANSFERED();
error SBT_CAN_NOT_BE_TRANSFERED();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not correct error message


constructor(
IVerifiersManager v,
Expand All @@ -49,17 +49,17 @@ contract OneTimeSBT is ERC721Enumerable {
// Convert the last four parameters into a valid timestamp, adding 30 years to adjust for block.timestamp starting in 1970
uint[6] memory dateNum;
for (uint i = 0; i < 6; i++) {
dateNum[i] = p_proof.pubSignals[PROVE_RSA_COMMITMENT_INDEX + i];
dateNum[i] = p_proof.pubSignals[PROVE_RSA_CURRENT_DATE_INDEX + i];
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not correct index place

}
uint currentTimestamp = getCurrentTimestamp(dateNum);
uint currentTimestamp = _getCurrentTimestamp(dateNum);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getCurrentTimestamp is used only here, so I made this function as internal and change the name of it in _camelCase


// Check that the current date is within a +/- 1 day range
if(
currentTimestamp < block.timestamp - 1 days ||
currentTimestamp > block.timestamp + 1 days
) {
revert CURRENT_DATE_NOT_VALID_RANGE();
};
revert CURRENT_DATE_NOT_IN_VALID_RANGE();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change custom error

}

// check blinded dcs
if (
Expand Down Expand Up @@ -87,7 +87,7 @@ contract OneTimeSBT is ERC721Enumerable {
for (uint256 i = 0; i < 3; i++) {
revealedData_packed[i] = p_proof.pubSignals[PROVE_RSA_REVEALED_DATA_PACKED_INDEX + i];
}
bytes memory charcodes = fieldElementsToBytes(
bytes memory charcodes = _fieldElementsToBytes(
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fieldElementsToBytes is only used here. So, I changed this function to internal and the name in _camelCase

revealedData_packed
);

Expand All @@ -100,62 +100,16 @@ contract OneTimeSBT is ERC721Enumerable {
attributes.values[4] = AttributeLibrary.getDateOfBirth(charcodes);
attributes.values[5] = AttributeLibrary.getGender(charcodes);
attributes.values[6] = AttributeLibrary.getExpiryDate(charcodes);
attributes.values[7] = AttributeLibrary.getOlderThan(charcodes);

sbtExpiration[newTokenId] = block.timestamp + 90 days;
}

function fieldElementsToBytes(
uint256[3] memory publicSignals
) public pure returns (bytes memory) {
uint8[3] memory bytesCount = [31, 31, 28];
bytes memory bytesArray = new bytes(90); // 31 + 31 + 28

uint256 index = 0;
for (uint256 i = 0; i < 3; i++) {
uint256 element = publicSignals[i];
for (uint8 j = 0; j < bytesCount[i]; j++) {
bytesArray[index++] = bytes1(uint8(element & 0xFF));
element = element >> 8;
}
}

return bytesArray;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this function later of this file


function sliceFirstThree(
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete sliceFirstThree function since it is not used in this contract

uint256[12] memory input
) public pure returns (uint256[3] memory) {
uint256[3] memory sliced;
uint[] memory olderThanAscii = new uint[](2);
olderThanAscii[0] = p_proof.pubSignals[PROVE_RSA_OLDER_THAN_INDEX];
olderThanAscii[1] = p_proof.pubSignals[PROVE_RSA_OLDER_THAN_INDEX + 1];
attributes.values[7] = _convertUintArrayToString(olderThanAscii);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

olderThan is now not in revealedData_packed, it is in older_than data field, so I changed this like this


for (uint256 i = 0; i < 3; i++) {
sliced[i] = input[i];
}

return sliced;
}

function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId,
uint256 batchSize
) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId, batchSize);
if (from != address(0)) {
revert SBT_CAN_BE_TRANSFERED();
}
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this function to later of this file


function isExpired(string memory date) public view returns (bool) {
if (isAttributeEmpty(date)) {
return false; // this is disregarded anyway in the next steps
}
uint256 expiryDate = formatter.dateToUnixTimestamp(date);

return block.timestamp > expiryDate;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this function to later of this file

sbtExpiration[newTokenId] = block.timestamp + 90 days;
}

// get functions
function getIssuingStateOf(
uint256 _tokenId
) public view returns (string memory) {
Expand Down Expand Up @@ -205,15 +159,51 @@ contract OneTimeSBT is ERC721Enumerable {
uint256 _tokenId
) public view returns (bool) {
uint256 expirationDate = sbtExpiration[_tokenId];
if (expirationDate < block.timestamp) {
return true;
return expirationDate > block.timestamp;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expiration > block.timestamp is the correct validation


// internal functions
function _convertUintArrayToString(uint[] memory input) internal pure returns (string memory) {
bytes memory bytesArray = new bytes(input.length);
for (uint i = 0; i < input.length; i++) {
bytesArray[i] = bytes1(uint8(input[i]));
}
return false;
return string(bytesArray);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add new util function which is used for older than.
Since older than is two ascii code which represent older than age, read uint array and just be able to convert in string number with string()


function _fieldElementsToBytes(
uint256[3] memory publicSignals
) internal pure returns (bytes memory) {
uint8[3] memory bytesCount = [31, 31, 28];
bytes memory bytesArray = new bytes(90); // 31 + 31 + 28

uint256 index = 0;
for (uint256 i = 0; i < 3; i++) {
uint256 element = publicSignals[i];
for (uint8 j = 0; j < bytesCount[i]; j++) {
bytesArray[index++] = bytes1(uint8(element & 0xFF));
element = element >> 8;
}
}

return bytesArray;
}

function getCurrentTimestamp(
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId,
uint256 batchSize
) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId, batchSize);
if (from != address(0)) {
revert SBT_CAN_NOT_BE_TRANSFERED();
}
}

function _getCurrentTimestamp(
uint256[6] memory dateNum
) public view returns (uint256) {
) internal view returns (uint256) {
string memory date = "";
for (uint i = 0; i < 6; i++) {
date = string(
Expand All @@ -224,6 +214,7 @@ contract OneTimeSBT is ERC721Enumerable {
return currentTimestamp;
}

// functions for calculate tokenURI
function isAttributeEmpty(
string memory attribute
) private pure returns (bool) {
Expand Down Expand Up @@ -253,6 +244,15 @@ contract OneTimeSBT is ERC721Enumerable {
return baseURI;
}

function isExpired(string memory date) public view returns (bool) {
if (isAttributeEmpty(date)) {
return false; // this is disregarded anyway in the next steps
}
uint256 expiryDate = formatter.dateToUnixTimestamp(date);

return block.timestamp > expiryDate;
}

function formatAttribute(
string memory traitType,
string memory value
Expand Down
3 changes: 3 additions & 0 deletions contracts/contracts/constants/constants.sol
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compiler get angry with this, so I changed

Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

uint256 constant ATTRIBUTE_ISSUING_STATE_INDEX = 0;
uint256 constant ATTRIBUTE_NAME_INDEX = 1;
uint256 constant ATTRIBUTE_PASSPORT_NUMBER_INDEX = 2;
Expand Down
9 changes: 0 additions & 9 deletions contracts/contracts/libraries/AttributeLibrary.sol
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to read older than from revealedData_Packed anymore.

Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,6 @@ library AttributeLibrary {
return extractAttribute(charcodes, EXPIRY_DATE_START, EXPIRY_DATE_END);
}

/**
* @notice Extracts the "older than" attribute from the charcodes.
* @param charcodes The bytes array containing packed attribute data.
* @return The "older than" value as a string.
*/
function getOlderThan(bytes memory charcodes) internal pure returns (string memory) {
return extractAttribute(charcodes, OLDER_THAN_START, OLDER_THAN_END);
}

/**
* @notice Extracts a substring from the charcodes based on start and end indices.
* @param charcodes The bytes array containing packed attribute data.
Expand Down
Loading
Loading