implement Access Control:
contract AccessControl {
event GrantRole(bytes32 indexed role, address indexed account);
event RevokeRole(bytes32 indexed role, address indexed account);
mapping(bytes32 => mapping(address => bool)) public roles;
bytes32 public constant ADMIN = keccak256(abi.encodePacked("ADMIN"));
//can make it private and constant
bytes32 public constant USER = keccak256(abi.encodePacked("USER"));
modifier onlyRole(bytes32 _role){
require(roles[_role][msg.sender]);
_;
}
constructor() {
roles[ADMIN][msg.sender] = true;
}
}
Hashing the name of the role to bytes32, so even the name is really long it can still fit in the bytes32, saving gas.
selfdestruct(payable(msg.sender));
⇒ with send eth to the msg.sender as well.
deconstructing a struct (lol):
https://solidity-by-example.org/structs/
struct Transaction {
address to;
uint value;
bytes data;
bool executed;
}
Transaction[] public transactions;
function getApprovalCount(uint _txId) private view returns(uint) {
uint count;
for (uint i; i < owners.length; i++) {
address owner = owners[i];
if(approved[_txId][owner]){
count++;
}
}
return count;
}
function execute(uint _txId) onlyOwner txExists(_txId) notExecuted(_txId) external {
uint approval = getApprovalCount(_txId);
Transaction storage transaction = transactions[_txId];
require(approval >= required, "vote not enough");
//execute the function
(bool success, bytes memory data) = transaction.to.call{value: transaction.value}(
transaction.data
);
require(success, "transaction failed");
transaction.executed = true;
//emit Execute
emit Execute(_txId);
}