Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Contract Name:
JustFrens
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 2000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-1.0 pragma solidity 0.8.9; import "@openzeppelin/contracts/metatx/ERC2771Context.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract JustFrens is Ownable, ERC2771Context { mapping(address => mapping(address => bool)) public followings; event Followed(address indexed follower, address indexed followee); event Unfollowed(address indexed follower, address indexed followee); constructor(address _trustedForwarder) ERC2771Context(_trustedForwarder) {} function follow(address followee) external { address follower = _msgSender(); require(follower != followee, "self"); _follow(follower, followee); } function bulkFollow(address[] calldata followees) external { address follower = _msgSender(); for (uint256 index = 0; index < followees.length; index++) { address followee = followees[index]; _follow(follower, followee); } } function _follow(address follower, address followee) internal { followings[follower][followee] = true; emit Followed(follower, followee); } function unfollow(address followee) external { address follower = _msgSender(); followings[follower][followee] = false; emit Unfollowed(follower, followee); } function setTrustedForwarder(address _forwarder) external onlyOwner { ERC2771Context._trustedForwarder = _forwarder; } function _msgData() internal view override(Context, ERC2771Context) returns (bytes calldata) { return ERC2771Context._msgData(); } function _msgSender() internal view override(Context, ERC2771Context) returns (address sender) { return ERC2771Context._msgSender(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (metatx/ERC2771Context.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Context variant with ERC2771 support. */ abstract contract ERC2771Context is Context { address internal _trustedForwarder; constructor(address trustedForwarder) { _trustedForwarder = trustedForwarder; } function isTrustedForwarder(address forwarder) public view virtual returns (bool) { return forwarder == _trustedForwarder; } function _msgSender() internal view virtual override returns (address sender) { if (isTrustedForwarder(msg.sender)) { // The assembly code is more direct than the Solidity version using `abi.decode`. assembly { sender := shr(96, calldataload(sub(calldatasize(), 20))) } } else { return super._msgSender(); } } function _msgData() internal view virtual override returns (bytes calldata) { if (isTrustedForwarder(msg.sender)) { return msg.data[:msg.data.length - 20]; } else { return super._msgData(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
{ "optimizer": { "enabled": true, "runs": 2000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_trustedForwarder","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"follower","type":"address"},{"indexed":true,"internalType":"address","name":"followee","type":"address"}],"name":"Followed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"follower","type":"address"},{"indexed":true,"internalType":"address","name":"followee","type":"address"}],"name":"Unfollowed","type":"event"},{"inputs":[{"internalType":"address[]","name":"followees","type":"address[]"}],"name":"bulkFollow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"followee","type":"address"}],"name":"follow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"followings","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_forwarder","type":"address"}],"name":"setTrustedForwarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"followee","type":"address"}],"name":"unfollow","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5060405161093038038061093083398101604081905261002f91610108565b8061004061003b610066565b61007f565b600180546001600160a01b0319166001600160a01b039290921691909117905550610138565b600061007a6100cf60201b6105201760201c565b905090565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001546000906001600160a01b03163314156100f2575060131936013560601c90565b61007a61010460201b61056b1760201c565b3390565b60006020828403121561011a57600080fd5b81516001600160a01b038116811461013157600080fd5b9392505050565b6107e9806101476000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063715018a611610076578063da7422281161005b578063da74222814610158578063f2fde38b1461016b578063fc8fd73f1461017e57600080fd5b8063715018a6146101355780638da5cb5b1461013d57600080fd5b8063015a4ead146100a85780634dbf27cc146100bd578063572b6c05146100d05780635dbcdff914610107575b600080fd5b6100bb6100b636600461065a565b610191565b005b6100bb6100cb36600461065a565b6101fb565b6100f26100de36600461065a565b6001546001600160a01b0391821691161490565b60405190151581526020015b60405180910390f35b6100f261011536600461067c565b600260209081526000928352604080842090915290825290205460ff1681565b6100bb610282565b6000546040516001600160a01b0390911681526020016100fe565b6100bb61016636600461065a565b610307565b6100bb61017936600461065a565b6103ba565b6100bb61018c3660046106af565b6104bb565b600061019b61056f565b6001600160a01b03808216600081815260026020908152604080832094881680845294909152808220805460ff1916905551939450919290917f25b48012798806863072289354ed0b3849b73152482d9c6694e5cbb35f38d5e391a35050565b600061020561056f565b9050816001600160a01b0316816001600160a01b031614156102745760405162461bcd60e51b815260040161026b9060208082526004908201527f73656c6600000000000000000000000000000000000000000000000000000000604082015260600190565b60405180910390fd5b61027e8183610579565b5050565b61028a61056f565b6001600160a01b03166102a56000546001600160a01b031690565b6001600160a01b0316146102fb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161026b565b61030560006105d6565b565b61030f61056f565b6001600160a01b031661032a6000546001600160a01b031690565b6001600160a01b0316146103805760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161026b565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6103c261056f565b6001600160a01b03166103dd6000546001600160a01b031690565b6001600160a01b0316146104335760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161026b565b6001600160a01b0381166104af5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161026b565b6104b8816105d6565b50565b60006104c561056f565b905060005b8281101561051a5760008484838181106104e6576104e6610724565b90506020020160208101906104fb919061065a565b90506105078382610579565b508061051281610753565b9150506104ca565b50505050565b6001546000906001600160a01b031633141561056157507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b905090565b3390565b6000610566610520565b6001600160a01b03808316600081815260026020908152604080832094861680845294909152808220805460ff19166001179055517f6178e95c138f06036cdc07a49ed6a3d23008969fa143baeceb037ebae22e8d149190a35050565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80356001600160a01b038116811461065557600080fd5b919050565b60006020828403121561066c57600080fd5b6106758261063e565b9392505050565b6000806040838503121561068f57600080fd5b6106988361063e565b91506106a66020840161063e565b90509250929050565b600080602083850312156106c257600080fd5b823567ffffffffffffffff808211156106da57600080fd5b818501915085601f8301126106ee57600080fd5b8135818111156106fd57600080fd5b8660208260051b850101111561071257600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156107ac577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea2646970667358221220b2b51e8882a54365d1164b5d3bfddd3f4bc43d309fdc8f5439b534bf4334c14664736f6c6343000809003300000000000000000000000086c80a8aa58e0a4fa09a69624c31ab2a6cad56b8
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000086c80a8aa58e0a4fa09a69624c31ab2a6cad56b8
-----Decoded View---------------
Arg [0] : _trustedForwarder (address): 0x86c80a8aa58e0a4fa09a69624c31ab2a6cad56b8
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000086c80a8aa58e0a4fa09a69624c31ab2a6cad56b8
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.