Contract Name:
BlazeItOnSonic
Contract Source Code:
File 1 of 1 : BlazeItOnSonic
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IBlazeToken {
function burnFrom(address account, uint256 amount) external;
}
/**
* @title BlazeItOnSonic A Timestamp Service
* @dev Contract for submitting documents with timestamp and burning Blaze tokens
*/
contract BlazeItOnSonic {
IBlazeToken public blazeToken;
uint256 public baseBurnAmount = 13 * (10 ** 18); // Starting burn amount for 1 document
uint256 public burnIncrementPercentage = 15; // Default increment percentage for additional documents
address public owner;
struct Submission {
string title;
string comments;
string fileType;
string tags;
uint256 timestamp;
address submitter;
uint256 expiry;
}
mapping(bytes32 => Submission) public submissions;
mapping(address => bytes32[]) public userSubmissions;
mapping(bytes32 => bytes32[]) public titleToHashes;
event DocumentSubmitted(address indexed submitter, bytes32 indexed hash, string title, string comments, uint256 timestamp);
event BurnAmountUpdated(uint256 newBurnAmount);
event BurnIncrementPercentageUpdated(uint256 newPercentage);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
modifier onlyOwner() {
require(msg.sender == owner, "Caller is not the owner");
_;
}
constructor(address _blazeToken) {
blazeToken = IBlazeToken(_blazeToken);
owner = msg.sender;
}
/**
* @dev Transfers ownership of the contract to a new owner
* @param newOwner The address of the new owner
*/
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0), "New owner is the zero address");
require(newOwner != owner, "New owner is the same as the current owner");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
/**
* @dev Updates the base burn amount for one document
* @param _newBurnAmount The new base burn amount
*/
function setBaseBurnAmount(uint256 _newBurnAmount) external onlyOwner {
baseBurnAmount = _newBurnAmount;
emit BurnAmountUpdated(_newBurnAmount);
}
/**
* @dev Updates the burn increment percentage for additional documents
* @param _newPercentage The new increment percentage
*/
function setBurnIncrementPercentage(uint256 _newPercentage) external onlyOwner {
burnIncrementPercentage = _newPercentage;
emit BurnIncrementPercentageUpdated(_newPercentage);
}
/**
* @dev Calculates the total burn amount based on the number of documents
* @param documentCount The number of documents to be submitted
* @return totalBurnAmount The total burn amount required
*/
function calculateBurnAmount(uint256 documentCount) public view returns (uint256) {
require(documentCount > 0 && documentCount <= 5, "Document count must be between 1 and 5");
uint256 totalBurnAmount = baseBurnAmount;
for (uint256 i = 1; i < documentCount; i++) {
totalBurnAmount += (totalBurnAmount * burnIncrementPercentage) / 100;
}
return totalBurnAmount;
}
/**
* @dev Submits a single document with metadata and burns the required tokens in one transaction
* @param _title The title of the document
* @param _comments Additional comments for the document
* @param _fileType The file type of the document
* @param _tags Tags associated with the document
* @param _expiry Expiry timestamp for the document
* @return documentHash The hash of the submitted document
*/
function burnAndSubmitDocument(string memory _title, string memory _comments, string memory _fileType, string memory _tags, uint256 _expiry) external returns (bytes32) {
uint256 burnAmount = calculateBurnAmount(1);
blazeToken.burnFrom(msg.sender, burnAmount);
bytes32 documentHash = keccak256(abi.encodePacked(_title, _comments, _fileType, _tags, msg.sender, block.timestamp, block.number));
submissions[documentHash] = Submission({
title: _title,
comments: _comments,
fileType: _fileType,
tags: _tags,
timestamp: block.timestamp,
submitter: msg.sender,
expiry: _expiry
});
userSubmissions[msg.sender].push(documentHash);
titleToHashes[keccak256(abi.encodePacked(_title))].push(documentHash);
emit DocumentSubmitted(msg.sender, documentHash, _title, _comments, block.timestamp);
return documentHash;
}
/**
* @dev Submits multiple documents in a single transaction and burns the required tokens
* @param _titles Array of document titles
* @param _comments Array of document comments
* @param _fileTypes Array of document file types
* @param _tags Array of document tags
* @param _expiries Array of expiry timestamps
*/
function burnAndSubmitMultipleDocuments(string[] memory _titles, string[] memory _comments, string[] memory _fileTypes, string[] memory _tags, uint256[] memory _expiries) external {
uint256 documentCount = _titles.length;
require(documentCount > 0 && documentCount <= 5, "Can only submit up to 5 documents at a time");
require(_titles.length == _comments.length && _comments.length == _fileTypes.length && _fileTypes.length == _tags.length && _tags.length == _expiries.length, "Mismatched input lengths");
uint256 burnAmount = calculateBurnAmount(documentCount);
blazeToken.burnFrom(msg.sender, burnAmount);
for (uint256 i = 0; i < documentCount; i++) {
bytes32 documentHash = keccak256(abi.encodePacked(_titles[i], _comments[i], _fileTypes[i], _tags[i], msg.sender, block.timestamp, block.number));
submissions[documentHash] = Submission({
title: _titles[i],
comments: _comments[i],
fileType: _fileTypes[i],
tags: _tags[i],
timestamp: block.timestamp,
submitter: msg.sender,
expiry: _expiries[i]
});
userSubmissions[msg.sender].push(documentHash);
titleToHashes[keccak256(abi.encodePacked(_titles[i]))].push(documentHash);
emit DocumentSubmitted(msg.sender, documentHash, _titles[i], _comments[i], block.timestamp);
}
}
/**
* @dev Verifies a document by its hash
* @param _hash The hash of the document to verify
* @return title The title of the document
* @return comments The comments of the document
* @return fileType The file type of the document
* @return tags The tags of the document
* @return timestamp The timestamp of the document submission
* @return submitter The address of the submitter
* @return expiry The expiry timestamp of the document
*/
function verifyDocument(bytes32 _hash) external view returns (string memory title, string memory comments, string memory fileType, string memory tags, uint256 timestamp, address submitter, uint256 expiry) {
Submission memory submission = submissions[_hash];
require(submission.timestamp != 0, "Document not found");
return (submission.title, submission.comments, submission.fileType, submission.tags, submission.timestamp, submission.submitter, submission.expiry);
}
/**
* @dev Retrieves all submissions by a specific user
* @param _user The address of the user
* @return Array of document hashes submitted by the user
*/
function getUserSubmissions(address _user) external view returns (bytes32[] memory) {
return userSubmissions[_user];
}
/**
* @dev Retrieves all submissions by title
* @param _title The title of the documents
* @return Array of document hashes matching the title
*/
function getSubmissionsByTitle(string memory _title) external view returns (bytes32[] memory) {
return titleToHashes[keccak256(abi.encodePacked(_title))];
}
/**
* @dev Retrieves submissions by a user within a specific time range
* @param _user The address of the user
* @param _startTime The start of the time range
* @param _endTime The end of the time range
* @return Array of document hashes submitted by the user within the time range
*/
function getUserSubmissionsByTimestamp(address _user, uint256 _startTime, uint256 _endTime) external view returns (bytes32[] memory) {
bytes32[] memory allSubmissions = userSubmissions[_user];
uint256 count = 0;
for (uint256 i = 0; i < allSubmissions.length; i++) {
Submission memory submission = submissions[allSubmissions[i]];
if (submission.timestamp >= _startTime && submission.timestamp <= _endTime) {
count++;
}
}
bytes32[] memory filteredSubmissions = new bytes32[](count);
uint256 index = 0;
for (uint256 i = 0; i < allSubmissions.length; i++) {
Submission memory submission = submissions[allSubmissions[i]];
if (submission.timestamp >= _startTime && submission.timestamp <= _endTime) {
filteredSubmissions[index] = allSubmissions[i];
index++;
}
}
return filteredSubmissions;
}
}