141 lines
3.6 KiB
Solidity
141 lines
3.6 KiB
Solidity
|
|
// SPDX-License-Identifier: MIT
|
||
|
|
pragma solidity ^0.8.24;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @title Billing
|
||
|
|
* @dev Smart contract for tracking billing and resource usage costs
|
||
|
|
*/
|
||
|
|
contract Billing {
|
||
|
|
struct UsageRecord {
|
||
|
|
string resourceId;
|
||
|
|
string resourceType;
|
||
|
|
uint256 startTime;
|
||
|
|
uint256 endTime;
|
||
|
|
uint256 cost; // Cost in smallest unit (wei-like)
|
||
|
|
string currency;
|
||
|
|
address billedTo;
|
||
|
|
}
|
||
|
|
|
||
|
|
struct Bill {
|
||
|
|
address billedTo;
|
||
|
|
uint256 periodStart;
|
||
|
|
uint256 periodEnd;
|
||
|
|
uint256 totalCost;
|
||
|
|
string currency;
|
||
|
|
bool paid;
|
||
|
|
uint256 paidAt;
|
||
|
|
}
|
||
|
|
|
||
|
|
mapping(string => UsageRecord[]) public resourceUsage;
|
||
|
|
mapping(address => Bill[]) public bills;
|
||
|
|
mapping(string => uint256) public resourceCosts;
|
||
|
|
|
||
|
|
event UsageRecorded(
|
||
|
|
string indexed resourceId,
|
||
|
|
address indexed billedTo,
|
||
|
|
uint256 cost,
|
||
|
|
uint256 timestamp
|
||
|
|
);
|
||
|
|
|
||
|
|
event BillGenerated(
|
||
|
|
address indexed billedTo,
|
||
|
|
uint256 billId,
|
||
|
|
uint256 totalCost,
|
||
|
|
uint256 periodStart,
|
||
|
|
uint256 periodEnd
|
||
|
|
);
|
||
|
|
|
||
|
|
event BillPaid(
|
||
|
|
address indexed billedTo,
|
||
|
|
uint256 billId,
|
||
|
|
uint256 paidAt
|
||
|
|
);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @dev Record resource usage and cost
|
||
|
|
*/
|
||
|
|
function recordUsage(
|
||
|
|
string memory resourceId,
|
||
|
|
string memory resourceType,
|
||
|
|
uint256 startTime,
|
||
|
|
uint256 endTime,
|
||
|
|
uint256 cost,
|
||
|
|
string memory currency,
|
||
|
|
address billedTo
|
||
|
|
) public returns (bool) {
|
||
|
|
UsageRecord memory record = UsageRecord({
|
||
|
|
resourceId: resourceId,
|
||
|
|
resourceType: resourceType,
|
||
|
|
startTime: startTime,
|
||
|
|
endTime: endTime,
|
||
|
|
cost: cost,
|
||
|
|
currency: currency,
|
||
|
|
billedTo: billedTo
|
||
|
|
});
|
||
|
|
|
||
|
|
resourceUsage[resourceId].push(record);
|
||
|
|
resourceCosts[resourceId] += cost;
|
||
|
|
|
||
|
|
emit UsageRecorded(resourceId, billedTo, cost, block.timestamp);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @dev Generate a bill for a billing period
|
||
|
|
*/
|
||
|
|
function generateBill(
|
||
|
|
address billedTo,
|
||
|
|
uint256 periodStart,
|
||
|
|
uint256 periodEnd
|
||
|
|
) public returns (uint256) {
|
||
|
|
uint256 totalCost = 0;
|
||
|
|
|
||
|
|
// Calculate total cost from all usage records in period
|
||
|
|
// This is simplified - actual implementation would aggregate all resources
|
||
|
|
|
||
|
|
uint256 billId = bills[billedTo].length;
|
||
|
|
Bill memory bill = Bill({
|
||
|
|
billedTo: billedTo,
|
||
|
|
periodStart: periodStart,
|
||
|
|
periodEnd: periodEnd,
|
||
|
|
totalCost: totalCost,
|
||
|
|
currency: "USD",
|
||
|
|
paid: false,
|
||
|
|
paidAt: 0
|
||
|
|
});
|
||
|
|
|
||
|
|
bills[billedTo].push(bill);
|
||
|
|
|
||
|
|
emit BillGenerated(billedTo, billId, totalCost, periodStart, periodEnd);
|
||
|
|
return billId;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @dev Mark a bill as paid
|
||
|
|
*/
|
||
|
|
function payBill(address billedTo, uint256 billId) public {
|
||
|
|
require(billId < bills[billedTo].length, "Bill does not exist");
|
||
|
|
require(!bills[billedTo][billId].paid, "Bill already paid");
|
||
|
|
|
||
|
|
bills[billedTo][billId].paid = true;
|
||
|
|
bills[billedTo][billId].paidAt = block.timestamp;
|
||
|
|
|
||
|
|
emit BillPaid(billedTo, billId, block.timestamp);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @dev Get total cost for a resource
|
||
|
|
*/
|
||
|
|
function getResourceTotalCost(string memory resourceId) public view returns (uint256) {
|
||
|
|
return resourceCosts[resourceId];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @dev Get all bills for an address
|
||
|
|
*/
|
||
|
|
function getBills(address billedTo) public view returns (Bill[] memory) {
|
||
|
|
return bills[billedTo];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|