Hi,
This works for my use cases for e-commerce and social media:
I was concerned on two things; lack of any timestamps and the JSON-LD files lack of security as they can be stored on centralised storages then changed at will.
I believe this helps bolster security by “grounding” the JSON-LD to the blockchain a lot more, by ensuring that any updates have emitted together the msg.sender and uri (hashed) link.
event DAOUpdate(
address indexed sender,
address indexed dao,
string name,
string description,
string governanceURI
);
event MemberUpdate(
address indexed sender,
address indexed dao,
address indexed member,
string memberURI
);
event ProposalUpdate(
address indexed sender,
address indexed dao,
string indexed proposalId,
string proposalURI
);
event ActivityLogUpdate(
address indexed sender,
address indexed dao,
string indexed activityId,
string activityLogURI
);
This means breaking up the updates to their own JSON-LD files. So there is an individual Member JSON-LD Schema, Proposal JSON-LD Schema file, individual Activity Log JSON-LD Schema, rather than having them collected in bigger JSON-LD files.
Every update is posted out by calling their corresponding singleton contract function; dao, memberUpdate, proposalUpdate, or activityLogUpdate with the msg.sender address and uri link.
function dao(
address calldata dao,
string calldata name,
string calldata description,
string calldata governanceURI
) public {
emit DAOUpdate(msg.sender, daos, name, description, governanceURI);
}
function memberUpdate(
address calldata dao,
address member,
string calldata memberURI
) public {
emit MemberUpdate(msg.sender, daos, member, memberURI);
}
function proposalUpdate(
address[] calldata daos,
string calldata proposalId,
string calldata proposalURI
) public {
emit ProposalUpdate(msg.sender, daos, proposalId, proposalURI);
}
function activityLogUpdate(
address calldata dao,
string calldata activityId,
string calldata activityLogURI
) public {
emit ActivityLogUpdate(msg.sender, daos, activityId, activityLogURI);
}
This solves my timestamp issue as every emitted event has a block number it came from. This can be retrieved and block numbers converted to timestamps using a web3 library.
Can validate off-line too that the posted uri hash matches the content that it points to (depending on recognised link formats like ipfs). As mentioned, each posted uri link is emitted with the msg.sender address, thus we know what account made the change. Off-line processing can validate if that account is a DAO member etc.
With the use of event filters from a web3 library, all proposals’ updates for a DAO can be retrieved and sorted by block number, hence just the latest changes can be returned etc. Similarly, all or individual proposals, members and activity logs can be retrieved using any or combination of their event’s indexed parameters.
So now I have a fourth version:
contract ERC4824v4 {
event SchemaUpdate(
address indexed sender,
string indexed indexedSchemaURI,
string name,
string description,
string schemaURI
);
event DAOUpdate(
address indexed sender,
address indexed dao,
string name,
string description,
string governanceURI
);
event MemberUpdate(
address indexed sender,
address indexed dao,
address indexed member,
string memberURI
);
event ProposalUpdate(
address indexed sender,
address indexed dao,
string indexed proposalId,
string proposalURI
);
event ActivityLogUpdate(
address indexed sender,
address indexed dao,
string indexed activityId,
string activityLogURI
);
function schemaUpdate(
string calldata name,
string calldata description,
string calldata schemaURI
) public {
emit SchemaUpdate(msg.sender, schemaURI, name, description, schemaURI);
}
function daoUpdate(
address dao,
string calldata name,
string calldata description,
string calldata governanceURI
) public {
emit DAOUpdate(msg.sender, dao, name, description, governanceURI);
}
function memberUpdate(
address dao,
address member,
string calldata memberURI
) public {
emit MemberUpdate(msg.sender, dao, member, memberURI);
}
function proposalUpdate(
address dao,
string calldata proposalId,
string calldata proposalURI
) public {
emit ProposalUpdate(msg.sender, dao, proposalId, proposalURI);
}
function activityLogUpdate(
address dao,
string calldata activityId,
string calldata activityLogURI
) public {
emit ActivityLogUpdate(msg.sender, dao, activityId, activityLogURI);
}
}
Edit: Addtional event to handle schema updates
event SchemaUpdate(
address indexed sender,
string indexed indexedSchemaURI,
string name,
string description,
string schemaURI
);