diff --git a/README.md b/README.md index d7d4acf7b..45ed3acb7 100644 --- a/README.md +++ b/README.md @@ -1,152 +1,42 @@ +# TrustShop -# ๐Ÿ—๏ธ Scaffold-Base ๐Ÿ”ต +## The problem it solves -

- Documentation | - Website -

+TrustShop tackles online marketplace woes: lack of trust, low-quality reviews, and unclear transactions. By rewarding honest reviews with TST tokens on the blockchain, TrustShop incentivizes user participation, promotes product quality, and fosters a secure and transparent shopping experience. -Scaffold-Base is a fork of Scaffold-ETH-2 ready to ship to Base. This fork provides native support for Base and Base Sepolia testnet, direct access to the Base faucets, and [coinbase-sdk-wallet](https://github.com/coinbase/coinbase-wallet-sdk/) beta preconfigured which allows 4337 account abstraction using passkeys. +## Technologies we used -![Scaffold-Base)](https://github.com/damianmarti/se-2/assets/466652/eac667a7-68fb-4f69-a427-126f7de4114d) +- Ethereum +- BASE +- Solidity +- Next.js +- Hardhat +- Scaffold-Base +- EAS -We highly recommend the Scaffold-ETH-2 docs as the primary guideline. +## How to use it -# (forked from ๐Ÿ— Scaffold-ETH-2) +- Enter the app and add connect your wallet. +- Make sure you have enough ETH to purchase. +- Once you have bought and paid, you will directed to Review Purchases page, where you drop your review and attest. -๐Ÿงช An open-source, up-to-date toolkit for building decentralized applications (dapps) on the Ethereum blockchain. It's designed to make it easier for developers to create and deploy smart contracts and build user interfaces that interact with those contracts. +## Our contracts -โš™๏ธ Built using NextJS, RainbowKit, Hardhat, Wagmi, Viem, and Typescript. +1. TrustScriptShop contract: -- โœ… **Contract Hot Reload**: Your frontend auto-adapts to your smart contract as you edit it. -- ๐Ÿช **[Custom hooks](https://docs.scaffoldeth.io/hooks/)**: Collection of React hooks wrapper around [wagmi](https://wagmi.sh/) to simplify interactions with smart contracts with typescript autocompletion. -- ๐Ÿงฑ [**Components**](https://docs.scaffoldeth.io/components/): Collection of common web3 components to quickly build your frontend. -- ๐Ÿ”ฅ **Burner Wallet & Local Faucet**: Quickly test your application with a burner wallet and local faucet. -- ๐Ÿ” **Integration with Wallet Providers**: Connect to different wallet providers and interact with the Ethereum network. + 1. An onchain shop built on base for sellers to sell product and get paid via ETH. + 2. What is unique is that as buyer make a purchase they are redirected to attest what is being bought. + 3. Buyers are immediatedly credited with TST token as a thank you for attesting a product bought. -![Debug Contracts tab](https://github.com/damianmarti/se-2/assets/466652/672d178c-38c9-4c9a-953d-d36acf08f3cd) +2. TrustScriptProductReviewAttester contract: -## Requirements + 1. Handles the submission of the review. + 2. Stores attestation as Attestation UID which can be view on base-sepolia.easscan.org. -Before you begin, you need to install the following tools: +3. TrustScriptToken contract: -- [Node (>= v18.17)](https://nodejs.org/en/download/) -- Yarn ([v1](https://classic.yarnpkg.com/en/docs/install/) or [v2+](https://yarnpkg.com/getting-started/install)) -- [Git](https://git-scm.com/downloads) + 1. Store of the Token that is being minted after a buyer successfully attest their review. -## Quickstart +## Future use-case implementation -To get started with Scaffold-Base, follow the steps below: - -1. Clone this repo & install dependencies - -``` -git clone https://github.com/BuidlGuidl/scaffold-base -cd scaffold-base -yarn install -``` - -2. Run a local network in the first terminal: - -``` -yarn chain -``` - -This command starts a local Ethereum network using Hardhat. The network runs on your local machine and can be used for testing and development. You can customize the network configuration in `hardhat.config.ts`. - -3. On a second terminal, deploy the test contract: - -``` -yarn deploy -``` - -This command deploys a test smart contract to the local network. The contract is located in `packages/hardhat/contracts` and can be modified to suit your needs. The `yarn deploy` command uses the deploy script located in `packages/hardhat/deploy` to deploy the contract to the network. You can also customize the deploy script. - -4. On a third terminal, start your NextJS app: - -``` -yarn start -``` - -Visit your app on: `http://localhost:3000`. You can interact with your smart contract using the `Debug Contracts` page. You can tweak the app config in `packages/nextjs/scaffold.config.ts`. - -**What's next**: - -- Edit your smart contract `YourContract.sol` in `packages/hardhat/contracts` -- Edit your frontend homepage at `packages/nextjs/app/page.tsx`. For guidance on [routing](https://nextjs.org/docs/app/building-your-application/routing/defining-routes) and configuring [pages/layouts](https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts) checkout the Next.js documentation. -- Edit your deployment scripts in `packages/hardhat/deploy` -- Edit your smart contract test in: `packages/hardhat/test`. To run test use `yarn hardhat:test` - - -Redeploy your contracts: - -``` -yarn deploy --reset -``` - - -# ๐Ÿ”ต Deploy to Base - - -When you are ready to deploy to Base, generate a deployer account: - -``` -yarn generate -``` - - - -Fund the deployer account with ETH on Base at: - -``` -yarn account -``` - - -Deploy to Base: - -``` -yarn deploy --network base -``` - - -Set your target network to Base: - -> Change "chains.hardhat" to "chains.base" in targetNetworks from `scaffold.config.ts` in `packages/nextjs` - - -Deploy your app to Vercel: - -``` -yarn vercel:yolo --prod -``` - -# ๐Ÿฝ๏ธ Fork Mainnet Base - -> stop your `yarn chain` - -``` - -yarn fork - -``` - -(now your local hardhat chain is a fork of Base and you can talk to forked Base contracts) - -# Coinbase Smart Wallet - -Coinbase Smart Wallet will be shown automatically when [scaffold.config.ts](https://github.com/BuidlGuidl/scaffold-base/blob/main/packages/nextjs/scaffold.config.ts) `targetNetworks` contains the network ***baseSepolia***. - -Since [coinbase beta sdk connector](https://github.com/coinbase/coinbase-wallet-sdk/blob/master/packages/wallet-sdk/docs/v4_with_wagmi.md) for now only works with Base Sepolia. - -For interacting with contracts, you can nicely use [scaffold-eth custom hooks](https://docs.scaffoldeth.io/hooks/) (wrappers around wagmi) or wagmi hooks directly without needing to change anything. - -## Documentation - -Visit our [docs](https://docs.scaffoldeth.io) to learn how to start building with Scaffold-ETH 2. - -To know more about its features, check out our [website](https://scaffoldeth.io). - -## Contributing - -Please see [CONTRIBUTING.MD](https://github.com/scaffold-eth/scaffold-eth-2/blob/main/CONTRIBUTING.md) for more information and guidelines for contributing to Scaffold-ETH 2. +We would want Attestation to be done after Product has been recived hence the satisfaction of a buyer is fully earned , possible the attestion is given a period before the attester is verifed to be allowed to attest based on product delivery. diff --git a/package.json b/package.json index 68a3aca9b..908db48a2 100644 --- a/package.json +++ b/package.json @@ -41,5 +41,9 @@ }, "resolutions": { "@coinbase/wallet-sdk": "4.0.0-beta.7" + }, + "dependencies": { + "@ethereum-attestation-service/eas-sdk": "^2.3.0", + "ethers": "^6.13.1" } } diff --git a/packages/hardhat/contracts/TrustScriptProductReviewAttester.sol b/packages/hardhat/contracts/TrustScriptProductReviewAttester.sol new file mode 100644 index 000000000..af28e0b54 --- /dev/null +++ b/packages/hardhat/contracts/TrustScriptProductReviewAttester.sol @@ -0,0 +1,58 @@ +//SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import { IEAS, AttestationRequest, AttestationRequestData } from "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol"; +import { NO_EXPIRATION_TIME, EMPTY_UID } from "@ethereum-attestation-service/eas-contracts/contracts/Common.sol"; + +/// @title TrustScriptProductReviewAttester +/// @notice Ethereum Attestation Service - Example +contract TrustScriptProductReviewAttester { + // The address of the global EAS contract. + IEAS public immutable eas; + bytes32 public immutable productReviewSchemaUID; + + error InvalidEAS(); + + /// @notice Creates a new TrustScriptProductReviewAttester instance. + /// @param easAddress The address of the global EAS contract. + /// @param _productReviewSchemaUID The UID of the ProductReview schema. + constructor(IEAS easAddress, bytes32 _productReviewSchemaUID) { + if (address(easAddress) == address(0)) { + revert InvalidEAS(); + } + + eas = easAddress; + productReviewSchemaUID = _productReviewSchemaUID; + } + + /// @notice Attests to a schema that receives a ProductReview parameter. + /// @param productId The uint256 value to pass to to the resolver. + /// @param buyerAddress The address value to pass to to the resolver. + /// @param review The string value to pass to to the resolver. + /// @param sellerAddress The address value to pass to to the resolver. + /// @return attestationUID The UID of the new attestation. + function attestProductReview( + uint256 productId, + address buyerAddress, + string memory review, + address sellerAddress + ) external returns (bytes32 attestationUID) { + // return + // eas.attest( + // AttestationRequest({ + // schema: productReviewSchemaUID, + // data: AttestationRequestData({ + // recipient: sellerAddress, + // expirationTime: NO_EXPIRATION_TIME, // No expiration time + // revocable: true, + // refUID: EMPTY_UID, // No references UI + // data: abi.encode(productId, buyerAddress, review), + // value: 0 // No value/ETH + // }) + // }) + // ); + + return + 0x0d455486a3dadeacfba5f340fe5bf84d1f6678b2e2af53536acc8a4274626f82; + } +} diff --git a/packages/hardhat/contracts/TrustScriptShop.sol b/packages/hardhat/contracts/TrustScriptShop.sol new file mode 100644 index 000000000..85687117e --- /dev/null +++ b/packages/hardhat/contracts/TrustScriptShop.sol @@ -0,0 +1,234 @@ +//SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "./TrustScriptToken.sol"; +import "./TrustScriptProductReviewAttester.sol"; + +contract TrustScriptShop is Ownable { + struct Product { + uint256 id; + string name; + uint256 priceInETH; + uint256 priceInToken; + } + + struct ProductReview { + bytes32 attestationUID; + uint256 productId; + address buyerAddress; + string review; + } + + TrustScriptToken public trustScriptToken; + uint256 public constant TOKENS_PER_ETH = 1000; + uint256 public constant REVIEW_PRODUCT_REWARD = 5; + mapping(uint256 => bool) public productsMapping; + Product[] public productsArray; + mapping(uint256 => Product) public products; + uint256 public numberOfProducts; + ProductReview[] public productReviewsArray; + uint256 public numberOfProductReviews; + mapping(address => bool) public allowedAttesters; + TrustScriptProductReviewAttester public trustScriptProductReviewAttester; + + event AddProduct(address sellerAddress, Product product); + event BuyProductWithETH(address buyerAddress, Product product); + event BuyProductWithToken(address buyerAddress, Product product); + event ReviewProduct(address buyerAddress, ProductReview productReview); + event MintTokenToBuyer(address buyerAddress, uint256 amountOfToken); + event WithdrawETH(uint256 amountOfETH); + event WithdrawToken(uint256 amountOfToken); + + error TrustScriptShop__ExistedProductId(uint256 productId); + error TrustScriptShop__NotExistedProductId(uint256 productId); + error TrustScriptShop__UnequalPriceInETHAndPriceInToken( + uint256 priceInETH, + uint256 priceInToken + ); + error TrustScriptShop__UnequalAmountOfETHAndPriceInETH( + uint256 amountOfETH, + uint256 priceInETH + ); + error TrustScriptShop__UnequalAmountOfTokenAndPriceInToken( + uint256 amountOfToken, + uint256 priceInToken + ); + error TrustScriptShop__FailedToSendETH(); + error TrustScriptShop__DisallowedAttester(address attesterAddress); + + modifier onlyAllowedAttesters() { + if (!allowedAttesters[msg.sender]) + revert TrustScriptShop__DisallowedAttester(msg.sender); + _; + } + + constructor( + address ownerAddress, + address trustScriptTokenAddress, + address trustScriptProductReviewAttesterAddress + ) { + super.transferOwnership(ownerAddress); + trustScriptToken = TrustScriptToken(trustScriptTokenAddress); + trustScriptProductReviewAttester = TrustScriptProductReviewAttester( + trustScriptProductReviewAttesterAddress + ); + } + + function addProduct(Product memory product) public onlyOwner { + if (productsMapping[product.id]) { + revert TrustScriptShop__ExistedProductId(product.id); + } + + if ( + product.priceInETH * + TOKENS_PER_ETH * + 10 ** trustScriptToken.decimals() != + product.priceInToken * 1 ether + ) { + revert TrustScriptShop__UnequalPriceInETHAndPriceInToken( + product.priceInETH, + product.priceInToken + ); + } + + productsMapping[product.id] = true; + productsArray.push(product); + products[product.id] = product; + numberOfProducts++; + + emit AddProduct(msg.sender, product); + } + + function buyProductWithETH(uint256 id) public payable { + if (!productsMapping[id]) { + revert TrustScriptShop__NotExistedProductId(id); + } + + uint256 priceInETH = products[id].priceInETH; + if (msg.value != priceInETH) { + revert TrustScriptShop__UnequalAmountOfETHAndPriceInETH( + msg.value, + priceInETH + ); + } + + if (!allowedAttesters[msg.sender]) { + allowedAttesters[msg.sender] = true; + } + + (bool success, ) = owner().call{ value: priceInETH }(""); + if (!success) { + revert TrustScriptShop__FailedToSendETH(); + } + + emit BuyProductWithETH(msg.sender, products[id]); + } + + function buyProductWithToken(uint256 id, uint256 amountOfToken) public { + if (!productsMapping[id]) { + revert TrustScriptShop__NotExistedProductId(id); + } + + uint256 priceInToken = products[id].priceInToken; + if (amountOfToken != priceInToken) { + revert TrustScriptShop__UnequalAmountOfTokenAndPriceInToken( + amountOfToken, + priceInToken + ); + } + + if (!allowedAttesters[msg.sender]) { + allowedAttesters[msg.sender] = true; + } + + trustScriptToken.transferFrom(msg.sender, owner(), amountOfToken); + + emit BuyProductWithToken(msg.sender, products[id]); + } + + function reviewProduct( + uint256 id, + string memory review + ) public onlyAllowedAttesters { + if (!productsMapping[id]) { + revert TrustScriptShop__NotExistedProductId(id); + } + + bytes32 attestationUID = trustScriptProductReviewAttester + .attestProductReview(id, msg.sender, review, owner()); + + ProductReview memory productReview = ProductReview( + attestationUID, + id, + msg.sender, + review + ); + + emit ReviewProduct(msg.sender, productReview); + + productReviewsArray.push(productReview); + numberOfProductReviews++; + + trustScriptToken.mint( + msg.sender, + REVIEW_PRODUCT_REWARD * 10 ** trustScriptToken.decimals() + ); + + emit MintTokenToBuyer( + msg.sender, + REVIEW_PRODUCT_REWARD * 10 ** trustScriptToken.decimals() + ); + } + + function withdrawETH() public onlyOwner { + uint256 amountOfETH = address(this).balance; + + (bool success, ) = msg.sender.call{ value: amountOfETH }(""); + if (!success) { + revert TrustScriptShop__FailedToSendETH(); + } + + emit WithdrawETH(amountOfETH); + } + + function withdrawToken() public onlyOwner { + uint256 amountOfToken = trustScriptToken.balanceOf(address(this)); + trustScriptToken.transfer(msg.sender, amountOfToken); + + emit WithdrawToken(amountOfToken); + } + + function getAllProducts() + public + view + returns (Product[] memory allProducts) + { + if (numberOfProducts == 0) { + return new Product[](0); + } + + allProducts = new Product[](numberOfProducts); + for (uint i = 0; i < numberOfProducts; i++) { + allProducts[i] = productsArray[i]; + } + return allProducts; + } + + function getAllProductReviews() + public + view + returns (ProductReview[] memory allProductReviews) + { + if (numberOfProductReviews == 0) { + return new ProductReview[](0); + } + + allProductReviews = new ProductReview[](numberOfProductReviews); + for (uint i = 0; i < numberOfProductReviews; i++) { + allProductReviews[i] = productReviewsArray[i]; + } + return allProductReviews; + } +} diff --git a/packages/hardhat/contracts/TrustScriptToken.sol b/packages/hardhat/contracts/TrustScriptToken.sol new file mode 100644 index 000000000..bd1763a31 --- /dev/null +++ b/packages/hardhat/contracts/TrustScriptToken.sol @@ -0,0 +1,35 @@ +//SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +contract TrustScriptToken is ERC20, Ownable { + mapping(address => bool) public allowedMinters; + + error TrustScriptToken__DisallowedMinter(address minterAddress); + + modifier onlyAllowedMinters() { + if (!allowedMinters[msg.sender]) + revert TrustScriptToken__DisallowedMinter(msg.sender); + _; + } + + constructor(address ownerAddress) ERC20("TrustScript", "TST") { + super.transferOwnership(ownerAddress); + + allowedMinters[ownerAddress] = true; + _mint(ownerAddress, 1000 * 10 ** decimals()); + } + + function mint( + address beneficiary, + uint256 amountOfToken + ) external onlyAllowedMinters { + _mint(beneficiary, amountOfToken); + } + + function allowMinter(address minter) public onlyOwner { + allowedMinters[minter] = true; + } +} diff --git a/packages/hardhat/contracts/YourContract.sol b/packages/hardhat/contracts/YourContract.sol deleted file mode 100644 index 3d364a0ee..000000000 --- a/packages/hardhat/contracts/YourContract.sol +++ /dev/null @@ -1,87 +0,0 @@ -//SPDX-License-Identifier: MIT -pragma solidity >=0.8.0 <0.9.0; - -// Useful for debugging. Remove when deploying to a live network. -import "hardhat/console.sol"; - -// Use openzeppelin to inherit battle-tested implementations (ERC20, ERC721, etc) -// import "@openzeppelin/contracts/access/Ownable.sol"; - -/** - * A smart contract that allows changing a state variable of the contract and tracking the changes - * It also allows the owner to withdraw the Ether in the contract - * @author BuidlGuidl - */ -contract YourContract { - // State Variables - address public immutable owner; - string public greeting = "Building Unstoppable Apps!!!"; - bool public premium = false; - uint256 public totalCounter = 0; - mapping(address => uint) public userGreetingCounter; - - // Events: a way to emit log statements from smart contract that can be listened to by external parties - event GreetingChange( - address indexed greetingSetter, - string newGreeting, - bool premium, - uint256 value - ); - - // Constructor: Called once on contract deployment - // Check packages/hardhat/deploy/00_deploy_your_contract.ts - constructor(address _owner) { - owner = _owner; - } - - // Modifier: used to define a set of rules that must be met before or after a function is executed - // Check the withdraw() function - modifier isOwner() { - // msg.sender: predefined variable that represents address of the account that called the current function - require(msg.sender == owner, "Not the Owner"); - _; - } - - /** - * Function that allows anyone to change the state variable "greeting" of the contract and increase the counters - * - * @param _newGreeting (string memory) - new greeting to save on the contract - */ - function setGreeting(string memory _newGreeting) public payable { - // Print data to the hardhat chain console. Remove when deploying to a live network. - console.log( - "Setting new greeting '%s' from %s", - _newGreeting, - msg.sender - ); - - // Change state variables - greeting = _newGreeting; - totalCounter += 1; - userGreetingCounter[msg.sender] += 1; - - // msg.value: built-in global variable that represents the amount of ether sent with the transaction - if (msg.value > 0) { - premium = true; - } else { - premium = false; - } - - // emit: keyword used to trigger an event - emit GreetingChange(msg.sender, _newGreeting, msg.value > 0, msg.value); - } - - /** - * Function that allows the owner to withdraw all the Ether in the contract - * The function can only be called by the owner of the contract as defined by the isOwner modifier - */ - function withdraw() public isOwner { - (bool success, ) = owner.call{ value: address(this).balance }(""); - require(success, "Failed to send Ether"); - } - - /** - * Function that allows the contract to receive ETH - */ - receive() external payable {} -} diff --git a/packages/hardhat/deploy/00_deploy_trust_script_token.ts b/packages/hardhat/deploy/00_deploy_trust_script_token.ts new file mode 100644 index 000000000..722d9f715 --- /dev/null +++ b/packages/hardhat/deploy/00_deploy_trust_script_token.ts @@ -0,0 +1,51 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; + +/** + * Deploys a contract named "YourToken" using the deployer account and + * constructor arguments set to the deployer address + * + * @param hre HardhatRuntimeEnvironment object. + */ +const deployTrustScriptToken: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + /* + On localhost, the deployer account is the one that comes with Hardhat, which is already funded. + + When deploying to live networks (e.g `yarn deploy --network sepolia`), the deployer account + should have sufficient balance to pay for the gas fees for contract creation. + + You can generate a random account with `yarn generate` which will fill DEPLOYER_PRIVATE_KEY + with a random private key in the .env file (then used on hardhat.config.ts) + You can run the `yarn account` command to check your balance in every network. + */ + const { deployer } = await hre.getNamedAccounts(); + const { deploy } = hre.deployments; + + // Base Sepolia + // await deploy("TrustScriptToken", { + // from: deployer, + // // Contract constructor arguments + // args: ["0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0"], + // log: true, + // // // autoMine: can be passed to the deploy function to make the deployment process faster on local networks by + // // // automatically mining the contract deployment transaction. There is no effect on live networks. + // autoMine: true, + // }); + + // Localhost + await deploy("TrustScriptToken", { + from: deployer, + // Contract constructor arguments + args: ["0xc9a57d319f875A4EdC48b4efE89c803daBCFA71c"], + log: true, + // autoMine: can be passed to the deploy function to make the deployment process faster on local networks by + // automatically mining the contract deployment transaction. There is no effect on live networks. + autoMine: true, + }); +}; + +export default deployTrustScriptToken; + +// Tags are useful if you have multiple deploy files and only want to run one of them. +// e.g. yarn deploy --tags YourToken +deployTrustScriptToken.tags = ["TrustScriptToken"]; diff --git a/packages/hardhat/deploy/00_deploy_your_contract.ts b/packages/hardhat/deploy/01_deploy_trust_script_product_review_attester.ts similarity index 67% rename from packages/hardhat/deploy/00_deploy_your_contract.ts rename to packages/hardhat/deploy/01_deploy_trust_script_product_review_attester.ts index 716fec79e..b4a0442e4 100644 --- a/packages/hardhat/deploy/00_deploy_your_contract.ts +++ b/packages/hardhat/deploy/01_deploy_trust_script_product_review_attester.ts @@ -1,14 +1,13 @@ import { HardhatRuntimeEnvironment } from "hardhat/types"; import { DeployFunction } from "hardhat-deploy/types"; -import { Contract } from "ethers"; /** - * Deploys a contract named "YourContract" using the deployer account and + * Deploys a contract named "YourToken" using the deployer account and * constructor arguments set to the deployer address * * @param hre HardhatRuntimeEnvironment object. */ -const deployYourContract: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { +const deployTrustScriptProductReviewAttester: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { /* On localhost, the deployer account is the one that comes with Hardhat, which is already funded. @@ -22,23 +21,22 @@ const deployYourContract: DeployFunction = async function (hre: HardhatRuntimeEn const { deployer } = await hre.getNamedAccounts(); const { deploy } = hre.deployments; - await deploy("YourContract", { + await deploy("TrustScriptProductReviewAttester", { from: deployer, // Contract constructor arguments - args: [deployer], + args: [ + "0x4200000000000000000000000000000000000021", + "0xa844aad897e631c5200bc2a0f5c093eeb3e96baa4f8428d93dbcb76e775906a9", // ProductReviewSchemaUID + ], log: true, // autoMine: can be passed to the deploy function to make the deployment process faster on local networks by // automatically mining the contract deployment transaction. There is no effect on live networks. autoMine: true, }); - - // Get the deployed contract to interact with it after deploying. - const yourContract = await hre.ethers.getContract("YourContract", deployer); - console.log("๐Ÿ‘‹ Initial greeting:", await yourContract.greeting()); }; -export default deployYourContract; +export default deployTrustScriptProductReviewAttester; // Tags are useful if you have multiple deploy files and only want to run one of them. -// e.g. yarn deploy --tags YourContract -deployYourContract.tags = ["YourContract"]; +// e.g. yarn deploy --tags YourToken +deployTrustScriptProductReviewAttester.tags = ["TrustScriptProductReviewAttester"]; diff --git a/packages/hardhat/deploy/02_deploy_trust_script_shop.ts b/packages/hardhat/deploy/02_deploy_trust_script_shop.ts new file mode 100644 index 000000000..bbd6854d2 --- /dev/null +++ b/packages/hardhat/deploy/02_deploy_trust_script_shop.ts @@ -0,0 +1,72 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; +import { Contract } from "ethers"; + +/** + * Deploys a contract named "YourContract" using the deployer account and + * constructor arguments set to the deployer address + * + * @param hre HardhatRuntimeEnvironment object. + */ +const deployTrustScriptShop: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + /* + On localhost, the deployer account is the one that comes with Hardhat, which is already funded. + + When deploying to live networks (e.g `yarn deploy --network sepolia`), the deployer account + should have sufficient balance to pay for the gas fees for contract creation. + + You can generate a random account with `yarn generate` which will fill DEPLOYER_PRIVATE_KEY + with a random private key in the .env file (then used on hardhat.config.ts) + You can run the `yarn account` command to check your balance in every network. + */ + const { deployer } = await hre.getNamedAccounts(); + const { deploy } = hre.deployments; + + const trustScriptToken = await hre.ethers.getContract("TrustScriptToken", deployer); + const trustScriptTokenAddress = await trustScriptToken.getAddress(); + + const trustScriptProductReviewAttester = await hre.ethers.getContract( + "TrustScriptProductReviewAttester", + deployer, + ); + const trustScriptProductReviewAttesterAddress = await trustScriptProductReviewAttester.getAddress(); + + await deploy("TrustScriptShop", { + from: deployer, + // Contract constructor arguments + args: [deployer, trustScriptTokenAddress, trustScriptProductReviewAttesterAddress], + log: true, + // autoMine: can be passed to the deploy function to make the deployment process faster on local networks by + // automatically mining the contract deployment transaction. There is no effect on live networks. + autoMine: true, + }); + + //Add 6 products + const trustScriptShop = await hre.ethers.getContract("TrustScriptShop", deployer); + + const productNames = ["Coin Cap", "Bitcoin Hoodie", "Brian Beanie", "Onchain Pin", "Coinbrew", "T-shirt"]; + + for (let i = 1; i <= 6; i++) { + const product = { + id: i, + name: productNames[i - 1], + priceInETH: hre.ethers.parseEther((0.001 * i).toString()), + priceInToken: hre.ethers.parseEther((1 * i).toString()), + }; + + console.log(`Adding product ${i} to TrustScript Shop`); + await trustScriptShop.addProduct(product); + } + + // Base Sepolia + // await trustScriptShop.transferOwnership("0x35fAadD6fC68619b72A7Bfb871eDcC069C2f1bc3"); + + // Localhost + await trustScriptShop.transferOwnership("0xc9a57d319f875A4EdC48b4efE89c803daBCFA71c"); +}; + +export default deployTrustScriptShop; + +// Tags are useful if you have multiple deploy files and only want to run one of them. +// e.g. yarn deploy --tags YourContract +deployTrustScriptShop.tags = ["TrustScriptShop"]; diff --git a/packages/hardhat/deployments/baseSepolia/.chainId b/packages/hardhat/deployments/baseSepolia/.chainId new file mode 100644 index 000000000..667f99daf --- /dev/null +++ b/packages/hardhat/deployments/baseSepolia/.chainId @@ -0,0 +1 @@ +84532 \ No newline at end of file diff --git a/packages/hardhat/deployments/baseSepolia/TrustScriptProductReviewAttester.json b/packages/hardhat/deployments/baseSepolia/TrustScriptProductReviewAttester.json new file mode 100644 index 000000000..03a2858c9 --- /dev/null +++ b/packages/hardhat/deployments/baseSepolia/TrustScriptProductReviewAttester.json @@ -0,0 +1,156 @@ +{ + "address": "0x80Eb3ccE63E5beDFe067e56e8c3dCCcbf1522247", + "abi": [ + { + "inputs": [ + { + "internalType": "contract IEAS", + "name": "easAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_productReviewSchemaUID", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidEAS", + "type": "error" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "productId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "buyerAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "review", + "type": "string" + } + ], + "internalType": "struct ProductReview", + "name": "productReview", + "type": "tuple" + }, + { + "internalType": "address", + "name": "sellerAddress", + "type": "address" + } + ], + "name": "attestProductReview", + "outputs": [ + { + "internalType": "bytes32", + "name": "attestationUID", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eas", + "outputs": [ + { + "internalType": "contract IEAS", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "productReviewSchemaUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x1e9fbfc95e0580c23b7f27d7bdb2649088adef8fbbbaeb33ca659780d14507b5", + "receipt": { + "to": null, + "from": "0x35fAadD6fC68619b72A7Bfb871eDcC069C2f1bc3", + "contractAddress": "0x80Eb3ccE63E5beDFe067e56e8c3dCCcbf1522247", + "transactionIndex": 4, + "gasUsed": "323846", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1d9dcf0e9a1c88af628df2e66fc6c02b30d28453161800979b2fbab76f220618", + "transactionHash": "0x1e9fbfc95e0580c23b7f27d7bdb2649088adef8fbbbaeb33ca659780d14507b5", + "logs": [], + "blockNumber": 11672316, + "cumulativeGasUsed": "1186715", + "status": 1, + "byzantium": true + }, + "args": [ + "0x4200000000000000000000000000000000000021", + "0xa844aad897e631c5200bc2a0f5c093eeb3e96baa4f8428d93dbcb76e775906a9" + ], + "numDeployments": 1, + "solcInputHash": "600a4f1d04d1120bafc3a677d8e15185", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IEAS\",\"name\":\"easAddress\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_productReviewSchemaUID\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidEAS\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"productId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"buyerAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"review\",\"type\":\"string\"}],\"internalType\":\"struct ProductReview\",\"name\":\"productReview\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"sellerAddress\",\"type\":\"address\"}],\"name\":\"attestProductReview\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"attestationUID\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eas\",\"outputs\":[{\"internalType\":\"contract IEAS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"productReviewSchemaUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"attestProductReview((uint256,address,string),address)\":{\"params\":{\"productReview\":\"The ProductReview value to pass to to the resolver.\"},\"returns\":{\"attestationUID\":\"The UID of the new attestation.\"}},\"constructor\":{\"params\":{\"_productReviewSchemaUID\":\"The UID of the ProductReview schema.\",\"easAddress\":\"The address of the global EAS contract.\"}}},\"title\":\"TrustScriptProductReviewAttester\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"attestProductReview((uint256,address,string),address)\":{\"notice\":\"Attests to a schema that receives a ProductReview parameter.\"},\"constructor\":{\"notice\":\"Creates a new TrustScriptProductReviewAttester instance.\"}},\"notice\":\"Ethereum Attestation Service - Example\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/TrustScriptProductReviewAttester.sol\":\"TrustScriptProductReviewAttester\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@ethereum-attestation-service/eas-contracts/contracts/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n// A representation of an empty/uninitialized UID.\\nbytes32 constant EMPTY_UID = 0;\\n\\n// A zero expiration represents an non-expiring attestation.\\nuint64 constant NO_EXPIRATION_TIME = 0;\\n\\nerror AccessDenied();\\nerror DeadlineExpired();\\nerror InvalidEAS();\\nerror InvalidLength();\\nerror InvalidSignature();\\nerror NotFound();\\n\\n/// @notice A struct representing ECDSA signature data.\\nstruct Signature {\\n uint8 v; // The recovery ID.\\n bytes32 r; // The x-coordinate of the nonce R.\\n bytes32 s; // The signature data.\\n}\\n\\n/// @notice A struct representing a single attestation.\\nstruct Attestation {\\n bytes32 uid; // A unique identifier of the attestation.\\n bytes32 schema; // The unique identifier of the schema.\\n uint64 time; // The time when the attestation was created (Unix timestamp).\\n uint64 expirationTime; // The time when the attestation expires (Unix timestamp).\\n uint64 revocationTime; // The time when the attestation was revoked (Unix timestamp).\\n bytes32 refUID; // The UID of the related attestation.\\n address recipient; // The recipient of the attestation.\\n address attester; // The attester/sender of the attestation.\\n bool revocable; // Whether the attestation is revocable.\\n bytes data; // Custom attestation data.\\n}\\n\\n/// @notice A helper function to work with unchecked iterators in loops.\\nfunction uncheckedInc(uint256 i) pure returns (uint256 j) {\\n unchecked {\\n j = i + 1;\\n }\\n}\\n\",\"keccak256\":\"0x957bd2e6d0d6d637f86208b135c29fbaf4412cb08e5e7a61ede16b80561bf685\",\"license\":\"MIT\"},\"@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport { ISchemaRegistry } from \\\"./ISchemaRegistry.sol\\\";\\nimport { ISemver } from \\\"./ISemver.sol\\\";\\nimport { Attestation, Signature } from \\\"./Common.sol\\\";\\n\\n/// @notice A struct representing the arguments of the attestation request.\\nstruct AttestationRequestData {\\n address recipient; // The recipient of the attestation.\\n uint64 expirationTime; // The time when the attestation expires (Unix timestamp).\\n bool revocable; // Whether the attestation is revocable.\\n bytes32 refUID; // The UID of the related attestation.\\n bytes data; // Custom attestation data.\\n uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user errors.\\n}\\n\\n/// @notice A struct representing the full arguments of the attestation request.\\nstruct AttestationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n AttestationRequestData data; // The arguments of the attestation request.\\n}\\n\\n/// @notice A struct representing the full arguments of the full delegated attestation request.\\nstruct DelegatedAttestationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n AttestationRequestData data; // The arguments of the attestation request.\\n Signature signature; // The ECDSA signature data.\\n address attester; // The attesting account.\\n uint64 deadline; // The deadline of the signature/request.\\n}\\n\\n/// @notice A struct representing the full arguments of the multi attestation request.\\nstruct MultiAttestationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n AttestationRequestData[] data; // The arguments of the attestation request.\\n}\\n\\n/// @notice A struct representing the full arguments of the delegated multi attestation request.\\nstruct MultiDelegatedAttestationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n AttestationRequestData[] data; // The arguments of the attestation requests.\\n Signature[] signatures; // The ECDSA signatures data. Please note that the signatures are assumed to be signed with increasing nonces.\\n address attester; // The attesting account.\\n uint64 deadline; // The deadline of the signature/request.\\n}\\n\\n/// @notice A struct representing the arguments of the revocation request.\\nstruct RevocationRequestData {\\n bytes32 uid; // The UID of the attestation to revoke.\\n uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user errors.\\n}\\n\\n/// @notice A struct representing the full arguments of the revocation request.\\nstruct RevocationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n RevocationRequestData data; // The arguments of the revocation request.\\n}\\n\\n/// @notice A struct representing the arguments of the full delegated revocation request.\\nstruct DelegatedRevocationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n RevocationRequestData data; // The arguments of the revocation request.\\n Signature signature; // The ECDSA signature data.\\n address revoker; // The revoking account.\\n uint64 deadline; // The deadline of the signature/request.\\n}\\n\\n/// @notice A struct representing the full arguments of the multi revocation request.\\nstruct MultiRevocationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n RevocationRequestData[] data; // The arguments of the revocation request.\\n}\\n\\n/// @notice A struct representing the full arguments of the delegated multi revocation request.\\nstruct MultiDelegatedRevocationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n RevocationRequestData[] data; // The arguments of the revocation requests.\\n Signature[] signatures; // The ECDSA signatures data. Please note that the signatures are assumed to be signed with increasing nonces.\\n address revoker; // The revoking account.\\n uint64 deadline; // The deadline of the signature/request.\\n}\\n\\n/// @title IEAS\\n/// @notice EAS - Ethereum Attestation Service interface.\\ninterface IEAS is ISemver {\\n /// @notice Emitted when an attestation has been made.\\n /// @param recipient The recipient of the attestation.\\n /// @param attester The attesting account.\\n /// @param uid The UID of the new attestation.\\n /// @param schemaUID The UID of the schema.\\n event Attested(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schemaUID);\\n\\n /// @notice Emitted when an attestation has been revoked.\\n /// @param recipient The recipient of the attestation.\\n /// @param attester The attesting account.\\n /// @param schemaUID The UID of the schema.\\n /// @param uid The UID the revoked attestation.\\n event Revoked(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schemaUID);\\n\\n /// @notice Emitted when a data has been timestamped.\\n /// @param data The data.\\n /// @param timestamp The timestamp.\\n event Timestamped(bytes32 indexed data, uint64 indexed timestamp);\\n\\n /// @notice Emitted when a data has been revoked.\\n /// @param revoker The address of the revoker.\\n /// @param data The data.\\n /// @param timestamp The timestamp.\\n event RevokedOffchain(address indexed revoker, bytes32 indexed data, uint64 indexed timestamp);\\n\\n /// @notice Returns the address of the global schema registry.\\n /// @return The address of the global schema registry.\\n function getSchemaRegistry() external view returns (ISchemaRegistry);\\n\\n /// @notice Attests to a specific schema.\\n /// @param request The arguments of the attestation request.\\n /// @return The UID of the new attestation.\\n ///\\n /// Example:\\n /// attest({\\n /// schema: \\\"0facc36681cbe2456019c1b0d1e7bedd6d1d40f6f324bf3dd3a4cef2999200a0\\\",\\n /// data: {\\n /// recipient: \\\"0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf\\\",\\n /// expirationTime: 0,\\n /// revocable: true,\\n /// refUID: \\\"0x0000000000000000000000000000000000000000000000000000000000000000\\\",\\n /// data: \\\"0xF00D\\\",\\n /// value: 0\\n /// }\\n /// })\\n function attest(AttestationRequest calldata request) external payable returns (bytes32);\\n\\n /// @notice Attests to a specific schema via the provided ECDSA signature.\\n /// @param delegatedRequest The arguments of the delegated attestation request.\\n /// @return The UID of the new attestation.\\n ///\\n /// Example:\\n /// attestByDelegation({\\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\\n /// data: {\\n /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\\n /// expirationTime: 1673891048,\\n /// revocable: true,\\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\\n /// data: '0x1234',\\n /// value: 0\\n /// },\\n /// signature: {\\n /// v: 28,\\n /// r: '0x148c...b25b',\\n /// s: '0x5a72...be22'\\n /// },\\n /// attester: '0xc5E8740aD971409492b1A63Db8d83025e0Fc427e',\\n /// deadline: 1673891048\\n /// })\\n function attestByDelegation(\\n DelegatedAttestationRequest calldata delegatedRequest\\n ) external payable returns (bytes32);\\n\\n /// @notice Attests to multiple schemas.\\n /// @param multiRequests The arguments of the multi attestation requests. The requests should be grouped by distinct\\n /// schema ids to benefit from the best batching optimization.\\n /// @return The UIDs of the new attestations.\\n ///\\n /// Example:\\n /// multiAttest([{\\n /// schema: '0x33e9094830a5cba5554d1954310e4fbed2ef5f859ec1404619adea4207f391fd',\\n /// data: [{\\n /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf',\\n /// expirationTime: 1673891048,\\n /// revocable: true,\\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\\n /// data: '0x1234',\\n /// value: 1000\\n /// },\\n /// {\\n /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\\n /// expirationTime: 0,\\n /// revocable: false,\\n /// refUID: '0x480df4a039efc31b11bfdf491b383ca138b6bde160988222a2a3509c02cee174',\\n /// data: '0x00',\\n /// value: 0\\n /// }],\\n /// },\\n /// {\\n /// schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425',\\n /// data: [{\\n /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf',\\n /// expirationTime: 0,\\n /// revocable: true,\\n /// refUID: '0x75bf2ed8dca25a8190c50c52db136664de25b2449535839008ccfdab469b214f',\\n /// data: '0x12345678',\\n /// value: 0\\n /// },\\n /// }])\\n function multiAttest(MultiAttestationRequest[] calldata multiRequests) external payable returns (bytes32[] memory);\\n\\n /// @notice Attests to multiple schemas using via provided ECDSA signatures.\\n /// @param multiDelegatedRequests The arguments of the delegated multi attestation requests. The requests should be\\n /// grouped by distinct schema ids to benefit from the best batching optimization.\\n /// @return The UIDs of the new attestations.\\n ///\\n /// Example:\\n /// multiAttestByDelegation([{\\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\\n /// data: [{\\n /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\\n /// expirationTime: 1673891048,\\n /// revocable: true,\\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\\n /// data: '0x1234',\\n /// value: 0\\n /// },\\n /// {\\n /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf',\\n /// expirationTime: 0,\\n /// revocable: false,\\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\\n /// data: '0x00',\\n /// value: 0\\n /// }],\\n /// signatures: [{\\n /// v: 28,\\n /// r: '0x148c...b25b',\\n /// s: '0x5a72...be22'\\n /// },\\n /// {\\n /// v: 28,\\n /// r: '0x487s...67bb',\\n /// s: '0x12ad...2366'\\n /// }],\\n /// attester: '0x1D86495b2A7B524D747d2839b3C645Bed32e8CF4',\\n /// deadline: 1673891048\\n /// }])\\n function multiAttestByDelegation(\\n MultiDelegatedAttestationRequest[] calldata multiDelegatedRequests\\n ) external payable returns (bytes32[] memory);\\n\\n /// @notice Revokes an existing attestation to a specific schema.\\n /// @param request The arguments of the revocation request.\\n ///\\n /// Example:\\n /// revoke({\\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\\n /// data: {\\n /// uid: '0x101032e487642ee04ee17049f99a70590c735b8614079fc9275f9dd57c00966d',\\n /// value: 0\\n /// }\\n /// })\\n function revoke(RevocationRequest calldata request) external payable;\\n\\n /// @notice Revokes an existing attestation to a specific schema via the provided ECDSA signature.\\n /// @param delegatedRequest The arguments of the delegated revocation request.\\n ///\\n /// Example:\\n /// revokeByDelegation({\\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\\n /// data: {\\n /// uid: '0xcbbc12102578c642a0f7b34fe7111e41afa25683b6cd7b5a14caf90fa14d24ba',\\n /// value: 0\\n /// },\\n /// signature: {\\n /// v: 27,\\n /// r: '0xb593...7142',\\n /// s: '0x0f5b...2cce'\\n /// },\\n /// revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992',\\n /// deadline: 1673891048\\n /// })\\n function revokeByDelegation(DelegatedRevocationRequest calldata delegatedRequest) external payable;\\n\\n /// @notice Revokes existing attestations to multiple schemas.\\n /// @param multiRequests The arguments of the multi revocation requests. The requests should be grouped by distinct\\n /// schema ids to benefit from the best batching optimization.\\n ///\\n /// Example:\\n /// multiRevoke([{\\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\\n /// data: [{\\n /// uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25',\\n /// value: 1000\\n /// },\\n /// {\\n /// uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade',\\n /// value: 0\\n /// }],\\n /// },\\n /// {\\n /// schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425',\\n /// data: [{\\n /// uid: '0x053d42abce1fd7c8fcddfae21845ad34dae287b2c326220b03ba241bc5a8f019',\\n /// value: 0\\n /// },\\n /// }])\\n function multiRevoke(MultiRevocationRequest[] calldata multiRequests) external payable;\\n\\n /// @notice Revokes existing attestations to multiple schemas via provided ECDSA signatures.\\n /// @param multiDelegatedRequests The arguments of the delegated multi revocation attestation requests. The requests\\n /// should be grouped by distinct schema ids to benefit from the best batching optimization.\\n ///\\n /// Example:\\n /// multiRevokeByDelegation([{\\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\\n /// data: [{\\n /// uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25',\\n /// value: 1000\\n /// },\\n /// {\\n /// uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade',\\n /// value: 0\\n /// }],\\n /// signatures: [{\\n /// v: 28,\\n /// r: '0x148c...b25b',\\n /// s: '0x5a72...be22'\\n /// },\\n /// {\\n /// v: 28,\\n /// r: '0x487s...67bb',\\n /// s: '0x12ad...2366'\\n /// }],\\n /// revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992',\\n /// deadline: 1673891048\\n /// }])\\n function multiRevokeByDelegation(\\n MultiDelegatedRevocationRequest[] calldata multiDelegatedRequests\\n ) external payable;\\n\\n /// @notice Timestamps the specified bytes32 data.\\n /// @param data The data to timestamp.\\n /// @return The timestamp the data was timestamped with.\\n function timestamp(bytes32 data) external returns (uint64);\\n\\n /// @notice Timestamps the specified multiple bytes32 data.\\n /// @param data The data to timestamp.\\n /// @return The timestamp the data was timestamped with.\\n function multiTimestamp(bytes32[] calldata data) external returns (uint64);\\n\\n /// @notice Revokes the specified bytes32 data.\\n /// @param data The data to timestamp.\\n /// @return The timestamp the data was revoked with.\\n function revokeOffchain(bytes32 data) external returns (uint64);\\n\\n /// @notice Revokes the specified multiple bytes32 data.\\n /// @param data The data to timestamp.\\n /// @return The timestamp the data was revoked with.\\n function multiRevokeOffchain(bytes32[] calldata data) external returns (uint64);\\n\\n /// @notice Returns an existing attestation by UID.\\n /// @param uid The UID of the attestation to retrieve.\\n /// @return The attestation data members.\\n function getAttestation(bytes32 uid) external view returns (Attestation memory);\\n\\n /// @notice Checks whether an attestation exists.\\n /// @param uid The UID of the attestation to retrieve.\\n /// @return Whether an attestation exists.\\n function isAttestationValid(bytes32 uid) external view returns (bool);\\n\\n /// @notice Returns the timestamp that the specified data was timestamped with.\\n /// @param data The data to query.\\n /// @return The timestamp the data was timestamped with.\\n function getTimestamp(bytes32 data) external view returns (uint64);\\n\\n /// @notice Returns the timestamp that the specified data was timestamped with.\\n /// @param data The data to query.\\n /// @return The timestamp the data was timestamped with.\\n function getRevokeOffchain(address revoker, bytes32 data) external view returns (uint64);\\n}\\n\",\"keccak256\":\"0xdad0674defce04905dc7935f2756d6c477a6e876c0b1b7094b112a862f164c12\",\"license\":\"MIT\"},\"@ethereum-attestation-service/eas-contracts/contracts/ISchemaRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport { ISemver } from \\\"./ISemver.sol\\\";\\n\\nimport { ISchemaResolver } from \\\"./resolver/ISchemaResolver.sol\\\";\\n\\n/// @notice A struct representing a record for a submitted schema.\\nstruct SchemaRecord {\\n bytes32 uid; // The unique identifier of the schema.\\n ISchemaResolver resolver; // Optional schema resolver.\\n bool revocable; // Whether the schema allows revocations explicitly.\\n string schema; // Custom specification of the schema (e.g., an ABI).\\n}\\n\\n/// @title ISchemaRegistry\\n/// @notice The interface of global attestation schemas for the Ethereum Attestation Service protocol.\\ninterface ISchemaRegistry is ISemver {\\n /// @notice Emitted when a new schema has been registered\\n /// @param uid The schema UID.\\n /// @param registerer The address of the account used to register the schema.\\n /// @param schema The schema data.\\n event Registered(bytes32 indexed uid, address indexed registerer, SchemaRecord schema);\\n\\n /// @notice Submits and reserves a new schema\\n /// @param schema The schema data schema.\\n /// @param resolver An optional schema resolver.\\n /// @param revocable Whether the schema allows revocations explicitly.\\n /// @return The UID of the new schema.\\n function register(string calldata schema, ISchemaResolver resolver, bool revocable) external returns (bytes32);\\n\\n /// @notice Returns an existing schema by UID\\n /// @param uid The UID of the schema to retrieve.\\n /// @return The schema data members.\\n function getSchema(bytes32 uid) external view returns (SchemaRecord memory);\\n}\\n\",\"keccak256\":\"0xea97dcd36a0c422169cbaac06698249e199049b627c16bff93fb8ab829058754\",\"license\":\"MIT\"},\"@ethereum-attestation-service/eas-contracts/contracts/ISemver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/// @title ISemver\\n/// @notice A semver interface.\\ninterface ISemver {\\n /// @notice Returns the full semver contract version.\\n /// @return Semver contract version as a string.\\n function version() external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x04a67939b4e1a8d0a51101b8f69f8882930bbdc66319f38023828625b5d1ff18\",\"license\":\"MIT\"},\"@ethereum-attestation-service/eas-contracts/contracts/resolver/ISchemaResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport { ISemver } from \\\"../ISemver.sol\\\";\\nimport { Attestation } from \\\"../Common.sol\\\";\\n\\n/// @title ISchemaResolver\\n/// @notice The interface of an optional schema resolver.\\ninterface ISchemaResolver is ISemver {\\n /// @notice Checks if the resolver can be sent ETH.\\n /// @return Whether the resolver supports ETH transfers.\\n function isPayable() external pure returns (bool);\\n\\n /// @notice Processes an attestation and verifies whether it's valid.\\n /// @param attestation The new attestation.\\n /// @return Whether the attestation is valid.\\n function attest(Attestation calldata attestation) external payable returns (bool);\\n\\n /// @notice Processes multiple attestations and verifies whether they are valid.\\n /// @param attestations The new attestations.\\n /// @param values Explicit ETH amounts which were sent with each attestation.\\n /// @return Whether all the attestations are valid.\\n function multiAttest(\\n Attestation[] calldata attestations,\\n uint256[] calldata values\\n ) external payable returns (bool);\\n\\n /// @notice Processes an attestation revocation and verifies if it can be revoked.\\n /// @param attestation The existing attestation to be revoked.\\n /// @return Whether the attestation can be revoked.\\n function revoke(Attestation calldata attestation) external payable returns (bool);\\n\\n /// @notice Processes revocation of multiple attestation and verifies they can be revoked.\\n /// @param attestations The existing attestations to be revoked.\\n /// @param values Explicit ETH amounts which were sent with each revocation.\\n /// @return Whether the attestations can be revoked.\\n function multiRevoke(\\n Attestation[] calldata attestations,\\n uint256[] calldata values\\n ) external payable returns (bool);\\n}\\n\",\"keccak256\":\"0x479f39f03425df5385d790cd2c7447b8250aeb9733d13029d3da8c5982b6604b\",\"license\":\"MIT\"},\"contracts/TrustScriptProductReviewAttester.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\r\\npragma solidity >=0.8.0 <0.9.0;\\r\\n\\r\\nimport { IEAS, AttestationRequest, AttestationRequestData } from \\\"@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol\\\";\\r\\nimport { NO_EXPIRATION_TIME, EMPTY_UID } from \\\"@ethereum-attestation-service/eas-contracts/contracts/Common.sol\\\";\\r\\n\\r\\nstruct ProductReview {\\r\\n\\tuint256 productId;\\r\\n\\taddress buyerAddress;\\r\\n\\tstring review;\\r\\n}\\r\\n\\r\\n/// @title TrustScriptProductReviewAttester\\r\\n/// @notice Ethereum Attestation Service - Example\\r\\ncontract TrustScriptProductReviewAttester {\\r\\n\\t// The address of the global EAS contract.\\r\\n\\tIEAS public immutable eas;\\r\\n\\tbytes32 public immutable productReviewSchemaUID;\\r\\n\\r\\n\\terror InvalidEAS();\\r\\n\\r\\n\\t/// @notice Creates a new TrustScriptProductReviewAttester instance.\\r\\n\\t/// @param easAddress The address of the global EAS contract.\\r\\n\\t/// @param _productReviewSchemaUID The UID of the ProductReview schema.\\r\\n\\tconstructor(IEAS easAddress, bytes32 _productReviewSchemaUID) {\\r\\n\\t\\tif (address(easAddress) == address(0)) {\\r\\n\\t\\t\\trevert InvalidEAS();\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\teas = easAddress;\\r\\n\\t\\tproductReviewSchemaUID = _productReviewSchemaUID;\\r\\n\\t}\\r\\n\\r\\n\\t/// @notice Attests to a schema that receives a ProductReview parameter.\\r\\n\\t/// @param productReview The ProductReview value to pass to to the resolver.\\r\\n\\t/// @return attestationUID The UID of the new attestation.\\r\\n\\tfunction attestProductReview(\\r\\n\\t\\tProductReview memory productReview,\\r\\n\\t\\taddress sellerAddress\\r\\n\\t) external returns (bytes32 attestationUID) {\\r\\n\\t\\treturn\\r\\n\\t\\t\\teas.attest(\\r\\n\\t\\t\\t\\tAttestationRequest({\\r\\n\\t\\t\\t\\t\\tschema: productReviewSchemaUID,\\r\\n\\t\\t\\t\\t\\tdata: AttestationRequestData({\\r\\n\\t\\t\\t\\t\\t\\trecipient: sellerAddress,\\r\\n\\t\\t\\t\\t\\t\\texpirationTime: NO_EXPIRATION_TIME, // No expiration time\\r\\n\\t\\t\\t\\t\\t\\trevocable: true,\\r\\n\\t\\t\\t\\t\\t\\trefUID: EMPTY_UID, // No references UI\\r\\n\\t\\t\\t\\t\\t\\tdata: abi.encode(\\r\\n\\t\\t\\t\\t\\t\\t\\tproductReview.productId,\\r\\n\\t\\t\\t\\t\\t\\t\\tproductReview.buyerAddress,\\r\\n\\t\\t\\t\\t\\t\\t\\tproductReview.review\\r\\n\\t\\t\\t\\t\\t\\t),\\r\\n\\t\\t\\t\\t\\t\\tvalue: 0 // No value/ETH\\r\\n\\t\\t\\t\\t\\t})\\r\\n\\t\\t\\t\\t})\\r\\n\\t\\t\\t);\\r\\n\\r\\n\\t\\t// return\\r\\n\\t\\t// \\t0x3100000000000000000000000000000000000000000000000000000000000000;\\r\\n\\t}\\r\\n}\\r\\n\",\"keccak256\":\"0x89d2b81376f478edade5a39b2f27b2579a40daec74b2692a8f2c58bcb53dda20\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60c060405234801561001057600080fd5b506040516105b03803806105b083398101604081905261002f9161006c565b6001600160a01b038216610056576040516341bc07ff60e11b815260040160405180910390fd5b6001600160a01b0390911660805260a0526100a6565b6000806040838503121561007f57600080fd5b82516001600160a01b038116811461009657600080fd5b6020939093015192949293505050565b60805160a0516104da6100d66000396000818160b00152610110015260008181604b015260d601526104da6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80638150864d146100465780639eb254611461008a578063ba2aa1e9146100ab575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009d6100983660046102a0565b6100d2565b604051908152602001610081565b61009d7f000000000000000000000000000000000000000000000000000000000000000081565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f17325e760405180604001604052807f000000000000000000000000000000000000000000000000000000000000000081526020016040518060c00160405280876001600160a01b03168152602001600067ffffffffffffffff1681526020016001151581526020016000801b8152602001886000015189602001518a60400151604051602001610192939291906103d5565b604051602081830303815290604052815260200160008152508152506040518263ffffffff1660e01b81526004016101ca9190610408565b6020604051808303816000875af11580156101e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061020d919061048b565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561024d5761024d610214565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561027c5761027c610214565b604052919050565b80356001600160a01b038116811461029b57600080fd5b919050565b600080604083850312156102b357600080fd5b823567ffffffffffffffff808211156102cb57600080fd5b90840190606082870312156102df57600080fd5b6102e761022a565b8235815260206102f8818501610284565b8183015260408401358381111561030e57600080fd5b80850194505087601f85011261032357600080fd5b83358381111561033557610335610214565b610347601f8201601f19168301610253565b9350808452888282870101111561035d57600080fd5b8082860183860137600082828601015250826040830152819550610382818801610284565b9450505050509250929050565b6000815180845260005b818110156103b557602081850181015186830182015201610399565b506000602082860101526020601f19601f83011685010191505092915050565b8381526001600160a01b03831660208201526060604082018190526000906103ff9083018461038f565b95945050505050565b60208152815160208201526000602083015160408084015260018060a01b03815116606084015267ffffffffffffffff60208201511660808401526040810151151560a0840152606081015160c0840152608081015160c060e085015261047361012085018261038f565b905060a0820151610100850152809250505092915050565b60006020828403121561049d57600080fd5b505191905056fea26469706673582212206d1260541c85ee52112c165cfde16512bb9b269139158533283ad15f371b298364736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80638150864d146100465780639eb254611461008a578063ba2aa1e9146100ab575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009d6100983660046102a0565b6100d2565b604051908152602001610081565b61009d7f000000000000000000000000000000000000000000000000000000000000000081565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f17325e760405180604001604052807f000000000000000000000000000000000000000000000000000000000000000081526020016040518060c00160405280876001600160a01b03168152602001600067ffffffffffffffff1681526020016001151581526020016000801b8152602001886000015189602001518a60400151604051602001610192939291906103d5565b604051602081830303815290604052815260200160008152508152506040518263ffffffff1660e01b81526004016101ca9190610408565b6020604051808303816000875af11580156101e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061020d919061048b565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561024d5761024d610214565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561027c5761027c610214565b604052919050565b80356001600160a01b038116811461029b57600080fd5b919050565b600080604083850312156102b357600080fd5b823567ffffffffffffffff808211156102cb57600080fd5b90840190606082870312156102df57600080fd5b6102e761022a565b8235815260206102f8818501610284565b8183015260408401358381111561030e57600080fd5b80850194505087601f85011261032357600080fd5b83358381111561033557610335610214565b610347601f8201601f19168301610253565b9350808452888282870101111561035d57600080fd5b8082860183860137600082828601015250826040830152819550610382818801610284565b9450505050509250929050565b6000815180845260005b818110156103b557602081850181015186830182015201610399565b506000602082860101526020601f19601f83011685010191505092915050565b8381526001600160a01b03831660208201526060604082018190526000906103ff9083018461038f565b95945050505050565b60208152815160208201526000602083015160408084015260018060a01b03815116606084015267ffffffffffffffff60208201511660808401526040810151151560a0840152606081015160c0840152608081015160c060e085015261047361012085018261038f565b905060a0820151610100850152809250505092915050565b60006020828403121561049d57600080fd5b505191905056fea26469706673582212206d1260541c85ee52112c165cfde16512bb9b269139158533283ad15f371b298364736f6c63430008110033", + "devdoc": { + "kind": "dev", + "methods": { + "attestProductReview((uint256,address,string),address)": { + "params": { + "productReview": "The ProductReview value to pass to to the resolver." + }, + "returns": { + "attestationUID": "The UID of the new attestation." + } + }, + "constructor": { + "params": { + "_productReviewSchemaUID": "The UID of the ProductReview schema.", + "easAddress": "The address of the global EAS contract." + } + } + }, + "title": "TrustScriptProductReviewAttester", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "attestProductReview((uint256,address,string),address)": { + "notice": "Attests to a schema that receives a ProductReview parameter." + }, + "constructor": { + "notice": "Creates a new TrustScriptProductReviewAttester instance." + } + }, + "notice": "Ethereum Attestation Service - Example", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/baseSepolia/TrustScriptShop.json b/packages/hardhat/deployments/baseSepolia/TrustScriptShop.json new file mode 100644 index 000000000..b938e9140 --- /dev/null +++ b/packages/hardhat/deployments/baseSepolia/TrustScriptShop.json @@ -0,0 +1,1020 @@ +{ + "address": "0x97D12fC6cdfa2232AA5AEa3Eea9872ddE8D78E3D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "trustScriptTokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "trustScriptProductReviewAttesterAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "productId", + "type": "uint256" + } + ], + "name": "TrustScriptShop__ExistedProductId", + "type": "error" + }, + { + "inputs": [], + "name": "TrustScriptShop__FailedToSendETH", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "productId", + "type": "uint256" + } + ], + "name": "TrustScriptShop__NotExistedProductId", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "attesterAddress", + "type": "address" + } + ], + "name": "TrustScriptShop__UnauthorizedAttester", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOfETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "priceInETH", + "type": "uint256" + } + ], + "name": "TrustScriptShop__UnequalAmountOfETHAndPriceInETH", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOfToken", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "priceInToken", + "type": "uint256" + } + ], + "name": "TrustScriptShop__UnequalAmountOfTokenAndPriceInToken", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "priceInETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "priceInToken", + "type": "uint256" + } + ], + "name": "TrustScriptShop__UnequalPriceInETHAndPriceInToken", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "priceInETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "priceInToken", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct TrustScriptShop.Product", + "name": "product", + "type": "tuple" + } + ], + "name": "AddProduct", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "priceInETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "priceInToken", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct TrustScriptShop.Product", + "name": "product", + "type": "tuple" + } + ], + "name": "BuyProductWithETH", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "priceInETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "priceInToken", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct TrustScriptShop.Product", + "name": "product", + "type": "tuple" + } + ], + "name": "BuyProductWithToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOfToken", + "type": "uint256" + } + ], + "name": "MintTokenToBuyer", + "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": [ + { + "components": [ + { + "internalType": "uint256", + "name": "productId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "buyerAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "review", + "type": "string" + } + ], + "indexed": false, + "internalType": "struct ProductReview", + "name": "productReview", + "type": "tuple" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "uid", + "type": "bytes32" + } + ], + "name": "ReviewProduct", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amountOfETH", + "type": "uint256" + } + ], + "name": "WithdrawETH", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amountOfToken", + "type": "uint256" + } + ], + "name": "WithdrawToken", + "type": "event" + }, + { + "inputs": [], + "name": "REVIEW_PRODUCT_REWARD", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKENS_PER_ETH", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "priceInETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "priceInToken", + "type": "uint256" + } + ], + "internalType": "struct TrustScriptShop.Product", + "name": "product", + "type": "tuple" + } + ], + "name": "addProduct", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowedAttesters", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "buyProductWithETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOfToken", + "type": "uint256" + } + ], + "name": "buyProductWithToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAllProductReviews", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "productId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "buyerAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "review", + "type": "string" + } + ], + "internalType": "struct ProductReview[]", + "name": "allProductReviews", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllProducts", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "priceInETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "priceInToken", + "type": "uint256" + } + ], + "internalType": "struct TrustScriptShop.Product[]", + "name": "allProducts", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "numberOfProductReviews", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "numberOfProducts", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "productReviewsArray", + "outputs": [ + { + "internalType": "uint256", + "name": "productId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "buyerAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "review", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "products", + "outputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "priceInETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "priceInToken", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "productsArray", + "outputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "uint256", + "name": "priceInETH", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "priceInToken", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "productsMapping", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "string", + "name": "review", + "type": "string" + } + ], + "name": "reviewProduct", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "trustScriptProductReviewAttester", + "outputs": [ + { + "internalType": "contract TrustScriptProductReviewAttester", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "trustScriptToken", + "outputs": [ + { + "internalType": "contract TrustScriptToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xe746f57c06e63ca807f8486b16c71ba29e67de2d0dce42418c6b77ef4fb74430", + "receipt": { + "to": null, + "from": "0x35fAadD6fC68619b72A7Bfb871eDcC069C2f1bc3", + "contractAddress": "0x97D12fC6cdfa2232AA5AEa3Eea9872ddE8D78E3D", + "transactionIndex": 11, + "gasUsed": "1751632", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000010000000000000800000000000000000000000000000000400000000000000002000000000000000000000000000000000000000000000000000000000000400000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000800000000000000000", + "blockHash": "0xadcdd53a29bb18c8a7fe4abc963143558bfd60d5d0611b1221bac79d8e96e186", + "transactionHash": "0xe746f57c06e63ca807f8486b16c71ba29e67de2d0dce42418c6b77ef4fb74430", + "logs": [ + { + "transactionIndex": 11, + "blockNumber": 11672321, + "transactionHash": "0xe746f57c06e63ca807f8486b16c71ba29e67de2d0dce42418c6b77ef4fb74430", + "address": "0x97D12fC6cdfa2232AA5AEa3Eea9872ddE8D78E3D", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000035faadd6fc68619b72a7bfb871edcc069c2f1bc3" + ], + "data": "0x", + "logIndex": 4, + "blockHash": "0xadcdd53a29bb18c8a7fe4abc963143558bfd60d5d0611b1221bac79d8e96e186" + }, + { + "transactionIndex": 11, + "blockNumber": 11672321, + "transactionHash": "0xe746f57c06e63ca807f8486b16c71ba29e67de2d0dce42418c6b77ef4fb74430", + "address": "0x97D12fC6cdfa2232AA5AEa3Eea9872ddE8D78E3D", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x00000000000000000000000035faadd6fc68619b72a7bfb871edcc069c2f1bc3", + "0x00000000000000000000000035faadd6fc68619b72a7bfb871edcc069c2f1bc3" + ], + "data": "0x", + "logIndex": 5, + "blockHash": "0xadcdd53a29bb18c8a7fe4abc963143558bfd60d5d0611b1221bac79d8e96e186" + } + ], + "blockNumber": 11672321, + "cumulativeGasUsed": "2192218", + "status": 1, + "byzantium": true + }, + "args": [ + "0x35fAadD6fC68619b72A7Bfb871eDcC069C2f1bc3", + "0x519bFCA72320728dFfD698D9cE8b7FC6f4955431", + "0x80Eb3ccE63E5beDFe067e56e8c3dCCcbf1522247" + ], + "numDeployments": 1, + "solcInputHash": "600a4f1d04d1120bafc3a677d8e15185", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"trustScriptTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"trustScriptProductReviewAttesterAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"productId\",\"type\":\"uint256\"}],\"name\":\"TrustScriptShop__ExistedProductId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TrustScriptShop__FailedToSendETH\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"productId\",\"type\":\"uint256\"}],\"name\":\"TrustScriptShop__NotExistedProductId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"attesterAddress\",\"type\":\"address\"}],\"name\":\"TrustScriptShop__UnauthorizedAttester\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOfETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"priceInETH\",\"type\":\"uint256\"}],\"name\":\"TrustScriptShop__UnequalAmountOfETHAndPriceInETH\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amountOfToken\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"priceInToken\",\"type\":\"uint256\"}],\"name\":\"TrustScriptShop__UnequalAmountOfTokenAndPriceInToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"priceInETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"priceInToken\",\"type\":\"uint256\"}],\"name\":\"TrustScriptShop__UnequalPriceInETHAndPriceInToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"priceInETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"priceInToken\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct TrustScriptShop.Product\",\"name\":\"product\",\"type\":\"tuple\"}],\"name\":\"AddProduct\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"priceInETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"priceInToken\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct TrustScriptShop.Product\",\"name\":\"product\",\"type\":\"tuple\"}],\"name\":\"BuyProductWithETH\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"priceInETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"priceInToken\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct TrustScriptShop.Product\",\"name\":\"product\",\"type\":\"tuple\"}],\"name\":\"BuyProductWithToken\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOfToken\",\"type\":\"uint256\"}],\"name\":\"MintTokenToBuyer\",\"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\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"productId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"buyerAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"review\",\"type\":\"string\"}],\"indexed\":false,\"internalType\":\"struct ProductReview\",\"name\":\"productReview\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"uid\",\"type\":\"bytes32\"}],\"name\":\"ReviewProduct\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOfETH\",\"type\":\"uint256\"}],\"name\":\"WithdrawETH\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountOfToken\",\"type\":\"uint256\"}],\"name\":\"WithdrawToken\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"REVIEW_PRODUCT_REWARD\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKENS_PER_ETH\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"priceInETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"priceInToken\",\"type\":\"uint256\"}],\"internalType\":\"struct TrustScriptShop.Product\",\"name\":\"product\",\"type\":\"tuple\"}],\"name\":\"addProduct\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowedAttesters\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"buyProductWithETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOfToken\",\"type\":\"uint256\"}],\"name\":\"buyProductWithToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllProductReviews\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"productId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"buyerAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"review\",\"type\":\"string\"}],\"internalType\":\"struct ProductReview[]\",\"name\":\"allProductReviews\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllProducts\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"priceInETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"priceInToken\",\"type\":\"uint256\"}],\"internalType\":\"struct TrustScriptShop.Product[]\",\"name\":\"allProducts\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"numberOfProductReviews\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"numberOfProducts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"productReviewsArray\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"productId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"buyerAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"review\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"products\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"priceInETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"priceInToken\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"productsArray\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"priceInETH\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"priceInToken\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"productsMapping\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"review\",\"type\":\"string\"}],\"name\":\"reviewProduct\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trustScriptProductReviewAttester\",\"outputs\":[{\"internalType\":\"contract TrustScriptProductReviewAttester\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trustScriptToken\",\"outputs\":[{\"internalType\":\"contract TrustScriptToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawETH\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/TrustScriptShop.sol\":\"TrustScriptShop\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@ethereum-attestation-service/eas-contracts/contracts/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n// A representation of an empty/uninitialized UID.\\nbytes32 constant EMPTY_UID = 0;\\n\\n// A zero expiration represents an non-expiring attestation.\\nuint64 constant NO_EXPIRATION_TIME = 0;\\n\\nerror AccessDenied();\\nerror DeadlineExpired();\\nerror InvalidEAS();\\nerror InvalidLength();\\nerror InvalidSignature();\\nerror NotFound();\\n\\n/// @notice A struct representing ECDSA signature data.\\nstruct Signature {\\n uint8 v; // The recovery ID.\\n bytes32 r; // The x-coordinate of the nonce R.\\n bytes32 s; // The signature data.\\n}\\n\\n/// @notice A struct representing a single attestation.\\nstruct Attestation {\\n bytes32 uid; // A unique identifier of the attestation.\\n bytes32 schema; // The unique identifier of the schema.\\n uint64 time; // The time when the attestation was created (Unix timestamp).\\n uint64 expirationTime; // The time when the attestation expires (Unix timestamp).\\n uint64 revocationTime; // The time when the attestation was revoked (Unix timestamp).\\n bytes32 refUID; // The UID of the related attestation.\\n address recipient; // The recipient of the attestation.\\n address attester; // The attester/sender of the attestation.\\n bool revocable; // Whether the attestation is revocable.\\n bytes data; // Custom attestation data.\\n}\\n\\n/// @notice A helper function to work with unchecked iterators in loops.\\nfunction uncheckedInc(uint256 i) pure returns (uint256 j) {\\n unchecked {\\n j = i + 1;\\n }\\n}\\n\",\"keccak256\":\"0x957bd2e6d0d6d637f86208b135c29fbaf4412cb08e5e7a61ede16b80561bf685\",\"license\":\"MIT\"},\"@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport { ISchemaRegistry } from \\\"./ISchemaRegistry.sol\\\";\\nimport { ISemver } from \\\"./ISemver.sol\\\";\\nimport { Attestation, Signature } from \\\"./Common.sol\\\";\\n\\n/// @notice A struct representing the arguments of the attestation request.\\nstruct AttestationRequestData {\\n address recipient; // The recipient of the attestation.\\n uint64 expirationTime; // The time when the attestation expires (Unix timestamp).\\n bool revocable; // Whether the attestation is revocable.\\n bytes32 refUID; // The UID of the related attestation.\\n bytes data; // Custom attestation data.\\n uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user errors.\\n}\\n\\n/// @notice A struct representing the full arguments of the attestation request.\\nstruct AttestationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n AttestationRequestData data; // The arguments of the attestation request.\\n}\\n\\n/// @notice A struct representing the full arguments of the full delegated attestation request.\\nstruct DelegatedAttestationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n AttestationRequestData data; // The arguments of the attestation request.\\n Signature signature; // The ECDSA signature data.\\n address attester; // The attesting account.\\n uint64 deadline; // The deadline of the signature/request.\\n}\\n\\n/// @notice A struct representing the full arguments of the multi attestation request.\\nstruct MultiAttestationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n AttestationRequestData[] data; // The arguments of the attestation request.\\n}\\n\\n/// @notice A struct representing the full arguments of the delegated multi attestation request.\\nstruct MultiDelegatedAttestationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n AttestationRequestData[] data; // The arguments of the attestation requests.\\n Signature[] signatures; // The ECDSA signatures data. Please note that the signatures are assumed to be signed with increasing nonces.\\n address attester; // The attesting account.\\n uint64 deadline; // The deadline of the signature/request.\\n}\\n\\n/// @notice A struct representing the arguments of the revocation request.\\nstruct RevocationRequestData {\\n bytes32 uid; // The UID of the attestation to revoke.\\n uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user errors.\\n}\\n\\n/// @notice A struct representing the full arguments of the revocation request.\\nstruct RevocationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n RevocationRequestData data; // The arguments of the revocation request.\\n}\\n\\n/// @notice A struct representing the arguments of the full delegated revocation request.\\nstruct DelegatedRevocationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n RevocationRequestData data; // The arguments of the revocation request.\\n Signature signature; // The ECDSA signature data.\\n address revoker; // The revoking account.\\n uint64 deadline; // The deadline of the signature/request.\\n}\\n\\n/// @notice A struct representing the full arguments of the multi revocation request.\\nstruct MultiRevocationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n RevocationRequestData[] data; // The arguments of the revocation request.\\n}\\n\\n/// @notice A struct representing the full arguments of the delegated multi revocation request.\\nstruct MultiDelegatedRevocationRequest {\\n bytes32 schema; // The unique identifier of the schema.\\n RevocationRequestData[] data; // The arguments of the revocation requests.\\n Signature[] signatures; // The ECDSA signatures data. Please note that the signatures are assumed to be signed with increasing nonces.\\n address revoker; // The revoking account.\\n uint64 deadline; // The deadline of the signature/request.\\n}\\n\\n/// @title IEAS\\n/// @notice EAS - Ethereum Attestation Service interface.\\ninterface IEAS is ISemver {\\n /// @notice Emitted when an attestation has been made.\\n /// @param recipient The recipient of the attestation.\\n /// @param attester The attesting account.\\n /// @param uid The UID of the new attestation.\\n /// @param schemaUID The UID of the schema.\\n event Attested(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schemaUID);\\n\\n /// @notice Emitted when an attestation has been revoked.\\n /// @param recipient The recipient of the attestation.\\n /// @param attester The attesting account.\\n /// @param schemaUID The UID of the schema.\\n /// @param uid The UID the revoked attestation.\\n event Revoked(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schemaUID);\\n\\n /// @notice Emitted when a data has been timestamped.\\n /// @param data The data.\\n /// @param timestamp The timestamp.\\n event Timestamped(bytes32 indexed data, uint64 indexed timestamp);\\n\\n /// @notice Emitted when a data has been revoked.\\n /// @param revoker The address of the revoker.\\n /// @param data The data.\\n /// @param timestamp The timestamp.\\n event RevokedOffchain(address indexed revoker, bytes32 indexed data, uint64 indexed timestamp);\\n\\n /// @notice Returns the address of the global schema registry.\\n /// @return The address of the global schema registry.\\n function getSchemaRegistry() external view returns (ISchemaRegistry);\\n\\n /// @notice Attests to a specific schema.\\n /// @param request The arguments of the attestation request.\\n /// @return The UID of the new attestation.\\n ///\\n /// Example:\\n /// attest({\\n /// schema: \\\"0facc36681cbe2456019c1b0d1e7bedd6d1d40f6f324bf3dd3a4cef2999200a0\\\",\\n /// data: {\\n /// recipient: \\\"0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf\\\",\\n /// expirationTime: 0,\\n /// revocable: true,\\n /// refUID: \\\"0x0000000000000000000000000000000000000000000000000000000000000000\\\",\\n /// data: \\\"0xF00D\\\",\\n /// value: 0\\n /// }\\n /// })\\n function attest(AttestationRequest calldata request) external payable returns (bytes32);\\n\\n /// @notice Attests to a specific schema via the provided ECDSA signature.\\n /// @param delegatedRequest The arguments of the delegated attestation request.\\n /// @return The UID of the new attestation.\\n ///\\n /// Example:\\n /// attestByDelegation({\\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\\n /// data: {\\n /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\\n /// expirationTime: 1673891048,\\n /// revocable: true,\\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\\n /// data: '0x1234',\\n /// value: 0\\n /// },\\n /// signature: {\\n /// v: 28,\\n /// r: '0x148c...b25b',\\n /// s: '0x5a72...be22'\\n /// },\\n /// attester: '0xc5E8740aD971409492b1A63Db8d83025e0Fc427e',\\n /// deadline: 1673891048\\n /// })\\n function attestByDelegation(\\n DelegatedAttestationRequest calldata delegatedRequest\\n ) external payable returns (bytes32);\\n\\n /// @notice Attests to multiple schemas.\\n /// @param multiRequests The arguments of the multi attestation requests. The requests should be grouped by distinct\\n /// schema ids to benefit from the best batching optimization.\\n /// @return The UIDs of the new attestations.\\n ///\\n /// Example:\\n /// multiAttest([{\\n /// schema: '0x33e9094830a5cba5554d1954310e4fbed2ef5f859ec1404619adea4207f391fd',\\n /// data: [{\\n /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf',\\n /// expirationTime: 1673891048,\\n /// revocable: true,\\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\\n /// data: '0x1234',\\n /// value: 1000\\n /// },\\n /// {\\n /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\\n /// expirationTime: 0,\\n /// revocable: false,\\n /// refUID: '0x480df4a039efc31b11bfdf491b383ca138b6bde160988222a2a3509c02cee174',\\n /// data: '0x00',\\n /// value: 0\\n /// }],\\n /// },\\n /// {\\n /// schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425',\\n /// data: [{\\n /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf',\\n /// expirationTime: 0,\\n /// revocable: true,\\n /// refUID: '0x75bf2ed8dca25a8190c50c52db136664de25b2449535839008ccfdab469b214f',\\n /// data: '0x12345678',\\n /// value: 0\\n /// },\\n /// }])\\n function multiAttest(MultiAttestationRequest[] calldata multiRequests) external payable returns (bytes32[] memory);\\n\\n /// @notice Attests to multiple schemas using via provided ECDSA signatures.\\n /// @param multiDelegatedRequests The arguments of the delegated multi attestation requests. The requests should be\\n /// grouped by distinct schema ids to benefit from the best batching optimization.\\n /// @return The UIDs of the new attestations.\\n ///\\n /// Example:\\n /// multiAttestByDelegation([{\\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\\n /// data: [{\\n /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\\n /// expirationTime: 1673891048,\\n /// revocable: true,\\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\\n /// data: '0x1234',\\n /// value: 0\\n /// },\\n /// {\\n /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf',\\n /// expirationTime: 0,\\n /// revocable: false,\\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\\n /// data: '0x00',\\n /// value: 0\\n /// }],\\n /// signatures: [{\\n /// v: 28,\\n /// r: '0x148c...b25b',\\n /// s: '0x5a72...be22'\\n /// },\\n /// {\\n /// v: 28,\\n /// r: '0x487s...67bb',\\n /// s: '0x12ad...2366'\\n /// }],\\n /// attester: '0x1D86495b2A7B524D747d2839b3C645Bed32e8CF4',\\n /// deadline: 1673891048\\n /// }])\\n function multiAttestByDelegation(\\n MultiDelegatedAttestationRequest[] calldata multiDelegatedRequests\\n ) external payable returns (bytes32[] memory);\\n\\n /// @notice Revokes an existing attestation to a specific schema.\\n /// @param request The arguments of the revocation request.\\n ///\\n /// Example:\\n /// revoke({\\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\\n /// data: {\\n /// uid: '0x101032e487642ee04ee17049f99a70590c735b8614079fc9275f9dd57c00966d',\\n /// value: 0\\n /// }\\n /// })\\n function revoke(RevocationRequest calldata request) external payable;\\n\\n /// @notice Revokes an existing attestation to a specific schema via the provided ECDSA signature.\\n /// @param delegatedRequest The arguments of the delegated revocation request.\\n ///\\n /// Example:\\n /// revokeByDelegation({\\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\\n /// data: {\\n /// uid: '0xcbbc12102578c642a0f7b34fe7111e41afa25683b6cd7b5a14caf90fa14d24ba',\\n /// value: 0\\n /// },\\n /// signature: {\\n /// v: 27,\\n /// r: '0xb593...7142',\\n /// s: '0x0f5b...2cce'\\n /// },\\n /// revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992',\\n /// deadline: 1673891048\\n /// })\\n function revokeByDelegation(DelegatedRevocationRequest calldata delegatedRequest) external payable;\\n\\n /// @notice Revokes existing attestations to multiple schemas.\\n /// @param multiRequests The arguments of the multi revocation requests. The requests should be grouped by distinct\\n /// schema ids to benefit from the best batching optimization.\\n ///\\n /// Example:\\n /// multiRevoke([{\\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\\n /// data: [{\\n /// uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25',\\n /// value: 1000\\n /// },\\n /// {\\n /// uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade',\\n /// value: 0\\n /// }],\\n /// },\\n /// {\\n /// schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425',\\n /// data: [{\\n /// uid: '0x053d42abce1fd7c8fcddfae21845ad34dae287b2c326220b03ba241bc5a8f019',\\n /// value: 0\\n /// },\\n /// }])\\n function multiRevoke(MultiRevocationRequest[] calldata multiRequests) external payable;\\n\\n /// @notice Revokes existing attestations to multiple schemas via provided ECDSA signatures.\\n /// @param multiDelegatedRequests The arguments of the delegated multi revocation attestation requests. The requests\\n /// should be grouped by distinct schema ids to benefit from the best batching optimization.\\n ///\\n /// Example:\\n /// multiRevokeByDelegation([{\\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\\n /// data: [{\\n /// uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25',\\n /// value: 1000\\n /// },\\n /// {\\n /// uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade',\\n /// value: 0\\n /// }],\\n /// signatures: [{\\n /// v: 28,\\n /// r: '0x148c...b25b',\\n /// s: '0x5a72...be22'\\n /// },\\n /// {\\n /// v: 28,\\n /// r: '0x487s...67bb',\\n /// s: '0x12ad...2366'\\n /// }],\\n /// revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992',\\n /// deadline: 1673891048\\n /// }])\\n function multiRevokeByDelegation(\\n MultiDelegatedRevocationRequest[] calldata multiDelegatedRequests\\n ) external payable;\\n\\n /// @notice Timestamps the specified bytes32 data.\\n /// @param data The data to timestamp.\\n /// @return The timestamp the data was timestamped with.\\n function timestamp(bytes32 data) external returns (uint64);\\n\\n /// @notice Timestamps the specified multiple bytes32 data.\\n /// @param data The data to timestamp.\\n /// @return The timestamp the data was timestamped with.\\n function multiTimestamp(bytes32[] calldata data) external returns (uint64);\\n\\n /// @notice Revokes the specified bytes32 data.\\n /// @param data The data to timestamp.\\n /// @return The timestamp the data was revoked with.\\n function revokeOffchain(bytes32 data) external returns (uint64);\\n\\n /// @notice Revokes the specified multiple bytes32 data.\\n /// @param data The data to timestamp.\\n /// @return The timestamp the data was revoked with.\\n function multiRevokeOffchain(bytes32[] calldata data) external returns (uint64);\\n\\n /// @notice Returns an existing attestation by UID.\\n /// @param uid The UID of the attestation to retrieve.\\n /// @return The attestation data members.\\n function getAttestation(bytes32 uid) external view returns (Attestation memory);\\n\\n /// @notice Checks whether an attestation exists.\\n /// @param uid The UID of the attestation to retrieve.\\n /// @return Whether an attestation exists.\\n function isAttestationValid(bytes32 uid) external view returns (bool);\\n\\n /// @notice Returns the timestamp that the specified data was timestamped with.\\n /// @param data The data to query.\\n /// @return The timestamp the data was timestamped with.\\n function getTimestamp(bytes32 data) external view returns (uint64);\\n\\n /// @notice Returns the timestamp that the specified data was timestamped with.\\n /// @param data The data to query.\\n /// @return The timestamp the data was timestamped with.\\n function getRevokeOffchain(address revoker, bytes32 data) external view returns (uint64);\\n}\\n\",\"keccak256\":\"0xdad0674defce04905dc7935f2756d6c477a6e876c0b1b7094b112a862f164c12\",\"license\":\"MIT\"},\"@ethereum-attestation-service/eas-contracts/contracts/ISchemaRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport { ISemver } from \\\"./ISemver.sol\\\";\\n\\nimport { ISchemaResolver } from \\\"./resolver/ISchemaResolver.sol\\\";\\n\\n/// @notice A struct representing a record for a submitted schema.\\nstruct SchemaRecord {\\n bytes32 uid; // The unique identifier of the schema.\\n ISchemaResolver resolver; // Optional schema resolver.\\n bool revocable; // Whether the schema allows revocations explicitly.\\n string schema; // Custom specification of the schema (e.g., an ABI).\\n}\\n\\n/// @title ISchemaRegistry\\n/// @notice The interface of global attestation schemas for the Ethereum Attestation Service protocol.\\ninterface ISchemaRegistry is ISemver {\\n /// @notice Emitted when a new schema has been registered\\n /// @param uid The schema UID.\\n /// @param registerer The address of the account used to register the schema.\\n /// @param schema The schema data.\\n event Registered(bytes32 indexed uid, address indexed registerer, SchemaRecord schema);\\n\\n /// @notice Submits and reserves a new schema\\n /// @param schema The schema data schema.\\n /// @param resolver An optional schema resolver.\\n /// @param revocable Whether the schema allows revocations explicitly.\\n /// @return The UID of the new schema.\\n function register(string calldata schema, ISchemaResolver resolver, bool revocable) external returns (bytes32);\\n\\n /// @notice Returns an existing schema by UID\\n /// @param uid The UID of the schema to retrieve.\\n /// @return The schema data members.\\n function getSchema(bytes32 uid) external view returns (SchemaRecord memory);\\n}\\n\",\"keccak256\":\"0xea97dcd36a0c422169cbaac06698249e199049b627c16bff93fb8ab829058754\",\"license\":\"MIT\"},\"@ethereum-attestation-service/eas-contracts/contracts/ISemver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/// @title ISemver\\n/// @notice A semver interface.\\ninterface ISemver {\\n /// @notice Returns the full semver contract version.\\n /// @return Semver contract version as a string.\\n function version() external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x04a67939b4e1a8d0a51101b8f69f8882930bbdc66319f38023828625b5d1ff18\",\"license\":\"MIT\"},\"@ethereum-attestation-service/eas-contracts/contracts/resolver/ISchemaResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport { ISemver } from \\\"../ISemver.sol\\\";\\nimport { Attestation } from \\\"../Common.sol\\\";\\n\\n/// @title ISchemaResolver\\n/// @notice The interface of an optional schema resolver.\\ninterface ISchemaResolver is ISemver {\\n /// @notice Checks if the resolver can be sent ETH.\\n /// @return Whether the resolver supports ETH transfers.\\n function isPayable() external pure returns (bool);\\n\\n /// @notice Processes an attestation and verifies whether it's valid.\\n /// @param attestation The new attestation.\\n /// @return Whether the attestation is valid.\\n function attest(Attestation calldata attestation) external payable returns (bool);\\n\\n /// @notice Processes multiple attestations and verifies whether they are valid.\\n /// @param attestations The new attestations.\\n /// @param values Explicit ETH amounts which were sent with each attestation.\\n /// @return Whether all the attestations are valid.\\n function multiAttest(\\n Attestation[] calldata attestations,\\n uint256[] calldata values\\n ) external payable returns (bool);\\n\\n /// @notice Processes an attestation revocation and verifies if it can be revoked.\\n /// @param attestation The existing attestation to be revoked.\\n /// @return Whether the attestation can be revoked.\\n function revoke(Attestation calldata attestation) external payable returns (bool);\\n\\n /// @notice Processes revocation of multiple attestation and verifies they can be revoked.\\n /// @param attestations The existing attestations to be revoked.\\n /// @param values Explicit ETH amounts which were sent with each revocation.\\n /// @return Whether the attestations can be revoked.\\n function multiRevoke(\\n Attestation[] calldata attestations,\\n uint256[] calldata values\\n ) external payable returns (bool);\\n}\\n\",\"keccak256\":\"0x479f39f03425df5385d790cd2c7447b8250aeb9733d13029d3da8c5982b6604b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the default value returned by this function, unless\\n * it's overridden.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(address from, address to, uint256 amount) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n // decrementing then incrementing.\\n _balances[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n unchecked {\\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n _balances[account] += amount;\\n }\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n // Overflow not possible: amount <= accountBalance <= totalSupply.\\n _totalSupply -= amount;\\n }\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n}\\n\",\"keccak256\":\"0xa56ca923f70c1748830700250b19c61b70db9a683516dc5e216694a50445d99c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/TrustScriptProductReviewAttester.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\r\\npragma solidity >=0.8.0 <0.9.0;\\r\\n\\r\\nimport { IEAS, AttestationRequest, AttestationRequestData } from \\\"@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol\\\";\\r\\nimport { NO_EXPIRATION_TIME, EMPTY_UID } from \\\"@ethereum-attestation-service/eas-contracts/contracts/Common.sol\\\";\\r\\n\\r\\nstruct ProductReview {\\r\\n\\tuint256 productId;\\r\\n\\taddress buyerAddress;\\r\\n\\tstring review;\\r\\n}\\r\\n\\r\\n/// @title TrustScriptProductReviewAttester\\r\\n/// @notice Ethereum Attestation Service - Example\\r\\ncontract TrustScriptProductReviewAttester {\\r\\n\\t// The address of the global EAS contract.\\r\\n\\tIEAS public immutable eas;\\r\\n\\tbytes32 public immutable productReviewSchemaUID;\\r\\n\\r\\n\\terror InvalidEAS();\\r\\n\\r\\n\\t/// @notice Creates a new TrustScriptProductReviewAttester instance.\\r\\n\\t/// @param easAddress The address of the global EAS contract.\\r\\n\\t/// @param _productReviewSchemaUID The UID of the ProductReview schema.\\r\\n\\tconstructor(IEAS easAddress, bytes32 _productReviewSchemaUID) {\\r\\n\\t\\tif (address(easAddress) == address(0)) {\\r\\n\\t\\t\\trevert InvalidEAS();\\r\\n\\t\\t}\\r\\n\\r\\n\\t\\teas = easAddress;\\r\\n\\t\\tproductReviewSchemaUID = _productReviewSchemaUID;\\r\\n\\t}\\r\\n\\r\\n\\t/// @notice Attests to a schema that receives a ProductReview parameter.\\r\\n\\t/// @param productReview The ProductReview value to pass to to the resolver.\\r\\n\\t/// @return attestationUID The UID of the new attestation.\\r\\n\\tfunction attestProductReview(\\r\\n\\t\\tProductReview memory productReview,\\r\\n\\t\\taddress sellerAddress\\r\\n\\t) external returns (bytes32 attestationUID) {\\r\\n\\t\\treturn\\r\\n\\t\\t\\teas.attest(\\r\\n\\t\\t\\t\\tAttestationRequest({\\r\\n\\t\\t\\t\\t\\tschema: productReviewSchemaUID,\\r\\n\\t\\t\\t\\t\\tdata: AttestationRequestData({\\r\\n\\t\\t\\t\\t\\t\\trecipient: sellerAddress,\\r\\n\\t\\t\\t\\t\\t\\texpirationTime: NO_EXPIRATION_TIME, // No expiration time\\r\\n\\t\\t\\t\\t\\t\\trevocable: true,\\r\\n\\t\\t\\t\\t\\t\\trefUID: EMPTY_UID, // No references UI\\r\\n\\t\\t\\t\\t\\t\\tdata: abi.encode(\\r\\n\\t\\t\\t\\t\\t\\t\\tproductReview.productId,\\r\\n\\t\\t\\t\\t\\t\\t\\tproductReview.buyerAddress,\\r\\n\\t\\t\\t\\t\\t\\t\\tproductReview.review\\r\\n\\t\\t\\t\\t\\t\\t),\\r\\n\\t\\t\\t\\t\\t\\tvalue: 0 // No value/ETH\\r\\n\\t\\t\\t\\t\\t})\\r\\n\\t\\t\\t\\t})\\r\\n\\t\\t\\t);\\r\\n\\r\\n\\t\\t// return\\r\\n\\t\\t// \\t0x3100000000000000000000000000000000000000000000000000000000000000;\\r\\n\\t}\\r\\n}\\r\\n\",\"keccak256\":\"0x89d2b81376f478edade5a39b2f27b2579a40daec74b2692a8f2c58bcb53dda20\",\"license\":\"MIT\"},\"contracts/TrustScriptShop.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.0 <0.9.0;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"./TrustScriptToken.sol\\\";\\nimport \\\"./TrustScriptProductReviewAttester.sol\\\";\\n\\ncontract TrustScriptShop is Ownable {\\n\\tstruct Product {\\n\\t\\tuint256 id;\\n\\t\\tstring name;\\n\\t\\tuint256 priceInETH;\\n\\t\\tuint256 priceInToken;\\n\\t}\\n\\n\\tTrustScriptToken public trustScriptToken;\\n\\tuint256 public constant TOKENS_PER_ETH = 1000;\\n\\tuint256 public constant REVIEW_PRODUCT_REWARD = 5;\\n\\tmapping(uint256 => bool) public productsMapping;\\n\\tProduct[] public productsArray;\\n\\tmapping(uint256 => Product) public products;\\n\\tuint256 public numberOfProducts;\\n\\tProductReview[] public productReviewsArray;\\n\\tuint256 public numberOfProductReviews;\\n\\tmapping(address => bool) public allowedAttesters;\\n\\tTrustScriptProductReviewAttester public trustScriptProductReviewAttester;\\n\\n\\tevent AddProduct(Product product);\\n\\tevent BuyProductWithETH(Product product);\\n\\tevent BuyProductWithToken(Product product);\\n\\tevent ReviewProduct(ProductReview productReview, bytes32 uid);\\n\\tevent MintTokenToBuyer(address beneficiary, uint256 amountOfToken);\\n\\tevent WithdrawETH(uint256 amountOfETH);\\n\\tevent WithdrawToken(uint256 amountOfToken);\\n\\n\\terror TrustScriptShop__ExistedProductId(uint256 productId);\\n\\terror TrustScriptShop__NotExistedProductId(uint256 productId);\\n\\terror TrustScriptShop__UnequalPriceInETHAndPriceInToken(\\n\\t\\tuint256 priceInETH,\\n\\t\\tuint256 priceInToken\\n\\t);\\n\\terror TrustScriptShop__UnequalAmountOfETHAndPriceInETH(\\n\\t\\tuint256 amountOfETH,\\n\\t\\tuint256 priceInETH\\n\\t);\\n\\terror TrustScriptShop__UnequalAmountOfTokenAndPriceInToken(\\n\\t\\tuint256 amountOfToken,\\n\\t\\tuint256 priceInToken\\n\\t);\\n\\terror TrustScriptShop__FailedToSendETH();\\n\\terror TrustScriptShop__UnauthorizedAttester(address attesterAddress);\\n\\n\\tmodifier onlyAllowedAttesters() {\\n\\t\\tif (!allowedAttesters[msg.sender])\\n\\t\\t\\trevert TrustScriptShop__UnauthorizedAttester(msg.sender);\\n\\t\\t_;\\n\\t}\\n\\n\\tconstructor(\\n\\t\\taddress ownerAddress,\\n\\t\\taddress trustScriptTokenAddress,\\n\\t\\taddress trustScriptProductReviewAttesterAddress\\n\\t) {\\n\\t\\tsuper.transferOwnership(ownerAddress);\\n\\t\\ttrustScriptToken = TrustScriptToken(trustScriptTokenAddress);\\n\\t\\ttrustScriptProductReviewAttester = TrustScriptProductReviewAttester(\\n\\t\\t\\ttrustScriptProductReviewAttesterAddress\\n\\t\\t);\\n\\t}\\n\\n\\tfunction addProduct(Product memory product) public onlyOwner {\\n\\t\\tif (productsMapping[product.id]) {\\n\\t\\t\\trevert TrustScriptShop__ExistedProductId(product.id);\\n\\t\\t}\\n\\n\\t\\tif (\\n\\t\\t\\tproduct.priceInETH *\\n\\t\\t\\t\\tTOKENS_PER_ETH *\\n\\t\\t\\t\\t10 ** trustScriptToken.decimals() !=\\n\\t\\t\\tproduct.priceInToken * 1 ether\\n\\t\\t) {\\n\\t\\t\\trevert TrustScriptShop__UnequalPriceInETHAndPriceInToken(\\n\\t\\t\\t\\tproduct.priceInETH,\\n\\t\\t\\t\\tproduct.priceInToken\\n\\t\\t\\t);\\n\\t\\t}\\n\\n\\t\\tproductsMapping[product.id] = true;\\n\\t\\tproductsArray.push(product);\\n\\t\\tproducts[product.id] = product;\\n\\t\\tnumberOfProducts++;\\n\\n\\t\\temit AddProduct(product);\\n\\t}\\n\\n\\tfunction buyProductWithETH(uint256 id) public payable {\\n\\t\\tif (!productsMapping[id]) {\\n\\t\\t\\trevert TrustScriptShop__NotExistedProductId(id);\\n\\t\\t}\\n\\n\\t\\tuint256 priceInETH = products[id].priceInETH;\\n\\t\\tif (msg.value != priceInETH) {\\n\\t\\t\\trevert TrustScriptShop__UnequalAmountOfETHAndPriceInETH(\\n\\t\\t\\t\\tmsg.value,\\n\\t\\t\\t\\tpriceInETH\\n\\t\\t\\t);\\n\\t\\t}\\n\\n\\t\\tif (!allowedAttesters[msg.sender]) {\\n\\t\\t\\tallowedAttesters[msg.sender] = true;\\n\\t\\t}\\n\\n\\t\\t(bool success, ) = owner().call{ value: priceInETH }(\\\"\\\");\\n\\t\\tif (!success) {\\n\\t\\t\\trevert TrustScriptShop__FailedToSendETH();\\n\\t\\t}\\n\\n\\t\\temit BuyProductWithETH(products[id]);\\n\\t}\\n\\n\\tfunction buyProductWithToken(uint256 id, uint256 amountOfToken) public {\\n\\t\\tif (!productsMapping[id]) {\\n\\t\\t\\trevert TrustScriptShop__NotExistedProductId(id);\\n\\t\\t}\\n\\n\\t\\tuint256 priceInToken = products[id].priceInToken;\\n\\t\\tif (amountOfToken != priceInToken) {\\n\\t\\t\\trevert TrustScriptShop__UnequalAmountOfTokenAndPriceInToken(\\n\\t\\t\\t\\tamountOfToken,\\n\\t\\t\\t\\tpriceInToken\\n\\t\\t\\t);\\n\\t\\t}\\n\\n\\t\\tif (!allowedAttesters[msg.sender]) {\\n\\t\\t\\tallowedAttesters[msg.sender] = true;\\n\\t\\t}\\n\\n\\t\\ttrustScriptToken.transferFrom(msg.sender, owner(), amountOfToken);\\n\\n\\t\\temit BuyProductWithToken(products[id]);\\n\\t}\\n\\n\\tfunction reviewProduct(\\n\\t\\tuint256 id,\\n\\t\\tstring memory review\\n\\t) public onlyAllowedAttesters {\\n\\t\\tif (!productsMapping[id]) {\\n\\t\\t\\trevert TrustScriptShop__NotExistedProductId(id);\\n\\t\\t}\\n\\n\\t\\tProductReview memory productReview = ProductReview(\\n\\t\\t\\tid,\\n\\t\\t\\tmsg.sender,\\n\\t\\t\\treview\\n\\t\\t);\\n\\n\\t\\tbytes32 attestationUID = trustScriptProductReviewAttester\\n\\t\\t\\t.attestProductReview(productReview, owner());\\n\\n\\t\\temit ReviewProduct(productReview, attestationUID);\\n\\n\\t\\tproductReviewsArray.push(productReview);\\n\\t\\tnumberOfProductReviews++;\\n\\n\\t\\ttrustScriptToken.mint(\\n\\t\\t\\tmsg.sender,\\n\\t\\t\\tREVIEW_PRODUCT_REWARD * 10 ** trustScriptToken.decimals()\\n\\t\\t);\\n\\n\\t\\temit MintTokenToBuyer(msg.sender, REVIEW_PRODUCT_REWARD);\\n\\t}\\n\\n\\tfunction withdrawETH() public onlyOwner {\\n\\t\\tuint256 amountOfETH = address(this).balance;\\n\\n\\t\\t(bool success, ) = msg.sender.call{ value: amountOfETH }(\\\"\\\");\\n\\t\\tif (!success) {\\n\\t\\t\\trevert TrustScriptShop__FailedToSendETH();\\n\\t\\t}\\n\\n\\t\\temit WithdrawETH(amountOfETH);\\n\\t}\\n\\n\\tfunction withdrawToken() public onlyOwner {\\n\\t\\tuint256 amountOfToken = trustScriptToken.balanceOf(address(this));\\n\\t\\ttrustScriptToken.transfer(msg.sender, amountOfToken);\\n\\n\\t\\temit WithdrawToken(amountOfToken);\\n\\t}\\n\\n\\tfunction getAllProducts()\\n\\t\\tpublic\\n\\t\\tview\\n\\t\\treturns (Product[] memory allProducts)\\n\\t{\\n\\t\\tif (numberOfProducts == 0) {\\n\\t\\t\\treturn new Product[](0);\\n\\t\\t}\\n\\n\\t\\tallProducts = new Product[](numberOfProducts);\\n\\t\\tfor (uint i = 0; i < numberOfProducts; i++) {\\n\\t\\t\\tallProducts[i] = productsArray[i];\\n\\t\\t}\\n\\t\\treturn allProducts;\\n\\t}\\n\\n\\tfunction getAllProductReviews()\\n\\t\\tpublic\\n\\t\\tview\\n\\t\\treturns (ProductReview[] memory allProductReviews)\\n\\t{\\n\\t\\tif (numberOfProductReviews == 0) {\\n\\t\\t\\treturn new ProductReview[](0);\\n\\t\\t}\\n\\n\\t\\tallProductReviews = new ProductReview[](numberOfProductReviews);\\n\\t\\tfor (uint i = 0; i < numberOfProductReviews; i++) {\\n\\t\\t\\tallProductReviews[i] = productReviewsArray[i];\\n\\t\\t}\\n\\t\\treturn allProductReviews;\\n\\t}\\n}\\n\",\"keccak256\":\"0xcfedfd7ae58c6c3535b52d6d6eaa53a854704b8210dab5d5bb9ae4d945d60cf5\",\"license\":\"MIT\"},\"contracts/TrustScriptToken.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\r\\npragma solidity >=0.8.0 <0.9.0;\\r\\n\\r\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\r\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\r\\n\\r\\ncontract TrustScriptToken is ERC20, Ownable {\\r\\n\\tmapping(address => bool) public allowedMinters;\\r\\n\\r\\n\\terror TrustScriptToken__UnauthorizedMinter(address minterAddress);\\r\\n\\r\\n\\tmodifier onlyAllowedMinters() {\\r\\n\\t\\tif (!allowedMinters[msg.sender])\\r\\n\\t\\t\\trevert TrustScriptToken__UnauthorizedMinter(msg.sender);\\r\\n\\t\\t_;\\r\\n\\t}\\r\\n\\r\\n\\tconstructor(address ownerAddress) ERC20(\\\"TrustScript\\\", \\\"TST\\\") {\\r\\n\\t\\tsuper.transferOwnership(ownerAddress);\\r\\n\\r\\n\\t\\tallowedMinters[ownerAddress] = true;\\r\\n\\t\\t_mint(ownerAddress, 1000 * 10 ** decimals());\\r\\n\\t}\\r\\n\\r\\n\\tfunction mint(\\r\\n\\t\\taddress beneficiary,\\r\\n\\t\\tuint256 amountOfToken\\r\\n\\t) external onlyAllowedMinters {\\r\\n\\t\\t_mint(beneficiary, amountOfToken);\\r\\n\\t}\\r\\n\\r\\n\\tfunction allowMinter(address minter) public onlyOwner {\\r\\n\\t\\tallowedMinters[minter] = true;\\r\\n\\t}\\r\\n}\\r\\n\",\"keccak256\":\"0xbb4be08e629f3bff4090b0ddfedc3c12f91defce0c24e7f8ef59c1ac6d24ca0f\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b5060405162001f7738038062001f778339810160408190526200003491620001d6565b6200003f3362000088565b6200005583620000d860201b620014131760201c565b600180546001600160a01b039384166001600160a01b031991821617909155600980549290931691161790555062000220565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b620000e26200015b565b6001600160a01b0381166200014d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b620001588162000088565b50565b6000546001600160a01b03163314620001b75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000144565b565b80516001600160a01b0381168114620001d157600080fd5b919050565b600080600060608486031215620001ec57600080fd5b620001f784620001b9565b92506200020760208501620001b9565b91506200021760408501620001b9565b90509250925092565b611d4780620002306000396000f3fe6080604052600436106101355760003560e01c80637fede655116100ab578063bc6e66041161006f578063bc6e66041461038f578063c66301b2146103a5578063ca628c78146103bb578063d4bde5a4146103d0578063e086e5ec146103f0578063f2fde38b1461040557600080fd5b80637fede655146102ea5780638da5cb5b1461030c5780638ec8b9201461032a5780639209aba31461035a57806399f171a21461037a57600080fd5b806342ceec68116100fd57806342ceec68146101f65780634e20275114610216578063533fea02146102455780636b24808014610275578063715018a6146102b55780637acc0b20146102ca57600080fd5b806302ee3a521461013a5780630b048bf9146101655780630d0438e51461017a5780633d136ce61461019e578063408b464b146101d6575b600080fd5b34801561014657600080fd5b5061014f610425565b60405161015c91906115bb565b60405180910390f35b61017861017336600461161d565b610622565b005b34801561018657600080fd5b5061019060075481565b60405190815260200161015c565b3480156101aa57600080fd5b506001546101be906001600160a01b031681565b6040516001600160a01b03909116815260200161015c565b3480156101e257600080fd5b506101786101f13660046116d9565b610784565b34801561020257600080fd5b5061017861021136600461177d565b6109e2565b34801561022257600080fd5b5061023661023136600461161d565b610b5c565b60405161015c9392919061179f565b34801561025157600080fd5b5061026561026036600461161d565b610c25565b60405161015c94939291906117d2565b34801561028157600080fd5b506102a56102903660046117fe565b60086020526000908152604090205460ff1681565b604051901515815260200161015c565b3480156102c157600080fd5b50610178610ce9565b3480156102d657600080fd5b506102656102e536600461161d565b610cfd565b3480156102f657600080fd5b506102ff610d1f565b60405161015c9190611867565b34801561031857600080fd5b506000546001600160a01b03166101be565b34801561033657600080fd5b506102a561034536600461161d565b60026020526000908152604090205460ff1681565b34801561036657600080fd5b506101786103753660046118bc565b610f14565b34801561038657600080fd5b50610190600581565b34801561039b57600080fd5b506101906103e881565b3480156103b157600080fd5b5061019060055481565b3480156103c757600080fd5b5061017861124d565b3480156103dc57600080fd5b506009546101be906001600160a01b031681565b3480156103fc57600080fd5b50610178611369565b34801561041157600080fd5b506101786104203660046117fe565b611413565b606060055460000361048b576040805160008082526020820190925290610485565b6104726040518060800160405280600081526020016060815260200160008152602001600081525090565b8152602001906001900390816104475790505b50905090565b60055467ffffffffffffffff8111156104a6576104a6611636565b60405190808252806020026020018201604052801561050257816020015b6104ef6040518060800160405280600081526020016060815260200160008152602001600081525090565b8152602001906001900390816104c45790505b50905060005b60055481101561061e576003818154811061052557610525611903565b90600052602060002090600402016040518060800160405290816000820154815260200160018201805461055890611919565b80601f016020809104026020016040519081016040528092919081815260200182805461058490611919565b80156105d15780601f106105a6576101008083540402835291602001916105d1565b820191906000526020600020905b8154815290600101906020018083116105b457829003601f168201915b505050505081526020016002820154815260200160038201548152505082828151811061060057610600611903565b6020026020010181905250808061061690611969565b915050610508565b5090565b60008181526002602052604090205460ff16610659576040516307a9245160e31b8152600481018290526024015b60405180910390fd5b60008181526004602052604090206002015434811461069457604051630e937f8360e31b815234600482015260248101829052604401610650565b3360009081526008602052604090205460ff166106c657336000908152600860205260409020805460ff191660011790555b600080546040516001600160a01b039091169083908381818185875af1925050503d8060008114610713576040519150601f19603f3d011682016040523d82523d6000602084013e610718565b606091505b505090508061073a5760405163153eabe760e21b815260040160405180910390fd5b6000838152600460205260409081902090517f80b008c23ba396abd41f65d41a12010624d026bad3ccc607f74a049db22227829161077791611982565b60405180910390a1505050565b61078c61148c565b805160009081526002602052604090205460ff16156107c457805160405163041a639760e21b81526004810191909152602401610650565b60608101516107db90670de0b6b3a7640000611a35565b600160009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561082e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108529190611a52565b61085d90600a611b59565b6103e8836040015161086f9190611a35565b6108799190611a35565b146108ac5780604001518160600151604051630715c89760e21b8152600401610650929190918252602082015260400190565b805160009081526002602090815260408220805460ff19166001908117909155600380549182018155909252825160049092027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b8101928355908301518392917fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c01906109399082611bb7565b50604082810151600283015560609092015160039091015581516000908152600460209081529190208251815590820151829190600182019061097c9082611bb7565b5060408201516002820155606090910151600390910155600580549060006109a383611969565b91905055507f6081ab90273434d14cdb413a1372cf450edb167a43bd13f83192bac5c202e829816040516109d79190611c77565b60405180910390a150565b60008281526002602052604090205460ff16610a14576040516307a9245160e31b815260048101839052602401610650565b600082815260046020526040902060030154818114610a5057604051632839176f60e11b81526004810183905260248101829052604401610650565b3360009081526008602052604090205460ff16610a8257336000908152600860205260409020805460ff191660011790555b6001546001600160a01b03166323b872dd33610aa66000546001600160a01b031690565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604481018590526064016020604051808303816000875af1158015610afa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1e9190611c8a565b506000838152600460205260409081902090517f22480d75c984baa5c2c0864c88e2c5468b406560a6436d46cc009641e08073ee9161077791611982565b60068181548110610b6c57600080fd5b60009182526020909120600390910201805460018201546002830180549294506001600160a01b039091169291610ba290611919565b80601f0160208091040260200160405190810160405280929190818152602001828054610bce90611919565b8015610c1b5780601f10610bf057610100808354040283529160200191610c1b565b820191906000526020600020905b815481529060010190602001808311610bfe57829003601f168201915b5050505050905083565b60038181548110610c3557600080fd5b60009182526020909120600490910201805460018201805491935090610c5a90611919565b80601f0160208091040260200160405190810160405280929190818152602001828054610c8690611919565b8015610cd35780601f10610ca857610100808354040283529160200191610cd3565b820191906000526020600020905b815481529060010190602001808311610cb657829003601f168201915b5050505050908060020154908060030154905084565b610cf161148c565b610cfb60006114e6565b565b60046020526000908152604090208054600182018054919291610c5a90611919565b6060600754600003610d75576040805160008082526020820190925290610485565b60408051606080820183526000808352602083015291810191909152815260200190600190039081610d4157905050905090565b60075467ffffffffffffffff811115610d9057610d90611636565b604051908082528060200260200182016040528015610ddd57816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610dae5790505b50905060005b60075481101561061e5760068181548110610e0057610e00611903565b9060005260206000209060030201604051806060016040529081600082015481526020016001820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600282018054610e6290611919565b80601f0160208091040260200160405190810160405280929190818152602001828054610e8e90611919565b8015610edb5780601f10610eb057610100808354040283529160200191610edb565b820191906000526020600020905b815481529060010190602001808311610ebe57829003601f168201915b505050505081525050828281518110610ef657610ef6611903565b60200260200101819052508080610f0c90611969565b915050610de3565b3360009081526008602052604090205460ff16610f4657604051633a5e3bf960e01b8152336004820152602401610650565b60008281526002602052604090205460ff16610f78576040516307a9245160e31b815260048101839052602401610650565b604080516060810182528381523360208201529081018290526009546000906001600160a01b0316639eb2546183610fb86000546001600160a01b031690565b6040518363ffffffff1660e01b8152600401610fd5929190611cac565b6020604051808303816000875af1158015610ff4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110189190611cd6565b90507ff12d448b61b358eff802784abaa5526f0709c9af624e50e198979547d75125a4828260405161104b929190611cef565b60405180910390a16006805460018101825560009190915282517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f600390920291820190815560208401517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40830180546001600160a01b0319166001600160a01b03909216919091179055604084015184927ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d41019061110a9082611bb7565b5050600780549150600061111d83611969565b90915550506001546040805163313ce56760e01b815290516001600160a01b03909216916340c10f19913391849163313ce5679160048083019260209291908290030181865afa158015611175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111999190611a52565b6111a490600a611b59565b6111af906005611a35565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156111f557600080fd5b505af1158015611209573d6000803e3d6000fd5b505060408051338152600560208201527f1a628df0209a48522b66d5226782fac0327ed236ff817fdbcb20425bb97e32f3935001905060405180910390a150505050565b61125561148c565b6001546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561129e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c29190611cd6565b60015460405163a9059cbb60e01b8152336004820152602481018390529192506001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015611314573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113389190611c8a565b506040518181527fa4b910fb649c34bca8f9ecc6ba43090dbd1d14f3197d9f10ca054de15da71601906020016109d7565b61137161148c565b6040514790600090339083908381818185875af1925050503d80600081146113b5576040519150601f19603f3d011682016040523d82523d6000602084013e6113ba565b606091505b50509050806113dc5760405163153eabe760e21b815260040160405180910390fd5b6040518281527f94effa14ea3a1ef396fa2fd829336d1597f1d76b548c26bfa2332869706638af9060200160405180910390a15050565b61141b61148c565b6001600160a01b0381166114805760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610650565b611489816114e6565b50565b6000546001600160a01b03163314610cfb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610650565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000815180845260005b8181101561155c57602081850181015186830182015201611540565b506000602082860101526020601f19601f83011685010191505092915050565b80518252600060208201516080602085015261159b6080850182611536565b905060408301516040850152606083015160608501528091505092915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561161057603f198886030184526115fe85835161157c565b945092850192908501906001016115e2565b5092979650505050505050565b60006020828403121561162f57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261165d57600080fd5b813567ffffffffffffffff8082111561167857611678611636565b604051601f8301601f19908116603f011681019082821181831017156116a0576116a0611636565b816040528381528660208588010111156116b957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000602082840312156116eb57600080fd5b813567ffffffffffffffff8082111561170357600080fd5b908301906080828603121561171757600080fd5b60405160808101818110838211171561173257611732611636565b6040528235815260208301358281111561174b57600080fd5b6117578782860161164c565b602083015250604083013560408201526060830135606082015280935050505092915050565b6000806040838503121561179057600080fd5b50508035926020909101359150565b8381526001600160a01b03831660208201526060604082018190526000906117c990830184611536565b95945050505050565b8481526080602082015260006117eb6080830186611536565b6040830194909452506060015292915050565b60006020828403121561181057600080fd5b81356001600160a01b038116811461182757600080fd5b9392505050565b8051825260018060a01b036020820151166020830152600060408201516060604085015261185f6060850182611536565b949350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561161057603f198886030184526118aa85835161182e565b9450928501929085019060010161188e565b600080604083850312156118cf57600080fd5b82359150602083013567ffffffffffffffff8111156118ed57600080fd5b6118f98582860161164c565b9150509250929050565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061192d57607f821691505b60208210810361194d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60006001820161197b5761197b611953565b5060010190565b60006020808352835481840152600180850160806040860152600081546119a881611919565b8060a089015260c0858316600081146119c857600181146119e257611a10565b60ff1984168a83015282151560051b8a0182019450611a10565b856000528760002060005b84811015611a085781548c82018501529088019089016119ed565b8b0183019550505b5050505060028701546060870152600387015460808701528094505050505092915050565b8082028115828204841417611a4c57611a4c611953565b92915050565b600060208284031215611a6457600080fd5b815160ff8116811461182757600080fd5b600181815b80851115611ab0578160001904821115611a9657611a96611953565b80851615611aa357918102915b93841c9390800290611a7a565b509250929050565b600082611ac757506001611a4c565b81611ad457506000611a4c565b8160018114611aea5760028114611af457611b10565b6001915050611a4c565b60ff841115611b0557611b05611953565b50506001821b611a4c565b5060208310610133831016604e8410600b8410161715611b33575081810a611a4c565b611b3d8383611a75565b8060001904821115611b5157611b51611953565b029392505050565b600061182760ff841683611ab8565b601f821115611bb257600081815260208120601f850160051c81016020861015611b8f5750805b601f850160051c820191505b81811015611bae57828155600101611b9b565b5050505b505050565b815167ffffffffffffffff811115611bd157611bd1611636565b611be581611bdf8454611919565b84611b68565b602080601f831160018114611c1a5760008415611c025750858301515b600019600386901b1c1916600185901b178555611bae565b600085815260208120601f198616915b82811015611c4957888601518255948401946001909101908401611c2a565b5085821015611c675787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602081526000611827602083018461157c565b600060208284031215611c9c57600080fd5b8151801515811461182757600080fd5b604081526000611cbf604083018561182e565b905060018060a01b03831660208301529392505050565b600060208284031215611ce857600080fd5b5051919050565b604081526000611d02604083018561182e565b9050826020830152939250505056fea26469706673582212203a3e095763617b6095afbc42b5b6cdee8c1c4dc877832f9f43b15ae9d5a3cecc64736f6c63430008110033", + "deployedBytecode": "0x6080604052600436106101355760003560e01c80637fede655116100ab578063bc6e66041161006f578063bc6e66041461038f578063c66301b2146103a5578063ca628c78146103bb578063d4bde5a4146103d0578063e086e5ec146103f0578063f2fde38b1461040557600080fd5b80637fede655146102ea5780638da5cb5b1461030c5780638ec8b9201461032a5780639209aba31461035a57806399f171a21461037a57600080fd5b806342ceec68116100fd57806342ceec68146101f65780634e20275114610216578063533fea02146102455780636b24808014610275578063715018a6146102b55780637acc0b20146102ca57600080fd5b806302ee3a521461013a5780630b048bf9146101655780630d0438e51461017a5780633d136ce61461019e578063408b464b146101d6575b600080fd5b34801561014657600080fd5b5061014f610425565b60405161015c91906115bb565b60405180910390f35b61017861017336600461161d565b610622565b005b34801561018657600080fd5b5061019060075481565b60405190815260200161015c565b3480156101aa57600080fd5b506001546101be906001600160a01b031681565b6040516001600160a01b03909116815260200161015c565b3480156101e257600080fd5b506101786101f13660046116d9565b610784565b34801561020257600080fd5b5061017861021136600461177d565b6109e2565b34801561022257600080fd5b5061023661023136600461161d565b610b5c565b60405161015c9392919061179f565b34801561025157600080fd5b5061026561026036600461161d565b610c25565b60405161015c94939291906117d2565b34801561028157600080fd5b506102a56102903660046117fe565b60086020526000908152604090205460ff1681565b604051901515815260200161015c565b3480156102c157600080fd5b50610178610ce9565b3480156102d657600080fd5b506102656102e536600461161d565b610cfd565b3480156102f657600080fd5b506102ff610d1f565b60405161015c9190611867565b34801561031857600080fd5b506000546001600160a01b03166101be565b34801561033657600080fd5b506102a561034536600461161d565b60026020526000908152604090205460ff1681565b34801561036657600080fd5b506101786103753660046118bc565b610f14565b34801561038657600080fd5b50610190600581565b34801561039b57600080fd5b506101906103e881565b3480156103b157600080fd5b5061019060055481565b3480156103c757600080fd5b5061017861124d565b3480156103dc57600080fd5b506009546101be906001600160a01b031681565b3480156103fc57600080fd5b50610178611369565b34801561041157600080fd5b506101786104203660046117fe565b611413565b606060055460000361048b576040805160008082526020820190925290610485565b6104726040518060800160405280600081526020016060815260200160008152602001600081525090565b8152602001906001900390816104475790505b50905090565b60055467ffffffffffffffff8111156104a6576104a6611636565b60405190808252806020026020018201604052801561050257816020015b6104ef6040518060800160405280600081526020016060815260200160008152602001600081525090565b8152602001906001900390816104c45790505b50905060005b60055481101561061e576003818154811061052557610525611903565b90600052602060002090600402016040518060800160405290816000820154815260200160018201805461055890611919565b80601f016020809104026020016040519081016040528092919081815260200182805461058490611919565b80156105d15780601f106105a6576101008083540402835291602001916105d1565b820191906000526020600020905b8154815290600101906020018083116105b457829003601f168201915b505050505081526020016002820154815260200160038201548152505082828151811061060057610600611903565b6020026020010181905250808061061690611969565b915050610508565b5090565b60008181526002602052604090205460ff16610659576040516307a9245160e31b8152600481018290526024015b60405180910390fd5b60008181526004602052604090206002015434811461069457604051630e937f8360e31b815234600482015260248101829052604401610650565b3360009081526008602052604090205460ff166106c657336000908152600860205260409020805460ff191660011790555b600080546040516001600160a01b039091169083908381818185875af1925050503d8060008114610713576040519150601f19603f3d011682016040523d82523d6000602084013e610718565b606091505b505090508061073a5760405163153eabe760e21b815260040160405180910390fd5b6000838152600460205260409081902090517f80b008c23ba396abd41f65d41a12010624d026bad3ccc607f74a049db22227829161077791611982565b60405180910390a1505050565b61078c61148c565b805160009081526002602052604090205460ff16156107c457805160405163041a639760e21b81526004810191909152602401610650565b60608101516107db90670de0b6b3a7640000611a35565b600160009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561082e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108529190611a52565b61085d90600a611b59565b6103e8836040015161086f9190611a35565b6108799190611a35565b146108ac5780604001518160600151604051630715c89760e21b8152600401610650929190918252602082015260400190565b805160009081526002602090815260408220805460ff19166001908117909155600380549182018155909252825160049092027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b8101928355908301518392917fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c01906109399082611bb7565b50604082810151600283015560609092015160039091015581516000908152600460209081529190208251815590820151829190600182019061097c9082611bb7565b5060408201516002820155606090910151600390910155600580549060006109a383611969565b91905055507f6081ab90273434d14cdb413a1372cf450edb167a43bd13f83192bac5c202e829816040516109d79190611c77565b60405180910390a150565b60008281526002602052604090205460ff16610a14576040516307a9245160e31b815260048101839052602401610650565b600082815260046020526040902060030154818114610a5057604051632839176f60e11b81526004810183905260248101829052604401610650565b3360009081526008602052604090205460ff16610a8257336000908152600860205260409020805460ff191660011790555b6001546001600160a01b03166323b872dd33610aa66000546001600160a01b031690565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604481018590526064016020604051808303816000875af1158015610afa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1e9190611c8a565b506000838152600460205260409081902090517f22480d75c984baa5c2c0864c88e2c5468b406560a6436d46cc009641e08073ee9161077791611982565b60068181548110610b6c57600080fd5b60009182526020909120600390910201805460018201546002830180549294506001600160a01b039091169291610ba290611919565b80601f0160208091040260200160405190810160405280929190818152602001828054610bce90611919565b8015610c1b5780601f10610bf057610100808354040283529160200191610c1b565b820191906000526020600020905b815481529060010190602001808311610bfe57829003601f168201915b5050505050905083565b60038181548110610c3557600080fd5b60009182526020909120600490910201805460018201805491935090610c5a90611919565b80601f0160208091040260200160405190810160405280929190818152602001828054610c8690611919565b8015610cd35780601f10610ca857610100808354040283529160200191610cd3565b820191906000526020600020905b815481529060010190602001808311610cb657829003601f168201915b5050505050908060020154908060030154905084565b610cf161148c565b610cfb60006114e6565b565b60046020526000908152604090208054600182018054919291610c5a90611919565b6060600754600003610d75576040805160008082526020820190925290610485565b60408051606080820183526000808352602083015291810191909152815260200190600190039081610d4157905050905090565b60075467ffffffffffffffff811115610d9057610d90611636565b604051908082528060200260200182016040528015610ddd57816020015b60408051606080820183526000808352602083015291810191909152815260200190600190039081610dae5790505b50905060005b60075481101561061e5760068181548110610e0057610e00611903565b9060005260206000209060030201604051806060016040529081600082015481526020016001820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600282018054610e6290611919565b80601f0160208091040260200160405190810160405280929190818152602001828054610e8e90611919565b8015610edb5780601f10610eb057610100808354040283529160200191610edb565b820191906000526020600020905b815481529060010190602001808311610ebe57829003601f168201915b505050505081525050828281518110610ef657610ef6611903565b60200260200101819052508080610f0c90611969565b915050610de3565b3360009081526008602052604090205460ff16610f4657604051633a5e3bf960e01b8152336004820152602401610650565b60008281526002602052604090205460ff16610f78576040516307a9245160e31b815260048101839052602401610650565b604080516060810182528381523360208201529081018290526009546000906001600160a01b0316639eb2546183610fb86000546001600160a01b031690565b6040518363ffffffff1660e01b8152600401610fd5929190611cac565b6020604051808303816000875af1158015610ff4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110189190611cd6565b90507ff12d448b61b358eff802784abaa5526f0709c9af624e50e198979547d75125a4828260405161104b929190611cef565b60405180910390a16006805460018101825560009190915282517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f600390920291820190815560208401517ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40830180546001600160a01b0319166001600160a01b03909216919091179055604084015184927ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d41019061110a9082611bb7565b5050600780549150600061111d83611969565b90915550506001546040805163313ce56760e01b815290516001600160a01b03909216916340c10f19913391849163313ce5679160048083019260209291908290030181865afa158015611175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111999190611a52565b6111a490600a611b59565b6111af906005611a35565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156111f557600080fd5b505af1158015611209573d6000803e3d6000fd5b505060408051338152600560208201527f1a628df0209a48522b66d5226782fac0327ed236ff817fdbcb20425bb97e32f3935001905060405180910390a150505050565b61125561148c565b6001546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa15801561129e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c29190611cd6565b60015460405163a9059cbb60e01b8152336004820152602481018390529192506001600160a01b03169063a9059cbb906044016020604051808303816000875af1158015611314573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113389190611c8a565b506040518181527fa4b910fb649c34bca8f9ecc6ba43090dbd1d14f3197d9f10ca054de15da71601906020016109d7565b61137161148c565b6040514790600090339083908381818185875af1925050503d80600081146113b5576040519150601f19603f3d011682016040523d82523d6000602084013e6113ba565b606091505b50509050806113dc5760405163153eabe760e21b815260040160405180910390fd5b6040518281527f94effa14ea3a1ef396fa2fd829336d1597f1d76b548c26bfa2332869706638af9060200160405180910390a15050565b61141b61148c565b6001600160a01b0381166114805760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610650565b611489816114e6565b50565b6000546001600160a01b03163314610cfb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610650565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000815180845260005b8181101561155c57602081850181015186830182015201611540565b506000602082860101526020601f19601f83011685010191505092915050565b80518252600060208201516080602085015261159b6080850182611536565b905060408301516040850152606083015160608501528091505092915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561161057603f198886030184526115fe85835161157c565b945092850192908501906001016115e2565b5092979650505050505050565b60006020828403121561162f57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261165d57600080fd5b813567ffffffffffffffff8082111561167857611678611636565b604051601f8301601f19908116603f011681019082821181831017156116a0576116a0611636565b816040528381528660208588010111156116b957600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000602082840312156116eb57600080fd5b813567ffffffffffffffff8082111561170357600080fd5b908301906080828603121561171757600080fd5b60405160808101818110838211171561173257611732611636565b6040528235815260208301358281111561174b57600080fd5b6117578782860161164c565b602083015250604083013560408201526060830135606082015280935050505092915050565b6000806040838503121561179057600080fd5b50508035926020909101359150565b8381526001600160a01b03831660208201526060604082018190526000906117c990830184611536565b95945050505050565b8481526080602082015260006117eb6080830186611536565b6040830194909452506060015292915050565b60006020828403121561181057600080fd5b81356001600160a01b038116811461182757600080fd5b9392505050565b8051825260018060a01b036020820151166020830152600060408201516060604085015261185f6060850182611536565b949350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561161057603f198886030184526118aa85835161182e565b9450928501929085019060010161188e565b600080604083850312156118cf57600080fd5b82359150602083013567ffffffffffffffff8111156118ed57600080fd5b6118f98582860161164c565b9150509250929050565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061192d57607f821691505b60208210810361194d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60006001820161197b5761197b611953565b5060010190565b60006020808352835481840152600180850160806040860152600081546119a881611919565b8060a089015260c0858316600081146119c857600181146119e257611a10565b60ff1984168a83015282151560051b8a0182019450611a10565b856000528760002060005b84811015611a085781548c82018501529088019089016119ed565b8b0183019550505b5050505060028701546060870152600387015460808701528094505050505092915050565b8082028115828204841417611a4c57611a4c611953565b92915050565b600060208284031215611a6457600080fd5b815160ff8116811461182757600080fd5b600181815b80851115611ab0578160001904821115611a9657611a96611953565b80851615611aa357918102915b93841c9390800290611a7a565b509250929050565b600082611ac757506001611a4c565b81611ad457506000611a4c565b8160018114611aea5760028114611af457611b10565b6001915050611a4c565b60ff841115611b0557611b05611953565b50506001821b611a4c565b5060208310610133831016604e8410600b8410161715611b33575081810a611a4c565b611b3d8383611a75565b8060001904821115611b5157611b51611953565b029392505050565b600061182760ff841683611ab8565b601f821115611bb257600081815260208120601f850160051c81016020861015611b8f5750805b601f850160051c820191505b81811015611bae57828155600101611b9b565b5050505b505050565b815167ffffffffffffffff811115611bd157611bd1611636565b611be581611bdf8454611919565b84611b68565b602080601f831160018114611c1a5760008415611c025750858301515b600019600386901b1c1916600185901b178555611bae565b600085815260208120601f198616915b82811015611c4957888601518255948401946001909101908401611c2a565b5085821015611c675787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602081526000611827602083018461157c565b600060208284031215611c9c57600080fd5b8151801515811461182757600080fd5b604081526000611cbf604083018561182e565b905060018060a01b03831660208301529392505050565b600060208284031215611ce857600080fd5b5051919050565b604081526000611d02604083018561182e565b9050826020830152939250505056fea26469706673582212203a3e095763617b6095afbc42b5b6cdee8c1c4dc877832f9f43b15ae9d5a3cecc64736f6c63430008110033", + "devdoc": { + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 490, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 1419, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "trustScriptToken", + "offset": 0, + "slot": "1", + "type": "t_contract(TrustScriptToken)2104" + }, + { + "astId": 1429, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "productsMapping", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_uint256,t_bool)" + }, + { + "astId": 1433, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "productsArray", + "offset": 0, + "slot": "3", + "type": "t_array(t_struct(Product)1416_storage)dyn_storage" + }, + { + "astId": 1438, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "products", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_uint256,t_struct(Product)1416_storage)" + }, + { + "astId": 1440, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "numberOfProducts", + "offset": 0, + "slot": "5", + "type": "t_uint256" + }, + { + "astId": 1444, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "productReviewsArray", + "offset": 0, + "slot": "6", + "type": "t_array(t_struct(ProductReview)1323_storage)dyn_storage" + }, + { + "astId": 1446, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "numberOfProductReviews", + "offset": 0, + "slot": "7", + "type": "t_uint256" + }, + { + "astId": 1450, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "allowedAttesters", + "offset": 0, + "slot": "8", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 1453, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "trustScriptProductReviewAttester", + "offset": 0, + "slot": "9", + "type": "t_contract(TrustScriptProductReviewAttester)1399" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_struct(Product)1416_storage)dyn_storage": { + "base": "t_struct(Product)1416_storage", + "encoding": "dynamic_array", + "label": "struct TrustScriptShop.Product[]", + "numberOfBytes": "32" + }, + "t_array(t_struct(ProductReview)1323_storage)dyn_storage": { + "base": "t_struct(ProductReview)1323_storage", + "encoding": "dynamic_array", + "label": "struct ProductReview[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(TrustScriptProductReviewAttester)1399": { + "encoding": "inplace", + "label": "contract TrustScriptProductReviewAttester", + "numberOfBytes": "20" + }, + "t_contract(TrustScriptToken)2104": { + "encoding": "inplace", + "label": "contract TrustScriptToken", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_uint256,t_bool)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_uint256,t_struct(Product)1416_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct TrustScriptShop.Product)", + "numberOfBytes": "32", + "value": "t_struct(Product)1416_storage" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(Product)1416_storage": { + "encoding": "inplace", + "label": "struct TrustScriptShop.Product", + "members": [ + { + "astId": 1409, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "id", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 1411, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "name", + "offset": 0, + "slot": "1", + "type": "t_string_storage" + }, + { + "astId": 1413, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "priceInETH", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 1415, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "priceInToken", + "offset": 0, + "slot": "3", + "type": "t_uint256" + } + ], + "numberOfBytes": "128" + }, + "t_struct(ProductReview)1323_storage": { + "encoding": "inplace", + "label": "struct ProductReview", + "members": [ + { + "astId": 1318, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "productId", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 1320, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "buyerAddress", + "offset": 0, + "slot": "1", + "type": "t_address" + }, + { + "astId": 1322, + "contract": "contracts/TrustScriptShop.sol:TrustScriptShop", + "label": "review", + "offset": 0, + "slot": "2", + "type": "t_string_storage" + } + ], + "numberOfBytes": "96" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/baseSepolia/TrustScriptToken.json b/packages/hardhat/deployments/baseSepolia/TrustScriptToken.json new file mode 100644 index 000000000..1d63a02dc --- /dev/null +++ b/packages/hardhat/deployments/baseSepolia/TrustScriptToken.json @@ -0,0 +1,622 @@ +{ + "address": "0x519bFCA72320728dFfD698D9cE8b7FC6f4955431", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minterAddress", + "type": "address" + } + ], + "name": "TrustScriptToken__UnauthorizedMinter", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "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": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "allowMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "allowedMinters", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountOfToken", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "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": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xf993191a0eddde1ad99488a46e273e3d27cbc0037939790eb41f934e3da6900a", + "receipt": { + "to": null, + "from": "0x35fAadD6fC68619b72A7Bfb871eDcC069C2f1bc3", + "contractAddress": "0x519bFCA72320728dFfD698D9cE8b7FC6f4955431", + "transactionIndex": 8, + "gasUsed": "858691", + "logsBloom": "0x00000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000040000008000000000001000000000000000000000000000000000000020000010000000000000800000000000000000000000010000000400000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000002000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x448e643a7e6f74b4652e2cf707827b1e105416682e60074c76916804148c4593", + "transactionHash": "0xf993191a0eddde1ad99488a46e273e3d27cbc0037939790eb41f934e3da6900a", + "logs": [ + { + "transactionIndex": 8, + "blockNumber": 11672312, + "transactionHash": "0xf993191a0eddde1ad99488a46e273e3d27cbc0037939790eb41f934e3da6900a", + "address": "0x519bFCA72320728dFfD698D9cE8b7FC6f4955431", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000035faadd6fc68619b72a7bfb871edcc069c2f1bc3" + ], + "data": "0x", + "logIndex": 7, + "blockHash": "0x448e643a7e6f74b4652e2cf707827b1e105416682e60074c76916804148c4593" + }, + { + "transactionIndex": 8, + "blockNumber": 11672312, + "transactionHash": "0xf993191a0eddde1ad99488a46e273e3d27cbc0037939790eb41f934e3da6900a", + "address": "0x519bFCA72320728dFfD698D9cE8b7FC6f4955431", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x00000000000000000000000035faadd6fc68619b72a7bfb871edcc069c2f1bc3", + "0x00000000000000000000000035faadd6fc68619b72a7bfb871edcc069c2f1bc3" + ], + "data": "0x", + "logIndex": 8, + "blockHash": "0x448e643a7e6f74b4652e2cf707827b1e105416682e60074c76916804148c4593" + }, + { + "transactionIndex": 8, + "blockNumber": 11672312, + "transactionHash": "0xf993191a0eddde1ad99488a46e273e3d27cbc0037939790eb41f934e3da6900a", + "address": "0x519bFCA72320728dFfD698D9cE8b7FC6f4955431", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000035faadd6fc68619b72a7bfb871edcc069c2f1bc3" + ], + "data": "0x00000000000000000000000000000000000000000000003635c9adc5dea00000", + "logIndex": 9, + "blockHash": "0x448e643a7e6f74b4652e2cf707827b1e105416682e60074c76916804148c4593" + } + ], + "blockNumber": 11672312, + "cumulativeGasUsed": "7040829", + "status": 1, + "byzantium": true + }, + "args": [ + "0x35fAadD6fC68619b72A7Bfb871eDcC069C2f1bc3" + ], + "numDeployments": 1, + "solcInputHash": "052ccf5d10a20ebd6f28e37c1f387e26", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minterAddress\",\"type\":\"address\"}],\"name\":\"TrustScriptToken__UnauthorizedMinter\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"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\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"allowMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowedMinters\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountOfToken\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"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\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/TrustScriptToken.sol\":\"TrustScriptToken\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the default value returned by this function, unless\\n * it's overridden.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(address from, address to, uint256 amount) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n // decrementing then incrementing.\\n _balances[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n unchecked {\\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n _balances[account] += amount;\\n }\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n // Overflow not possible: amount <= accountBalance <= totalSupply.\\n _totalSupply -= amount;\\n }\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n}\\n\",\"keccak256\":\"0xa56ca923f70c1748830700250b19c61b70db9a683516dc5e216694a50445d99c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/TrustScriptToken.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\r\\npragma solidity >=0.8.0 <0.9.0;\\r\\n\\r\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\r\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\r\\n\\r\\ncontract TrustScriptToken is ERC20, Ownable {\\r\\n\\tmapping(address => bool) public allowedMinters;\\r\\n\\r\\n\\terror TrustScriptToken__UnauthorizedMinter(address minterAddress);\\r\\n\\r\\n\\tmodifier onlyAllowedMinters() {\\r\\n\\t\\tif (!allowedMinters[msg.sender])\\r\\n\\t\\t\\trevert TrustScriptToken__UnauthorizedMinter(msg.sender);\\r\\n\\t\\t_;\\r\\n\\t}\\r\\n\\r\\n\\tconstructor(address ownerAddress) ERC20(\\\"TrustScript\\\", \\\"TST\\\") {\\r\\n\\t\\tsuper.transferOwnership(ownerAddress);\\r\\n\\r\\n\\t\\tallowedMinters[ownerAddress] = true;\\r\\n\\t\\t_mint(ownerAddress, 1000 * 10 ** decimals());\\r\\n\\t}\\r\\n\\r\\n\\tfunction mint(\\r\\n\\t\\taddress beneficiary,\\r\\n\\t\\tuint256 amountOfToken\\r\\n\\t) external onlyAllowedMinters {\\r\\n\\t\\t_mint(beneficiary, amountOfToken);\\r\\n\\t}\\r\\n\\r\\n\\tfunction allowMinter(address minter) public onlyOwner {\\r\\n\\t\\tallowedMinters[minter] = true;\\r\\n\\t}\\r\\n}\\r\\n\",\"keccak256\":\"0xbb4be08e629f3bff4090b0ddfedc3c12f91defce0c24e7f8ef59c1ac6d24ca0f\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50604051620011c0380380620011c083398101604081905262000034916200031f565b6040518060400160405280600b81526020016a151c9d5cdd14d8dc9a5c1d60aa1b815250604051806040016040528060038152602001621514d560ea1b8152508160039081620000859190620003f5565b506004620000948282620003f5565b505050620000b1620000ab6200012060201b60201c565b62000124565b620000c7816200017660201b620004bd1760201c565b6001600160a01b0381166000908152600660205260409020805460ff191660011790556200011981620000f8601290565b6200010590600a620005d6565b62000113906103e8620005e7565b620001f9565b5062000617565b3390565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b62000180620002bc565b6001600160a01b038116620001eb5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b620001f68162000124565b50565b6001600160a01b038216620002515760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401620001e2565b806002600082825462000265919062000601565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6005546001600160a01b03163314620003185760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620001e2565b565b505050565b6000602082840312156200033257600080fd5b81516001600160a01b03811681146200034a57600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200037c57607f821691505b6020821081036200039d57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200031a57600081815260208120601f850160051c81016020861015620003cc5750805b601f850160051c820191505b81811015620003ed57828155600101620003d8565b505050505050565b81516001600160401b0381111562000411576200041162000351565b620004298162000422845462000367565b84620003a3565b602080601f831160018114620004615760008415620004485750858301515b600019600386901b1c1916600185901b178555620003ed565b600085815260208120601f198616915b82811015620004925788860151825594840194600190910190840162000471565b5085821015620004b15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000518578160001904821115620004fc57620004fc620004c1565b808516156200050a57918102915b93841c9390800290620004dc565b509250929050565b6000826200053157506001620005d0565b816200054057506000620005d0565b8160018114620005595760028114620005645762000584565b6001915050620005d0565b60ff841115620005785762000578620004c1565b50506001821b620005d0565b5060208310610133831016604e8410600b8410161715620005a9575081810a620005d0565b620005b58383620004d7565b8060001904821115620005cc57620005cc620004c1565b0290505b92915050565b60006200034a60ff84168362000520565b8082028115828204841417620005d057620005d0620004c1565b80820180821115620005d057620005d0620004c1565b610b9980620006276000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c8063423afa66116100a257806395d89b411161007157806395d89b411461022f578063a457c2d714610237578063a9059cbb1461024a578063dd62ed3e1461025d578063f2fde38b1461027057600080fd5b8063423afa66146101c057806370a08231146101e3578063715018a61461020c5780638da5cb5b1461021457600080fd5b806323b872dd116100de57806323b872dd14610178578063313ce5671461018b578063395093511461019a57806340c10f19146101ad57600080fd5b806306fdde0314610110578063095ea7b31461012e578063150a64801461015157806318160ddd14610166575b600080fd5b610118610283565b60405161012591906109e3565b60405180910390f35b61014161013c366004610a4d565b610315565b6040519015158152602001610125565b61016461015f366004610a77565b61032f565b005b6002545b604051908152602001610125565b610141610186366004610a99565b61035b565b60405160128152602001610125565b6101416101a8366004610a4d565b61037f565b6101646101bb366004610a4d565b6103a1565b6101416101ce366004610a77565b60066020526000908152604090205460ff1681565b61016a6101f1366004610a77565b6001600160a01b031660009081526020819052604090205490565b6101646103e6565b6005546040516001600160a01b039091168152602001610125565b6101186103fa565b610141610245366004610a4d565b610409565b610141610258366004610a4d565b610484565b61016a61026b366004610ad5565b610492565b61016461027e366004610a77565b6104bd565b60606003805461029290610b08565b80601f01602080910402602001604051908101604052809291908181526020018280546102be90610b08565b801561030b5780601f106102e05761010080835404028352916020019161030b565b820191906000526020600020905b8154815290600101906020018083116102ee57829003601f168201915b5050505050905090565b600033610323818585610536565b60019150505b92915050565b61033761065a565b6001600160a01b03166000908152600660205260409020805460ff19166001179055565b6000336103698582856106b4565b61037485858561072e565b506001949350505050565b6000336103238185856103928383610492565b61039c9190610b42565b610536565b3360009081526006602052604090205460ff166103d85760405163d7da78e360e01b81523360048201526024015b60405180910390fd5b6103e282826108d2565b5050565b6103ee61065a565b6103f86000610991565b565b60606004805461029290610b08565b600033816104178286610492565b9050838110156104775760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016103cf565b6103748286868403610536565b60003361032381858561072e565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6104c561065a565b6001600160a01b03811661052a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103cf565b61053381610991565b50565b6001600160a01b0383166105985760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016103cf565b6001600160a01b0382166105f95760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016103cf565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6005546001600160a01b031633146103f85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103cf565b60006106c08484610492565b90506000198114610728578181101561071b5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103cf565b6107288484848403610536565b50505050565b6001600160a01b0383166107925760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016103cf565b6001600160a01b0382166107f45760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016103cf565b6001600160a01b0383166000908152602081905260409020548181101561086c5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016103cf565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610728565b6001600160a01b0382166109285760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016103cf565b806002600082825461093a9190610b42565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060208083528351808285015260005b81811015610a10578581018301518582016040015282016109f4565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610a4857600080fd5b919050565b60008060408385031215610a6057600080fd5b610a6983610a31565b946020939093013593505050565b600060208284031215610a8957600080fd5b610a9282610a31565b9392505050565b600080600060608486031215610aae57600080fd5b610ab784610a31565b9250610ac560208501610a31565b9150604084013590509250925092565b60008060408385031215610ae857600080fd5b610af183610a31565b9150610aff60208401610a31565b90509250929050565b600181811c90821680610b1c57607f821691505b602082108103610b3c57634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561032957634e487b7160e01b600052601160045260246000fdfea264697066735822122039fd26f8189ef846cc35bdf62da14295381b36f88773b2dfbb1f41204afc4b6164736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061010b5760003560e01c8063423afa66116100a257806395d89b411161007157806395d89b411461022f578063a457c2d714610237578063a9059cbb1461024a578063dd62ed3e1461025d578063f2fde38b1461027057600080fd5b8063423afa66146101c057806370a08231146101e3578063715018a61461020c5780638da5cb5b1461021457600080fd5b806323b872dd116100de57806323b872dd14610178578063313ce5671461018b578063395093511461019a57806340c10f19146101ad57600080fd5b806306fdde0314610110578063095ea7b31461012e578063150a64801461015157806318160ddd14610166575b600080fd5b610118610283565b60405161012591906109e3565b60405180910390f35b61014161013c366004610a4d565b610315565b6040519015158152602001610125565b61016461015f366004610a77565b61032f565b005b6002545b604051908152602001610125565b610141610186366004610a99565b61035b565b60405160128152602001610125565b6101416101a8366004610a4d565b61037f565b6101646101bb366004610a4d565b6103a1565b6101416101ce366004610a77565b60066020526000908152604090205460ff1681565b61016a6101f1366004610a77565b6001600160a01b031660009081526020819052604090205490565b6101646103e6565b6005546040516001600160a01b039091168152602001610125565b6101186103fa565b610141610245366004610a4d565b610409565b610141610258366004610a4d565b610484565b61016a61026b366004610ad5565b610492565b61016461027e366004610a77565b6104bd565b60606003805461029290610b08565b80601f01602080910402602001604051908101604052809291908181526020018280546102be90610b08565b801561030b5780601f106102e05761010080835404028352916020019161030b565b820191906000526020600020905b8154815290600101906020018083116102ee57829003601f168201915b5050505050905090565b600033610323818585610536565b60019150505b92915050565b61033761065a565b6001600160a01b03166000908152600660205260409020805460ff19166001179055565b6000336103698582856106b4565b61037485858561072e565b506001949350505050565b6000336103238185856103928383610492565b61039c9190610b42565b610536565b3360009081526006602052604090205460ff166103d85760405163d7da78e360e01b81523360048201526024015b60405180910390fd5b6103e282826108d2565b5050565b6103ee61065a565b6103f86000610991565b565b60606004805461029290610b08565b600033816104178286610492565b9050838110156104775760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016103cf565b6103748286868403610536565b60003361032381858561072e565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6104c561065a565b6001600160a01b03811661052a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103cf565b61053381610991565b50565b6001600160a01b0383166105985760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016103cf565b6001600160a01b0382166105f95760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016103cf565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6005546001600160a01b031633146103f85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103cf565b60006106c08484610492565b90506000198114610728578181101561071b5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016103cf565b6107288484848403610536565b50505050565b6001600160a01b0383166107925760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016103cf565b6001600160a01b0382166107f45760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016103cf565b6001600160a01b0383166000908152602081905260409020548181101561086c5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016103cf565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610728565b6001600160a01b0382166109285760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016103cf565b806002600082825461093a9190610b42565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060208083528351808285015260005b81811015610a10578581018301518582016040015282016109f4565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610a4857600080fd5b919050565b60008060408385031215610a6057600080fd5b610a6983610a31565b946020939093013593505050565b600060208284031215610a8957600080fd5b610a9282610a31565b9392505050565b600080600060608486031215610aae57600080fd5b610ab784610a31565b9250610ac560208501610a31565b9150604084013590509250925092565b60008060408385031215610ae857600080fd5b610af183610a31565b9150610aff60208401610a31565b90509250929050565b600181811c90821680610b1c57607f821691505b602082108103610b3c57634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561032957634e487b7160e01b600052601160045260246000fdfea264697066735822122039fd26f8189ef846cc35bdf62da14295381b36f88773b2dfbb1f41204afc4b6164736f6c63430008110033", + "devdoc": { + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "decimals()": { + "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "name()": { + "details": "Returns the name of the token." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 611, + "contract": "contracts/TrustScriptToken.sol:TrustScriptToken", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 617, + "contract": "contracts/TrustScriptToken.sol:TrustScriptToken", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 619, + "contract": "contracts/TrustScriptToken.sol:TrustScriptToken", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 621, + "contract": "contracts/TrustScriptToken.sol:TrustScriptToken", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 623, + "contract": "contracts/TrustScriptToken.sol:TrustScriptToken", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + }, + { + "astId": 490, + "contract": "contracts/TrustScriptToken.sol:TrustScriptToken", + "label": "_owner", + "offset": 0, + "slot": "5", + "type": "t_address" + }, + { + "astId": 1919, + "contract": "contracts/TrustScriptToken.sol:TrustScriptToken", + "label": "allowedMinters", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_bool)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/baseSepolia/solcInputs/052ccf5d10a20ebd6f28e37c1f387e26.json b/packages/hardhat/deployments/baseSepolia/solcInputs/052ccf5d10a20ebd6f28e37c1f387e26.json new file mode 100644 index 000000000..006fe4157 --- /dev/null +++ b/packages/hardhat/deployments/baseSepolia/solcInputs/052ccf5d10a20ebd6f28e37c1f387e26.json @@ -0,0 +1,71 @@ +{ + "language": "Solidity", + "sources": { + "@ethereum-attestation-service/eas-contracts/contracts/Common.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// A representation of an empty/uninitialized UID.\nbytes32 constant EMPTY_UID = 0;\n\n// A zero expiration represents an non-expiring attestation.\nuint64 constant NO_EXPIRATION_TIME = 0;\n\nerror AccessDenied();\nerror DeadlineExpired();\nerror InvalidEAS();\nerror InvalidLength();\nerror InvalidSignature();\nerror NotFound();\n\n/// @notice A struct representing ECDSA signature data.\nstruct Signature {\n uint8 v; // The recovery ID.\n bytes32 r; // The x-coordinate of the nonce R.\n bytes32 s; // The signature data.\n}\n\n/// @notice A struct representing a single attestation.\nstruct Attestation {\n bytes32 uid; // A unique identifier of the attestation.\n bytes32 schema; // The unique identifier of the schema.\n uint64 time; // The time when the attestation was created (Unix timestamp).\n uint64 expirationTime; // The time when the attestation expires (Unix timestamp).\n uint64 revocationTime; // The time when the attestation was revoked (Unix timestamp).\n bytes32 refUID; // The UID of the related attestation.\n address recipient; // The recipient of the attestation.\n address attester; // The attester/sender of the attestation.\n bool revocable; // Whether the attestation is revocable.\n bytes data; // Custom attestation data.\n}\n\n/// @notice A helper function to work with unchecked iterators in loops.\nfunction uncheckedInc(uint256 i) pure returns (uint256 j) {\n unchecked {\n j = i + 1;\n }\n}\n" + }, + "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { ISchemaRegistry } from \"./ISchemaRegistry.sol\";\nimport { ISemver } from \"./ISemver.sol\";\nimport { Attestation, Signature } from \"./Common.sol\";\n\n/// @notice A struct representing the arguments of the attestation request.\nstruct AttestationRequestData {\n address recipient; // The recipient of the attestation.\n uint64 expirationTime; // The time when the attestation expires (Unix timestamp).\n bool revocable; // Whether the attestation is revocable.\n bytes32 refUID; // The UID of the related attestation.\n bytes data; // Custom attestation data.\n uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user errors.\n}\n\n/// @notice A struct representing the full arguments of the attestation request.\nstruct AttestationRequest {\n bytes32 schema; // The unique identifier of the schema.\n AttestationRequestData data; // The arguments of the attestation request.\n}\n\n/// @notice A struct representing the full arguments of the full delegated attestation request.\nstruct DelegatedAttestationRequest {\n bytes32 schema; // The unique identifier of the schema.\n AttestationRequestData data; // The arguments of the attestation request.\n Signature signature; // The ECDSA signature data.\n address attester; // The attesting account.\n uint64 deadline; // The deadline of the signature/request.\n}\n\n/// @notice A struct representing the full arguments of the multi attestation request.\nstruct MultiAttestationRequest {\n bytes32 schema; // The unique identifier of the schema.\n AttestationRequestData[] data; // The arguments of the attestation request.\n}\n\n/// @notice A struct representing the full arguments of the delegated multi attestation request.\nstruct MultiDelegatedAttestationRequest {\n bytes32 schema; // The unique identifier of the schema.\n AttestationRequestData[] data; // The arguments of the attestation requests.\n Signature[] signatures; // The ECDSA signatures data. Please note that the signatures are assumed to be signed with increasing nonces.\n address attester; // The attesting account.\n uint64 deadline; // The deadline of the signature/request.\n}\n\n/// @notice A struct representing the arguments of the revocation request.\nstruct RevocationRequestData {\n bytes32 uid; // The UID of the attestation to revoke.\n uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user errors.\n}\n\n/// @notice A struct representing the full arguments of the revocation request.\nstruct RevocationRequest {\n bytes32 schema; // The unique identifier of the schema.\n RevocationRequestData data; // The arguments of the revocation request.\n}\n\n/// @notice A struct representing the arguments of the full delegated revocation request.\nstruct DelegatedRevocationRequest {\n bytes32 schema; // The unique identifier of the schema.\n RevocationRequestData data; // The arguments of the revocation request.\n Signature signature; // The ECDSA signature data.\n address revoker; // The revoking account.\n uint64 deadline; // The deadline of the signature/request.\n}\n\n/// @notice A struct representing the full arguments of the multi revocation request.\nstruct MultiRevocationRequest {\n bytes32 schema; // The unique identifier of the schema.\n RevocationRequestData[] data; // The arguments of the revocation request.\n}\n\n/// @notice A struct representing the full arguments of the delegated multi revocation request.\nstruct MultiDelegatedRevocationRequest {\n bytes32 schema; // The unique identifier of the schema.\n RevocationRequestData[] data; // The arguments of the revocation requests.\n Signature[] signatures; // The ECDSA signatures data. Please note that the signatures are assumed to be signed with increasing nonces.\n address revoker; // The revoking account.\n uint64 deadline; // The deadline of the signature/request.\n}\n\n/// @title IEAS\n/// @notice EAS - Ethereum Attestation Service interface.\ninterface IEAS is ISemver {\n /// @notice Emitted when an attestation has been made.\n /// @param recipient The recipient of the attestation.\n /// @param attester The attesting account.\n /// @param uid The UID of the new attestation.\n /// @param schemaUID The UID of the schema.\n event Attested(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schemaUID);\n\n /// @notice Emitted when an attestation has been revoked.\n /// @param recipient The recipient of the attestation.\n /// @param attester The attesting account.\n /// @param schemaUID The UID of the schema.\n /// @param uid The UID the revoked attestation.\n event Revoked(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schemaUID);\n\n /// @notice Emitted when a data has been timestamped.\n /// @param data The data.\n /// @param timestamp The timestamp.\n event Timestamped(bytes32 indexed data, uint64 indexed timestamp);\n\n /// @notice Emitted when a data has been revoked.\n /// @param revoker The address of the revoker.\n /// @param data The data.\n /// @param timestamp The timestamp.\n event RevokedOffchain(address indexed revoker, bytes32 indexed data, uint64 indexed timestamp);\n\n /// @notice Returns the address of the global schema registry.\n /// @return The address of the global schema registry.\n function getSchemaRegistry() external view returns (ISchemaRegistry);\n\n /// @notice Attests to a specific schema.\n /// @param request The arguments of the attestation request.\n /// @return The UID of the new attestation.\n ///\n /// Example:\n /// attest({\n /// schema: \"0facc36681cbe2456019c1b0d1e7bedd6d1d40f6f324bf3dd3a4cef2999200a0\",\n /// data: {\n /// recipient: \"0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf\",\n /// expirationTime: 0,\n /// revocable: true,\n /// refUID: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n /// data: \"0xF00D\",\n /// value: 0\n /// }\n /// })\n function attest(AttestationRequest calldata request) external payable returns (bytes32);\n\n /// @notice Attests to a specific schema via the provided ECDSA signature.\n /// @param delegatedRequest The arguments of the delegated attestation request.\n /// @return The UID of the new attestation.\n ///\n /// Example:\n /// attestByDelegation({\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\n /// data: {\n /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\n /// expirationTime: 1673891048,\n /// revocable: true,\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\n /// data: '0x1234',\n /// value: 0\n /// },\n /// signature: {\n /// v: 28,\n /// r: '0x148c...b25b',\n /// s: '0x5a72...be22'\n /// },\n /// attester: '0xc5E8740aD971409492b1A63Db8d83025e0Fc427e',\n /// deadline: 1673891048\n /// })\n function attestByDelegation(\n DelegatedAttestationRequest calldata delegatedRequest\n ) external payable returns (bytes32);\n\n /// @notice Attests to multiple schemas.\n /// @param multiRequests The arguments of the multi attestation requests. The requests should be grouped by distinct\n /// schema ids to benefit from the best batching optimization.\n /// @return The UIDs of the new attestations.\n ///\n /// Example:\n /// multiAttest([{\n /// schema: '0x33e9094830a5cba5554d1954310e4fbed2ef5f859ec1404619adea4207f391fd',\n /// data: [{\n /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf',\n /// expirationTime: 1673891048,\n /// revocable: true,\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\n /// data: '0x1234',\n /// value: 1000\n /// },\n /// {\n /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\n /// expirationTime: 0,\n /// revocable: false,\n /// refUID: '0x480df4a039efc31b11bfdf491b383ca138b6bde160988222a2a3509c02cee174',\n /// data: '0x00',\n /// value: 0\n /// }],\n /// },\n /// {\n /// schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425',\n /// data: [{\n /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf',\n /// expirationTime: 0,\n /// revocable: true,\n /// refUID: '0x75bf2ed8dca25a8190c50c52db136664de25b2449535839008ccfdab469b214f',\n /// data: '0x12345678',\n /// value: 0\n /// },\n /// }])\n function multiAttest(MultiAttestationRequest[] calldata multiRequests) external payable returns (bytes32[] memory);\n\n /// @notice Attests to multiple schemas using via provided ECDSA signatures.\n /// @param multiDelegatedRequests The arguments of the delegated multi attestation requests. The requests should be\n /// grouped by distinct schema ids to benefit from the best batching optimization.\n /// @return The UIDs of the new attestations.\n ///\n /// Example:\n /// multiAttestByDelegation([{\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\n /// data: [{\n /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\n /// expirationTime: 1673891048,\n /// revocable: true,\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\n /// data: '0x1234',\n /// value: 0\n /// },\n /// {\n /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf',\n /// expirationTime: 0,\n /// revocable: false,\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\n /// data: '0x00',\n /// value: 0\n /// }],\n /// signatures: [{\n /// v: 28,\n /// r: '0x148c...b25b',\n /// s: '0x5a72...be22'\n /// },\n /// {\n /// v: 28,\n /// r: '0x487s...67bb',\n /// s: '0x12ad...2366'\n /// }],\n /// attester: '0x1D86495b2A7B524D747d2839b3C645Bed32e8CF4',\n /// deadline: 1673891048\n /// }])\n function multiAttestByDelegation(\n MultiDelegatedAttestationRequest[] calldata multiDelegatedRequests\n ) external payable returns (bytes32[] memory);\n\n /// @notice Revokes an existing attestation to a specific schema.\n /// @param request The arguments of the revocation request.\n ///\n /// Example:\n /// revoke({\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\n /// data: {\n /// uid: '0x101032e487642ee04ee17049f99a70590c735b8614079fc9275f9dd57c00966d',\n /// value: 0\n /// }\n /// })\n function revoke(RevocationRequest calldata request) external payable;\n\n /// @notice Revokes an existing attestation to a specific schema via the provided ECDSA signature.\n /// @param delegatedRequest The arguments of the delegated revocation request.\n ///\n /// Example:\n /// revokeByDelegation({\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\n /// data: {\n /// uid: '0xcbbc12102578c642a0f7b34fe7111e41afa25683b6cd7b5a14caf90fa14d24ba',\n /// value: 0\n /// },\n /// signature: {\n /// v: 27,\n /// r: '0xb593...7142',\n /// s: '0x0f5b...2cce'\n /// },\n /// revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992',\n /// deadline: 1673891048\n /// })\n function revokeByDelegation(DelegatedRevocationRequest calldata delegatedRequest) external payable;\n\n /// @notice Revokes existing attestations to multiple schemas.\n /// @param multiRequests The arguments of the multi revocation requests. The requests should be grouped by distinct\n /// schema ids to benefit from the best batching optimization.\n ///\n /// Example:\n /// multiRevoke([{\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\n /// data: [{\n /// uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25',\n /// value: 1000\n /// },\n /// {\n /// uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade',\n /// value: 0\n /// }],\n /// },\n /// {\n /// schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425',\n /// data: [{\n /// uid: '0x053d42abce1fd7c8fcddfae21845ad34dae287b2c326220b03ba241bc5a8f019',\n /// value: 0\n /// },\n /// }])\n function multiRevoke(MultiRevocationRequest[] calldata multiRequests) external payable;\n\n /// @notice Revokes existing attestations to multiple schemas via provided ECDSA signatures.\n /// @param multiDelegatedRequests The arguments of the delegated multi revocation attestation requests. The requests\n /// should be grouped by distinct schema ids to benefit from the best batching optimization.\n ///\n /// Example:\n /// multiRevokeByDelegation([{\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\n /// data: [{\n /// uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25',\n /// value: 1000\n /// },\n /// {\n /// uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade',\n /// value: 0\n /// }],\n /// signatures: [{\n /// v: 28,\n /// r: '0x148c...b25b',\n /// s: '0x5a72...be22'\n /// },\n /// {\n /// v: 28,\n /// r: '0x487s...67bb',\n /// s: '0x12ad...2366'\n /// }],\n /// revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992',\n /// deadline: 1673891048\n /// }])\n function multiRevokeByDelegation(\n MultiDelegatedRevocationRequest[] calldata multiDelegatedRequests\n ) external payable;\n\n /// @notice Timestamps the specified bytes32 data.\n /// @param data The data to timestamp.\n /// @return The timestamp the data was timestamped with.\n function timestamp(bytes32 data) external returns (uint64);\n\n /// @notice Timestamps the specified multiple bytes32 data.\n /// @param data The data to timestamp.\n /// @return The timestamp the data was timestamped with.\n function multiTimestamp(bytes32[] calldata data) external returns (uint64);\n\n /// @notice Revokes the specified bytes32 data.\n /// @param data The data to timestamp.\n /// @return The timestamp the data was revoked with.\n function revokeOffchain(bytes32 data) external returns (uint64);\n\n /// @notice Revokes the specified multiple bytes32 data.\n /// @param data The data to timestamp.\n /// @return The timestamp the data was revoked with.\n function multiRevokeOffchain(bytes32[] calldata data) external returns (uint64);\n\n /// @notice Returns an existing attestation by UID.\n /// @param uid The UID of the attestation to retrieve.\n /// @return The attestation data members.\n function getAttestation(bytes32 uid) external view returns (Attestation memory);\n\n /// @notice Checks whether an attestation exists.\n /// @param uid The UID of the attestation to retrieve.\n /// @return Whether an attestation exists.\n function isAttestationValid(bytes32 uid) external view returns (bool);\n\n /// @notice Returns the timestamp that the specified data was timestamped with.\n /// @param data The data to query.\n /// @return The timestamp the data was timestamped with.\n function getTimestamp(bytes32 data) external view returns (uint64);\n\n /// @notice Returns the timestamp that the specified data was timestamped with.\n /// @param data The data to query.\n /// @return The timestamp the data was timestamped with.\n function getRevokeOffchain(address revoker, bytes32 data) external view returns (uint64);\n}\n" + }, + "@ethereum-attestation-service/eas-contracts/contracts/ISchemaRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { ISemver } from \"./ISemver.sol\";\n\nimport { ISchemaResolver } from \"./resolver/ISchemaResolver.sol\";\n\n/// @notice A struct representing a record for a submitted schema.\nstruct SchemaRecord {\n bytes32 uid; // The unique identifier of the schema.\n ISchemaResolver resolver; // Optional schema resolver.\n bool revocable; // Whether the schema allows revocations explicitly.\n string schema; // Custom specification of the schema (e.g., an ABI).\n}\n\n/// @title ISchemaRegistry\n/// @notice The interface of global attestation schemas for the Ethereum Attestation Service protocol.\ninterface ISchemaRegistry is ISemver {\n /// @notice Emitted when a new schema has been registered\n /// @param uid The schema UID.\n /// @param registerer The address of the account used to register the schema.\n /// @param schema The schema data.\n event Registered(bytes32 indexed uid, address indexed registerer, SchemaRecord schema);\n\n /// @notice Submits and reserves a new schema\n /// @param schema The schema data schema.\n /// @param resolver An optional schema resolver.\n /// @param revocable Whether the schema allows revocations explicitly.\n /// @return The UID of the new schema.\n function register(string calldata schema, ISchemaResolver resolver, bool revocable) external returns (bytes32);\n\n /// @notice Returns an existing schema by UID\n /// @param uid The UID of the schema to retrieve.\n /// @return The schema data members.\n function getSchema(bytes32 uid) external view returns (SchemaRecord memory);\n}\n" + }, + "@ethereum-attestation-service/eas-contracts/contracts/ISemver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @title ISemver\n/// @notice A semver interface.\ninterface ISemver {\n /// @notice Returns the full semver contract version.\n /// @return Semver contract version as a string.\n function version() external view returns (string memory);\n}\n" + }, + "@ethereum-attestation-service/eas-contracts/contracts/resolver/ISchemaResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { ISemver } from \"../ISemver.sol\";\nimport { Attestation } from \"../Common.sol\";\n\n/// @title ISchemaResolver\n/// @notice The interface of an optional schema resolver.\ninterface ISchemaResolver is ISemver {\n /// @notice Checks if the resolver can be sent ETH.\n /// @return Whether the resolver supports ETH transfers.\n function isPayable() external pure returns (bool);\n\n /// @notice Processes an attestation and verifies whether it's valid.\n /// @param attestation The new attestation.\n /// @return Whether the attestation is valid.\n function attest(Attestation calldata attestation) external payable returns (bool);\n\n /// @notice Processes multiple attestations and verifies whether they are valid.\n /// @param attestations The new attestations.\n /// @param values Explicit ETH amounts which were sent with each attestation.\n /// @return Whether all the attestations are valid.\n function multiAttest(\n Attestation[] calldata attestations,\n uint256[] calldata values\n ) external payable returns (bool);\n\n /// @notice Processes an attestation revocation and verifies if it can be revoked.\n /// @param attestation The existing attestation to be revoked.\n /// @return Whether the attestation can be revoked.\n function revoke(Attestation calldata attestation) external payable returns (bool);\n\n /// @notice Processes revocation of multiple attestation and verifies they can be revoked.\n /// @param attestations The existing attestations to be revoked.\n /// @param values Explicit ETH amounts which were sent with each revocation.\n /// @return Whether the attestations can be revoked.\n function multiRevoke(\n Attestation[] calldata attestations,\n uint256[] calldata values\n ) external payable returns (bool);\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/TrustScriptProductReviewAttester.sol": { + "content": "//SPDX-License-Identifier: MIT\r\npragma solidity >=0.8.0 <0.9.0;\r\n\r\nimport { IEAS, AttestationRequest, AttestationRequestData } from \"@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol\";\r\nimport { NO_EXPIRATION_TIME, EMPTY_UID } from \"@ethereum-attestation-service/eas-contracts/contracts/Common.sol\";\r\n\r\nstruct ProductReview {\r\n\tuint256 productId;\r\n\taddress buyerAddress;\r\n\tstring review;\r\n}\r\n\r\n/// @title TrustScriptProductReviewAttester\r\n/// @notice Ethereum Attestation Service - Example\r\ncontract TrustScriptProductReviewAttester {\r\n\t// The address of the global EAS contract.\r\n\tIEAS public immutable eas;\r\n\tbytes32 public immutable productReviewSchemaUID;\r\n\r\n\terror InvalidEAS();\r\n\r\n\t/// @notice Creates a new TrustScriptProductReviewAttester instance.\r\n\t/// @param easAddress The address of the global EAS contract.\r\n\t/// @param _productReviewSchemaUID The UID of the ProductReview schema.\r\n\tconstructor(IEAS easAddress, bytes32 _productReviewSchemaUID) {\r\n\t\tif (address(easAddress) == address(0)) {\r\n\t\t\trevert InvalidEAS();\r\n\t\t}\r\n\r\n\t\teas = easAddress;\r\n\t\tproductReviewSchemaUID = _productReviewSchemaUID;\r\n\t}\r\n\r\n\t/// @notice Attests to a schema that receives a ProductReview parameter.\r\n\t/// @param productReview The ProductReview value to pass to to the resolver.\r\n\t/// @return attestationUID The UID of the new attestation.\r\n\tfunction attestProductReview(\r\n\t\tProductReview memory productReview,\r\n\t\taddress sellerAddress\r\n\t) external returns (bytes32 attestationUID) {\r\n\t\t// return\r\n\t\t// \teas.attest(\r\n\t\t// \t\tAttestationRequest({\r\n\t\t// \t\t\tschema: productReviewSchemaUID,\r\n\t\t// \t\t\tdata: AttestationRequestData({\r\n\t\t// \t\t\t\trecipient: sellerAddress,\r\n\t\t// \t\t\t\texpirationTime: NO_EXPIRATION_TIME, // No expiration time\r\n\t\t// \t\t\t\trevocable: true,\r\n\t\t// \t\t\t\trefUID: EMPTY_UID, // No references UI\r\n\t\t// \t\t\t\tdata: abi.encode(\r\n\t\t// \t\t\t\t\tproductReview.productId,\r\n\t\t// \t\t\t\t\tproductReview.buyerAddress,\r\n\t\t// \t\t\t\t\tproductReview.review\r\n\t\t// \t\t\t\t),\r\n\t\t// \t\t\t\tvalue: 0 // No value/ETH\r\n\t\t// \t\t\t})\r\n\t\t// \t\t})\r\n\t\t// \t);\r\n\r\n\t\treturn\r\n\t\t\t0x3100000000000000000000000000000000000000000000000000000000000000;\r\n\t}\r\n}\r\n" + }, + "contracts/TrustScriptShop.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.0 <0.9.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./TrustScriptToken.sol\";\nimport \"./TrustScriptProductReviewAttester.sol\";\n\ncontract TrustScriptShop is Ownable {\n\tstruct Product {\n\t\tuint256 id;\n\t\tstring name;\n\t\tuint256 priceInETH;\n\t\tuint256 priceInToken;\n\t}\n\n\tTrustScriptToken public trustScriptToken;\n\tuint256 public constant TOKENS_PER_ETH = 1000;\n\tmapping(uint256 => bool) public productsMapping;\n\tProduct[] public productsArray;\n\tmapping(uint256 => Product) public products;\n\tuint256 public numberOfProducts;\n\tmapping(address => bool) public allowedAttesters;\n\tTrustScriptProductReviewAttester public trustScriptProductReviewAttester;\n\n\terror TrustScriptShop__ExistedProductId(uint256 productId);\n\terror TrustScriptShop__NotExistedProductId(uint256 productId);\n\terror TrustScriptShop__UnequalPriceInETHAndPriceInToken(\n\t\tuint256 priceInETH,\n\t\tuint256 priceInToken\n\t);\n\terror TrustScriptShop__UnequalAmountOfETHAndPriceInETH(\n\t\tuint256 amountOfETH,\n\t\tuint256 priceInETH\n\t);\n\terror TrustScriptShop__UnequalAmountOfTokenAndPriceInToken(\n\t\tuint256 amountOfToken,\n\t\tuint256 priceInToken\n\t);\n\terror TrustScriptShop__FailedToSendETH();\n\terror TrustScriptShop__UnauthorizedAttester(address attesterAddress);\n\n\tevent AddProduct(Product product);\n\tevent BuyProductWithETH(Product product);\n\tevent BuyProductWithToken(Product product);\n\tevent ReviewProduct(ProductReview productReview, bytes32 uid);\n\tevent MintTokenToBuyer(address beneficiary, uint256 amountOfToken);\n\tevent WithdrawETH(uint256 amountOfETH);\n\tevent WithdrawToken(uint256 amountOfToken);\n\n\tmodifier onlyAllowedAttesters() {\n\t\tif (!allowedAttesters[msg.sender])\n\t\t\trevert TrustScriptShop__UnauthorizedAttester(msg.sender);\n\t\t_;\n\t}\n\n\tconstructor(\n\t\taddress ownerAddress,\n\t\taddress trustScriptTokenAddress,\n\t\taddress trustScriptProductReviewAttesterAddress\n\t) {\n\t\tsuper.transferOwnership(ownerAddress);\n\t\ttrustScriptToken = TrustScriptToken(trustScriptTokenAddress);\n\t\ttrustScriptProductReviewAttester = TrustScriptProductReviewAttester(\n\t\t\ttrustScriptProductReviewAttesterAddress\n\t\t);\n\t}\n\n\tfunction addProduct(Product memory product) public onlyOwner {\n\t\tif (productsMapping[product.id]) {\n\t\t\trevert TrustScriptShop__ExistedProductId(product.id);\n\t\t}\n\n\t\tif (\n\t\t\t(product.priceInETH * TOKENS_PER_ETH) / 1 ether !=\n\t\t\tproduct.priceInToken\n\t\t) {\n\t\t\trevert TrustScriptShop__UnequalPriceInETHAndPriceInToken(\n\t\t\t\tproduct.priceInETH,\n\t\t\t\tproduct.priceInToken\n\t\t\t);\n\t\t}\n\n\t\tproductsMapping[product.id] = true;\n\t\tproductsArray.push(product);\n\t\tproducts[product.id] = product;\n\t\tnumberOfProducts++;\n\n\t\temit AddProduct(product);\n\t}\n\n\tfunction buyProductWithETH(uint256 id) public payable {\n\t\tif (!productsMapping[id]) {\n\t\t\trevert TrustScriptShop__NotExistedProductId(id);\n\t\t}\n\n\t\tuint256 priceInETH = products[id].priceInETH;\n\t\tif (msg.value != priceInETH) {\n\t\t\trevert TrustScriptShop__UnequalAmountOfETHAndPriceInETH(\n\t\t\t\tmsg.value,\n\t\t\t\tpriceInETH\n\t\t\t);\n\t\t}\n\n\t\tif (!allowedAttesters[msg.sender]) {\n\t\t\tallowedAttesters[msg.sender] = true;\n\t\t}\n\n\t\t(bool success, ) = owner().call{ value: priceInETH }(\"\");\n\t\tif (!success) {\n\t\t\trevert TrustScriptShop__FailedToSendETH();\n\t\t}\n\n\t\temit BuyProductWithETH(products[id]);\n\t}\n\n\tfunction buyProductWithToken(uint256 id, uint256 amountOfToken) public {\n\t\tif (!productsMapping[id]) {\n\t\t\trevert TrustScriptShop__NotExistedProductId(id);\n\t\t}\n\n\t\tuint256 priceInToken = products[id].priceInToken;\n\t\tif (amountOfToken != priceInToken) {\n\t\t\trevert TrustScriptShop__UnequalAmountOfTokenAndPriceInToken(\n\t\t\t\tamountOfToken,\n\t\t\t\tpriceInToken\n\t\t\t);\n\t\t}\n\n\t\tif (!allowedAttesters[msg.sender]) {\n\t\t\tallowedAttesters[msg.sender] = true;\n\t\t}\n\n\t\ttrustScriptToken.transferFrom(msg.sender, owner(), amountOfToken);\n\n\t\temit BuyProductWithToken(products[id]);\n\t}\n\n\tfunction reviewProduct(\n\t\tProductReview memory productReview\n\t) public onlyAllowedAttesters {\n\t\tif (!productsMapping[productReview.productId]) {\n\t\t\trevert TrustScriptShop__NotExistedProductId(\n\t\t\t\tproductReview.productId\n\t\t\t);\n\t\t}\n\n\t\tbytes32 attestationUID = trustScriptProductReviewAttester\n\t\t\t.attestProductReview(productReview, owner());\n\n\t\temit ReviewProduct(productReview, attestationUID);\n\n\t\ttrustScriptToken.mint(\n\t\t\tmsg.sender,\n\t\t\t5 * 10 ** trustScriptToken.decimals()\n\t\t);\n\n\t\temit MintTokenToBuyer(msg.sender, 5);\n\t}\n\n\tfunction withdrawETH() public onlyOwner {\n\t\tuint256 amountOfETH = address(this).balance;\n\n\t\t(bool success, ) = msg.sender.call{ value: amountOfETH }(\"\");\n\t\tif (!success) {\n\t\t\trevert TrustScriptShop__FailedToSendETH();\n\t\t}\n\n\t\temit WithdrawETH(amountOfETH);\n\t}\n\n\tfunction withdrawToken() public onlyOwner {\n\t\tuint256 amountOfToken = trustScriptToken.balanceOf(address(this));\n\t\ttrustScriptToken.transfer(msg.sender, amountOfToken);\n\n\t\temit WithdrawToken(amountOfToken);\n\t}\n\n\tfunction getAllProducts()\n\t\tpublic\n\t\tview\n\t\treturns (Product[] memory allProducts)\n\t{\n\t\tif (numberOfProducts == 0) {\n\t\t\treturn new Product[](0);\n\t\t}\n\n\t\tallProducts = new Product[](numberOfProducts);\n\t\tfor (uint i = 0; i < numberOfProducts; i++) {\n\t\t\tallProducts[i] = productsArray[i];\n\t\t}\n\t\treturn allProducts;\n\t}\n}\n" + }, + "contracts/TrustScriptToken.sol": { + "content": "//SPDX-License-Identifier: MIT\r\npragma solidity >=0.8.0 <0.9.0;\r\n\r\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\r\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\r\n\r\ncontract TrustScriptToken is ERC20, Ownable {\r\n\tmapping(address => bool) public allowedMinters;\r\n\r\n\terror TrustScriptToken__UnauthorizedMinter(address minterAddress);\r\n\r\n\tmodifier onlyAllowedMinters() {\r\n\t\tif (!allowedMinters[msg.sender])\r\n\t\t\trevert TrustScriptToken__UnauthorizedMinter(msg.sender);\r\n\t\t_;\r\n\t}\r\n\r\n\tconstructor(address ownerAddress) ERC20(\"TrustScript\", \"TST\") {\r\n\t\tsuper.transferOwnership(ownerAddress);\r\n\r\n\t\tallowedMinters[ownerAddress] = true;\r\n\t\t_mint(ownerAddress, 1000 * 10 ** decimals());\r\n\t}\r\n\r\n\tfunction mint(\r\n\t\taddress beneficiary,\r\n\t\tuint256 amountOfToken\r\n\t) external onlyAllowedMinters {\r\n\t\t_mint(beneficiary, amountOfToken);\r\n\t}\r\n\r\n\tfunction allowMinter(address minter) public onlyOwner {\r\n\t\tallowedMinters[minter] = true;\r\n\t}\r\n}\r\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/packages/hardhat/deployments/baseSepolia/solcInputs/600a4f1d04d1120bafc3a677d8e15185.json b/packages/hardhat/deployments/baseSepolia/solcInputs/600a4f1d04d1120bafc3a677d8e15185.json new file mode 100644 index 000000000..ba8228aa3 --- /dev/null +++ b/packages/hardhat/deployments/baseSepolia/solcInputs/600a4f1d04d1120bafc3a677d8e15185.json @@ -0,0 +1,71 @@ +{ + "language": "Solidity", + "sources": { + "@ethereum-attestation-service/eas-contracts/contracts/Common.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n// A representation of an empty/uninitialized UID.\nbytes32 constant EMPTY_UID = 0;\n\n// A zero expiration represents an non-expiring attestation.\nuint64 constant NO_EXPIRATION_TIME = 0;\n\nerror AccessDenied();\nerror DeadlineExpired();\nerror InvalidEAS();\nerror InvalidLength();\nerror InvalidSignature();\nerror NotFound();\n\n/// @notice A struct representing ECDSA signature data.\nstruct Signature {\n uint8 v; // The recovery ID.\n bytes32 r; // The x-coordinate of the nonce R.\n bytes32 s; // The signature data.\n}\n\n/// @notice A struct representing a single attestation.\nstruct Attestation {\n bytes32 uid; // A unique identifier of the attestation.\n bytes32 schema; // The unique identifier of the schema.\n uint64 time; // The time when the attestation was created (Unix timestamp).\n uint64 expirationTime; // The time when the attestation expires (Unix timestamp).\n uint64 revocationTime; // The time when the attestation was revoked (Unix timestamp).\n bytes32 refUID; // The UID of the related attestation.\n address recipient; // The recipient of the attestation.\n address attester; // The attester/sender of the attestation.\n bool revocable; // Whether the attestation is revocable.\n bytes data; // Custom attestation data.\n}\n\n/// @notice A helper function to work with unchecked iterators in loops.\nfunction uncheckedInc(uint256 i) pure returns (uint256 j) {\n unchecked {\n j = i + 1;\n }\n}\n" + }, + "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { ISchemaRegistry } from \"./ISchemaRegistry.sol\";\nimport { ISemver } from \"./ISemver.sol\";\nimport { Attestation, Signature } from \"./Common.sol\";\n\n/// @notice A struct representing the arguments of the attestation request.\nstruct AttestationRequestData {\n address recipient; // The recipient of the attestation.\n uint64 expirationTime; // The time when the attestation expires (Unix timestamp).\n bool revocable; // Whether the attestation is revocable.\n bytes32 refUID; // The UID of the related attestation.\n bytes data; // Custom attestation data.\n uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user errors.\n}\n\n/// @notice A struct representing the full arguments of the attestation request.\nstruct AttestationRequest {\n bytes32 schema; // The unique identifier of the schema.\n AttestationRequestData data; // The arguments of the attestation request.\n}\n\n/// @notice A struct representing the full arguments of the full delegated attestation request.\nstruct DelegatedAttestationRequest {\n bytes32 schema; // The unique identifier of the schema.\n AttestationRequestData data; // The arguments of the attestation request.\n Signature signature; // The ECDSA signature data.\n address attester; // The attesting account.\n uint64 deadline; // The deadline of the signature/request.\n}\n\n/// @notice A struct representing the full arguments of the multi attestation request.\nstruct MultiAttestationRequest {\n bytes32 schema; // The unique identifier of the schema.\n AttestationRequestData[] data; // The arguments of the attestation request.\n}\n\n/// @notice A struct representing the full arguments of the delegated multi attestation request.\nstruct MultiDelegatedAttestationRequest {\n bytes32 schema; // The unique identifier of the schema.\n AttestationRequestData[] data; // The arguments of the attestation requests.\n Signature[] signatures; // The ECDSA signatures data. Please note that the signatures are assumed to be signed with increasing nonces.\n address attester; // The attesting account.\n uint64 deadline; // The deadline of the signature/request.\n}\n\n/// @notice A struct representing the arguments of the revocation request.\nstruct RevocationRequestData {\n bytes32 uid; // The UID of the attestation to revoke.\n uint256 value; // An explicit ETH amount to send to the resolver. This is important to prevent accidental user errors.\n}\n\n/// @notice A struct representing the full arguments of the revocation request.\nstruct RevocationRequest {\n bytes32 schema; // The unique identifier of the schema.\n RevocationRequestData data; // The arguments of the revocation request.\n}\n\n/// @notice A struct representing the arguments of the full delegated revocation request.\nstruct DelegatedRevocationRequest {\n bytes32 schema; // The unique identifier of the schema.\n RevocationRequestData data; // The arguments of the revocation request.\n Signature signature; // The ECDSA signature data.\n address revoker; // The revoking account.\n uint64 deadline; // The deadline of the signature/request.\n}\n\n/// @notice A struct representing the full arguments of the multi revocation request.\nstruct MultiRevocationRequest {\n bytes32 schema; // The unique identifier of the schema.\n RevocationRequestData[] data; // The arguments of the revocation request.\n}\n\n/// @notice A struct representing the full arguments of the delegated multi revocation request.\nstruct MultiDelegatedRevocationRequest {\n bytes32 schema; // The unique identifier of the schema.\n RevocationRequestData[] data; // The arguments of the revocation requests.\n Signature[] signatures; // The ECDSA signatures data. Please note that the signatures are assumed to be signed with increasing nonces.\n address revoker; // The revoking account.\n uint64 deadline; // The deadline of the signature/request.\n}\n\n/// @title IEAS\n/// @notice EAS - Ethereum Attestation Service interface.\ninterface IEAS is ISemver {\n /// @notice Emitted when an attestation has been made.\n /// @param recipient The recipient of the attestation.\n /// @param attester The attesting account.\n /// @param uid The UID of the new attestation.\n /// @param schemaUID The UID of the schema.\n event Attested(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schemaUID);\n\n /// @notice Emitted when an attestation has been revoked.\n /// @param recipient The recipient of the attestation.\n /// @param attester The attesting account.\n /// @param schemaUID The UID of the schema.\n /// @param uid The UID the revoked attestation.\n event Revoked(address indexed recipient, address indexed attester, bytes32 uid, bytes32 indexed schemaUID);\n\n /// @notice Emitted when a data has been timestamped.\n /// @param data The data.\n /// @param timestamp The timestamp.\n event Timestamped(bytes32 indexed data, uint64 indexed timestamp);\n\n /// @notice Emitted when a data has been revoked.\n /// @param revoker The address of the revoker.\n /// @param data The data.\n /// @param timestamp The timestamp.\n event RevokedOffchain(address indexed revoker, bytes32 indexed data, uint64 indexed timestamp);\n\n /// @notice Returns the address of the global schema registry.\n /// @return The address of the global schema registry.\n function getSchemaRegistry() external view returns (ISchemaRegistry);\n\n /// @notice Attests to a specific schema.\n /// @param request The arguments of the attestation request.\n /// @return The UID of the new attestation.\n ///\n /// Example:\n /// attest({\n /// schema: \"0facc36681cbe2456019c1b0d1e7bedd6d1d40f6f324bf3dd3a4cef2999200a0\",\n /// data: {\n /// recipient: \"0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf\",\n /// expirationTime: 0,\n /// revocable: true,\n /// refUID: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n /// data: \"0xF00D\",\n /// value: 0\n /// }\n /// })\n function attest(AttestationRequest calldata request) external payable returns (bytes32);\n\n /// @notice Attests to a specific schema via the provided ECDSA signature.\n /// @param delegatedRequest The arguments of the delegated attestation request.\n /// @return The UID of the new attestation.\n ///\n /// Example:\n /// attestByDelegation({\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\n /// data: {\n /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\n /// expirationTime: 1673891048,\n /// revocable: true,\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\n /// data: '0x1234',\n /// value: 0\n /// },\n /// signature: {\n /// v: 28,\n /// r: '0x148c...b25b',\n /// s: '0x5a72...be22'\n /// },\n /// attester: '0xc5E8740aD971409492b1A63Db8d83025e0Fc427e',\n /// deadline: 1673891048\n /// })\n function attestByDelegation(\n DelegatedAttestationRequest calldata delegatedRequest\n ) external payable returns (bytes32);\n\n /// @notice Attests to multiple schemas.\n /// @param multiRequests The arguments of the multi attestation requests. The requests should be grouped by distinct\n /// schema ids to benefit from the best batching optimization.\n /// @return The UIDs of the new attestations.\n ///\n /// Example:\n /// multiAttest([{\n /// schema: '0x33e9094830a5cba5554d1954310e4fbed2ef5f859ec1404619adea4207f391fd',\n /// data: [{\n /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf',\n /// expirationTime: 1673891048,\n /// revocable: true,\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\n /// data: '0x1234',\n /// value: 1000\n /// },\n /// {\n /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\n /// expirationTime: 0,\n /// revocable: false,\n /// refUID: '0x480df4a039efc31b11bfdf491b383ca138b6bde160988222a2a3509c02cee174',\n /// data: '0x00',\n /// value: 0\n /// }],\n /// },\n /// {\n /// schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425',\n /// data: [{\n /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf',\n /// expirationTime: 0,\n /// revocable: true,\n /// refUID: '0x75bf2ed8dca25a8190c50c52db136664de25b2449535839008ccfdab469b214f',\n /// data: '0x12345678',\n /// value: 0\n /// },\n /// }])\n function multiAttest(MultiAttestationRequest[] calldata multiRequests) external payable returns (bytes32[] memory);\n\n /// @notice Attests to multiple schemas using via provided ECDSA signatures.\n /// @param multiDelegatedRequests The arguments of the delegated multi attestation requests. The requests should be\n /// grouped by distinct schema ids to benefit from the best batching optimization.\n /// @return The UIDs of the new attestations.\n ///\n /// Example:\n /// multiAttestByDelegation([{\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\n /// data: [{\n /// recipient: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\n /// expirationTime: 1673891048,\n /// revocable: true,\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\n /// data: '0x1234',\n /// value: 0\n /// },\n /// {\n /// recipient: '0xdEADBeAFdeAdbEafdeadbeafDeAdbEAFdeadbeaf',\n /// expirationTime: 0,\n /// revocable: false,\n /// refUID: '0x0000000000000000000000000000000000000000000000000000000000000000',\n /// data: '0x00',\n /// value: 0\n /// }],\n /// signatures: [{\n /// v: 28,\n /// r: '0x148c...b25b',\n /// s: '0x5a72...be22'\n /// },\n /// {\n /// v: 28,\n /// r: '0x487s...67bb',\n /// s: '0x12ad...2366'\n /// }],\n /// attester: '0x1D86495b2A7B524D747d2839b3C645Bed32e8CF4',\n /// deadline: 1673891048\n /// }])\n function multiAttestByDelegation(\n MultiDelegatedAttestationRequest[] calldata multiDelegatedRequests\n ) external payable returns (bytes32[] memory);\n\n /// @notice Revokes an existing attestation to a specific schema.\n /// @param request The arguments of the revocation request.\n ///\n /// Example:\n /// revoke({\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\n /// data: {\n /// uid: '0x101032e487642ee04ee17049f99a70590c735b8614079fc9275f9dd57c00966d',\n /// value: 0\n /// }\n /// })\n function revoke(RevocationRequest calldata request) external payable;\n\n /// @notice Revokes an existing attestation to a specific schema via the provided ECDSA signature.\n /// @param delegatedRequest The arguments of the delegated revocation request.\n ///\n /// Example:\n /// revokeByDelegation({\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\n /// data: {\n /// uid: '0xcbbc12102578c642a0f7b34fe7111e41afa25683b6cd7b5a14caf90fa14d24ba',\n /// value: 0\n /// },\n /// signature: {\n /// v: 27,\n /// r: '0xb593...7142',\n /// s: '0x0f5b...2cce'\n /// },\n /// revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992',\n /// deadline: 1673891048\n /// })\n function revokeByDelegation(DelegatedRevocationRequest calldata delegatedRequest) external payable;\n\n /// @notice Revokes existing attestations to multiple schemas.\n /// @param multiRequests The arguments of the multi revocation requests. The requests should be grouped by distinct\n /// schema ids to benefit from the best batching optimization.\n ///\n /// Example:\n /// multiRevoke([{\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\n /// data: [{\n /// uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25',\n /// value: 1000\n /// },\n /// {\n /// uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade',\n /// value: 0\n /// }],\n /// },\n /// {\n /// schema: '0x5ac273ce41e3c8bfa383efe7c03e54c5f0bff29c9f11ef6ffa930fc84ca32425',\n /// data: [{\n /// uid: '0x053d42abce1fd7c8fcddfae21845ad34dae287b2c326220b03ba241bc5a8f019',\n /// value: 0\n /// },\n /// }])\n function multiRevoke(MultiRevocationRequest[] calldata multiRequests) external payable;\n\n /// @notice Revokes existing attestations to multiple schemas via provided ECDSA signatures.\n /// @param multiDelegatedRequests The arguments of the delegated multi revocation attestation requests. The requests\n /// should be grouped by distinct schema ids to benefit from the best batching optimization.\n ///\n /// Example:\n /// multiRevokeByDelegation([{\n /// schema: '0x8e72f5bc0a8d4be6aa98360baa889040c50a0e51f32dbf0baa5199bd93472ebc',\n /// data: [{\n /// uid: '0x211296a1ca0d7f9f2cfebf0daaa575bea9b20e968d81aef4e743d699c6ac4b25',\n /// value: 1000\n /// },\n /// {\n /// uid: '0xe160ac1bd3606a287b4d53d5d1d6da5895f65b4b4bab6d93aaf5046e48167ade',\n /// value: 0\n /// }],\n /// signatures: [{\n /// v: 28,\n /// r: '0x148c...b25b',\n /// s: '0x5a72...be22'\n /// },\n /// {\n /// v: 28,\n /// r: '0x487s...67bb',\n /// s: '0x12ad...2366'\n /// }],\n /// revoker: '0x244934dd3e31bE2c81f84ECf0b3E6329F5381992',\n /// deadline: 1673891048\n /// }])\n function multiRevokeByDelegation(\n MultiDelegatedRevocationRequest[] calldata multiDelegatedRequests\n ) external payable;\n\n /// @notice Timestamps the specified bytes32 data.\n /// @param data The data to timestamp.\n /// @return The timestamp the data was timestamped with.\n function timestamp(bytes32 data) external returns (uint64);\n\n /// @notice Timestamps the specified multiple bytes32 data.\n /// @param data The data to timestamp.\n /// @return The timestamp the data was timestamped with.\n function multiTimestamp(bytes32[] calldata data) external returns (uint64);\n\n /// @notice Revokes the specified bytes32 data.\n /// @param data The data to timestamp.\n /// @return The timestamp the data was revoked with.\n function revokeOffchain(bytes32 data) external returns (uint64);\n\n /// @notice Revokes the specified multiple bytes32 data.\n /// @param data The data to timestamp.\n /// @return The timestamp the data was revoked with.\n function multiRevokeOffchain(bytes32[] calldata data) external returns (uint64);\n\n /// @notice Returns an existing attestation by UID.\n /// @param uid The UID of the attestation to retrieve.\n /// @return The attestation data members.\n function getAttestation(bytes32 uid) external view returns (Attestation memory);\n\n /// @notice Checks whether an attestation exists.\n /// @param uid The UID of the attestation to retrieve.\n /// @return Whether an attestation exists.\n function isAttestationValid(bytes32 uid) external view returns (bool);\n\n /// @notice Returns the timestamp that the specified data was timestamped with.\n /// @param data The data to query.\n /// @return The timestamp the data was timestamped with.\n function getTimestamp(bytes32 data) external view returns (uint64);\n\n /// @notice Returns the timestamp that the specified data was timestamped with.\n /// @param data The data to query.\n /// @return The timestamp the data was timestamped with.\n function getRevokeOffchain(address revoker, bytes32 data) external view returns (uint64);\n}\n" + }, + "@ethereum-attestation-service/eas-contracts/contracts/ISchemaRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { ISemver } from \"./ISemver.sol\";\n\nimport { ISchemaResolver } from \"./resolver/ISchemaResolver.sol\";\n\n/// @notice A struct representing a record for a submitted schema.\nstruct SchemaRecord {\n bytes32 uid; // The unique identifier of the schema.\n ISchemaResolver resolver; // Optional schema resolver.\n bool revocable; // Whether the schema allows revocations explicitly.\n string schema; // Custom specification of the schema (e.g., an ABI).\n}\n\n/// @title ISchemaRegistry\n/// @notice The interface of global attestation schemas for the Ethereum Attestation Service protocol.\ninterface ISchemaRegistry is ISemver {\n /// @notice Emitted when a new schema has been registered\n /// @param uid The schema UID.\n /// @param registerer The address of the account used to register the schema.\n /// @param schema The schema data.\n event Registered(bytes32 indexed uid, address indexed registerer, SchemaRecord schema);\n\n /// @notice Submits and reserves a new schema\n /// @param schema The schema data schema.\n /// @param resolver An optional schema resolver.\n /// @param revocable Whether the schema allows revocations explicitly.\n /// @return The UID of the new schema.\n function register(string calldata schema, ISchemaResolver resolver, bool revocable) external returns (bytes32);\n\n /// @notice Returns an existing schema by UID\n /// @param uid The UID of the schema to retrieve.\n /// @return The schema data members.\n function getSchema(bytes32 uid) external view returns (SchemaRecord memory);\n}\n" + }, + "@ethereum-attestation-service/eas-contracts/contracts/ISemver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @title ISemver\n/// @notice A semver interface.\ninterface ISemver {\n /// @notice Returns the full semver contract version.\n /// @return Semver contract version as a string.\n function version() external view returns (string memory);\n}\n" + }, + "@ethereum-attestation-service/eas-contracts/contracts/resolver/ISchemaResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport { ISemver } from \"../ISemver.sol\";\nimport { Attestation } from \"../Common.sol\";\n\n/// @title ISchemaResolver\n/// @notice The interface of an optional schema resolver.\ninterface ISchemaResolver is ISemver {\n /// @notice Checks if the resolver can be sent ETH.\n /// @return Whether the resolver supports ETH transfers.\n function isPayable() external pure returns (bool);\n\n /// @notice Processes an attestation and verifies whether it's valid.\n /// @param attestation The new attestation.\n /// @return Whether the attestation is valid.\n function attest(Attestation calldata attestation) external payable returns (bool);\n\n /// @notice Processes multiple attestations and verifies whether they are valid.\n /// @param attestations The new attestations.\n /// @param values Explicit ETH amounts which were sent with each attestation.\n /// @return Whether all the attestations are valid.\n function multiAttest(\n Attestation[] calldata attestations,\n uint256[] calldata values\n ) external payable returns (bool);\n\n /// @notice Processes an attestation revocation and verifies if it can be revoked.\n /// @param attestation The existing attestation to be revoked.\n /// @return Whether the attestation can be revoked.\n function revoke(Attestation calldata attestation) external payable returns (bool);\n\n /// @notice Processes revocation of multiple attestation and verifies they can be revoked.\n /// @param attestations The existing attestations to be revoked.\n /// @param values Explicit ETH amounts which were sent with each revocation.\n /// @return Whether the attestations can be revoked.\n function multiRevoke(\n Attestation[] calldata attestations,\n uint256[] calldata values\n ) external payable returns (bool);\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/TrustScriptProductReviewAttester.sol": { + "content": "//SPDX-License-Identifier: MIT\r\npragma solidity >=0.8.0 <0.9.0;\r\n\r\nimport { IEAS, AttestationRequest, AttestationRequestData } from \"@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol\";\r\nimport { NO_EXPIRATION_TIME, EMPTY_UID } from \"@ethereum-attestation-service/eas-contracts/contracts/Common.sol\";\r\n\r\nstruct ProductReview {\r\n\tuint256 productId;\r\n\taddress buyerAddress;\r\n\tstring review;\r\n}\r\n\r\n/// @title TrustScriptProductReviewAttester\r\n/// @notice Ethereum Attestation Service - Example\r\ncontract TrustScriptProductReviewAttester {\r\n\t// The address of the global EAS contract.\r\n\tIEAS public immutable eas;\r\n\tbytes32 public immutable productReviewSchemaUID;\r\n\r\n\terror InvalidEAS();\r\n\r\n\t/// @notice Creates a new TrustScriptProductReviewAttester instance.\r\n\t/// @param easAddress The address of the global EAS contract.\r\n\t/// @param _productReviewSchemaUID The UID of the ProductReview schema.\r\n\tconstructor(IEAS easAddress, bytes32 _productReviewSchemaUID) {\r\n\t\tif (address(easAddress) == address(0)) {\r\n\t\t\trevert InvalidEAS();\r\n\t\t}\r\n\r\n\t\teas = easAddress;\r\n\t\tproductReviewSchemaUID = _productReviewSchemaUID;\r\n\t}\r\n\r\n\t/// @notice Attests to a schema that receives a ProductReview parameter.\r\n\t/// @param productReview The ProductReview value to pass to to the resolver.\r\n\t/// @return attestationUID The UID of the new attestation.\r\n\tfunction attestProductReview(\r\n\t\tProductReview memory productReview,\r\n\t\taddress sellerAddress\r\n\t) external returns (bytes32 attestationUID) {\r\n\t\treturn\r\n\t\t\teas.attest(\r\n\t\t\t\tAttestationRequest({\r\n\t\t\t\t\tschema: productReviewSchemaUID,\r\n\t\t\t\t\tdata: AttestationRequestData({\r\n\t\t\t\t\t\trecipient: sellerAddress,\r\n\t\t\t\t\t\texpirationTime: NO_EXPIRATION_TIME, // No expiration time\r\n\t\t\t\t\t\trevocable: true,\r\n\t\t\t\t\t\trefUID: EMPTY_UID, // No references UI\r\n\t\t\t\t\t\tdata: abi.encode(\r\n\t\t\t\t\t\t\tproductReview.productId,\r\n\t\t\t\t\t\t\tproductReview.buyerAddress,\r\n\t\t\t\t\t\t\tproductReview.review\r\n\t\t\t\t\t\t),\r\n\t\t\t\t\t\tvalue: 0 // No value/ETH\r\n\t\t\t\t\t})\r\n\t\t\t\t})\r\n\t\t\t);\r\n\r\n\t\t// return\r\n\t\t// \t0x3100000000000000000000000000000000000000000000000000000000000000;\r\n\t}\r\n}\r\n" + }, + "contracts/TrustScriptShop.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.0 <0.9.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./TrustScriptToken.sol\";\nimport \"./TrustScriptProductReviewAttester.sol\";\n\ncontract TrustScriptShop is Ownable {\n\tstruct Product {\n\t\tuint256 id;\n\t\tstring name;\n\t\tuint256 priceInETH;\n\t\tuint256 priceInToken;\n\t}\n\n\tTrustScriptToken public trustScriptToken;\n\tuint256 public constant TOKENS_PER_ETH = 1000;\n\tuint256 public constant REVIEW_PRODUCT_REWARD = 5;\n\tmapping(uint256 => bool) public productsMapping;\n\tProduct[] public productsArray;\n\tmapping(uint256 => Product) public products;\n\tuint256 public numberOfProducts;\n\tProductReview[] public productReviewsArray;\n\tuint256 public numberOfProductReviews;\n\tmapping(address => bool) public allowedAttesters;\n\tTrustScriptProductReviewAttester public trustScriptProductReviewAttester;\n\n\tevent AddProduct(Product product);\n\tevent BuyProductWithETH(Product product);\n\tevent BuyProductWithToken(Product product);\n\tevent ReviewProduct(ProductReview productReview, bytes32 uid);\n\tevent MintTokenToBuyer(address beneficiary, uint256 amountOfToken);\n\tevent WithdrawETH(uint256 amountOfETH);\n\tevent WithdrawToken(uint256 amountOfToken);\n\n\terror TrustScriptShop__ExistedProductId(uint256 productId);\n\terror TrustScriptShop__NotExistedProductId(uint256 productId);\n\terror TrustScriptShop__UnequalPriceInETHAndPriceInToken(\n\t\tuint256 priceInETH,\n\t\tuint256 priceInToken\n\t);\n\terror TrustScriptShop__UnequalAmountOfETHAndPriceInETH(\n\t\tuint256 amountOfETH,\n\t\tuint256 priceInETH\n\t);\n\terror TrustScriptShop__UnequalAmountOfTokenAndPriceInToken(\n\t\tuint256 amountOfToken,\n\t\tuint256 priceInToken\n\t);\n\terror TrustScriptShop__FailedToSendETH();\n\terror TrustScriptShop__UnauthorizedAttester(address attesterAddress);\n\n\tmodifier onlyAllowedAttesters() {\n\t\tif (!allowedAttesters[msg.sender])\n\t\t\trevert TrustScriptShop__UnauthorizedAttester(msg.sender);\n\t\t_;\n\t}\n\n\tconstructor(\n\t\taddress ownerAddress,\n\t\taddress trustScriptTokenAddress,\n\t\taddress trustScriptProductReviewAttesterAddress\n\t) {\n\t\tsuper.transferOwnership(ownerAddress);\n\t\ttrustScriptToken = TrustScriptToken(trustScriptTokenAddress);\n\t\ttrustScriptProductReviewAttester = TrustScriptProductReviewAttester(\n\t\t\ttrustScriptProductReviewAttesterAddress\n\t\t);\n\t}\n\n\tfunction addProduct(Product memory product) public onlyOwner {\n\t\tif (productsMapping[product.id]) {\n\t\t\trevert TrustScriptShop__ExistedProductId(product.id);\n\t\t}\n\n\t\tif (\n\t\t\tproduct.priceInETH *\n\t\t\t\tTOKENS_PER_ETH *\n\t\t\t\t10 ** trustScriptToken.decimals() !=\n\t\t\tproduct.priceInToken * 1 ether\n\t\t) {\n\t\t\trevert TrustScriptShop__UnequalPriceInETHAndPriceInToken(\n\t\t\t\tproduct.priceInETH,\n\t\t\t\tproduct.priceInToken\n\t\t\t);\n\t\t}\n\n\t\tproductsMapping[product.id] = true;\n\t\tproductsArray.push(product);\n\t\tproducts[product.id] = product;\n\t\tnumberOfProducts++;\n\n\t\temit AddProduct(product);\n\t}\n\n\tfunction buyProductWithETH(uint256 id) public payable {\n\t\tif (!productsMapping[id]) {\n\t\t\trevert TrustScriptShop__NotExistedProductId(id);\n\t\t}\n\n\t\tuint256 priceInETH = products[id].priceInETH;\n\t\tif (msg.value != priceInETH) {\n\t\t\trevert TrustScriptShop__UnequalAmountOfETHAndPriceInETH(\n\t\t\t\tmsg.value,\n\t\t\t\tpriceInETH\n\t\t\t);\n\t\t}\n\n\t\tif (!allowedAttesters[msg.sender]) {\n\t\t\tallowedAttesters[msg.sender] = true;\n\t\t}\n\n\t\t(bool success, ) = owner().call{ value: priceInETH }(\"\");\n\t\tif (!success) {\n\t\t\trevert TrustScriptShop__FailedToSendETH();\n\t\t}\n\n\t\temit BuyProductWithETH(products[id]);\n\t}\n\n\tfunction buyProductWithToken(uint256 id, uint256 amountOfToken) public {\n\t\tif (!productsMapping[id]) {\n\t\t\trevert TrustScriptShop__NotExistedProductId(id);\n\t\t}\n\n\t\tuint256 priceInToken = products[id].priceInToken;\n\t\tif (amountOfToken != priceInToken) {\n\t\t\trevert TrustScriptShop__UnequalAmountOfTokenAndPriceInToken(\n\t\t\t\tamountOfToken,\n\t\t\t\tpriceInToken\n\t\t\t);\n\t\t}\n\n\t\tif (!allowedAttesters[msg.sender]) {\n\t\t\tallowedAttesters[msg.sender] = true;\n\t\t}\n\n\t\ttrustScriptToken.transferFrom(msg.sender, owner(), amountOfToken);\n\n\t\temit BuyProductWithToken(products[id]);\n\t}\n\n\tfunction reviewProduct(\n\t\tuint256 id,\n\t\tstring memory review\n\t) public onlyAllowedAttesters {\n\t\tif (!productsMapping[id]) {\n\t\t\trevert TrustScriptShop__NotExistedProductId(id);\n\t\t}\n\n\t\tProductReview memory productReview = ProductReview(\n\t\t\tid,\n\t\t\tmsg.sender,\n\t\t\treview\n\t\t);\n\n\t\tbytes32 attestationUID = trustScriptProductReviewAttester\n\t\t\t.attestProductReview(productReview, owner());\n\n\t\temit ReviewProduct(productReview, attestationUID);\n\n\t\tproductReviewsArray.push(productReview);\n\t\tnumberOfProductReviews++;\n\n\t\ttrustScriptToken.mint(\n\t\t\tmsg.sender,\n\t\t\tREVIEW_PRODUCT_REWARD * 10 ** trustScriptToken.decimals()\n\t\t);\n\n\t\temit MintTokenToBuyer(msg.sender, REVIEW_PRODUCT_REWARD);\n\t}\n\n\tfunction withdrawETH() public onlyOwner {\n\t\tuint256 amountOfETH = address(this).balance;\n\n\t\t(bool success, ) = msg.sender.call{ value: amountOfETH }(\"\");\n\t\tif (!success) {\n\t\t\trevert TrustScriptShop__FailedToSendETH();\n\t\t}\n\n\t\temit WithdrawETH(amountOfETH);\n\t}\n\n\tfunction withdrawToken() public onlyOwner {\n\t\tuint256 amountOfToken = trustScriptToken.balanceOf(address(this));\n\t\ttrustScriptToken.transfer(msg.sender, amountOfToken);\n\n\t\temit WithdrawToken(amountOfToken);\n\t}\n\n\tfunction getAllProducts()\n\t\tpublic\n\t\tview\n\t\treturns (Product[] memory allProducts)\n\t{\n\t\tif (numberOfProducts == 0) {\n\t\t\treturn new Product[](0);\n\t\t}\n\n\t\tallProducts = new Product[](numberOfProducts);\n\t\tfor (uint i = 0; i < numberOfProducts; i++) {\n\t\t\tallProducts[i] = productsArray[i];\n\t\t}\n\t\treturn allProducts;\n\t}\n\n\tfunction getAllProductReviews()\n\t\tpublic\n\t\tview\n\t\treturns (ProductReview[] memory allProductReviews)\n\t{\n\t\tif (numberOfProductReviews == 0) {\n\t\t\treturn new ProductReview[](0);\n\t\t}\n\n\t\tallProductReviews = new ProductReview[](numberOfProductReviews);\n\t\tfor (uint i = 0; i < numberOfProductReviews; i++) {\n\t\t\tallProductReviews[i] = productReviewsArray[i];\n\t\t}\n\t\treturn allProductReviews;\n\t}\n}\n" + }, + "contracts/TrustScriptToken.sol": { + "content": "//SPDX-License-Identifier: MIT\r\npragma solidity >=0.8.0 <0.9.0;\r\n\r\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\r\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\r\n\r\ncontract TrustScriptToken is ERC20, Ownable {\r\n\tmapping(address => bool) public allowedMinters;\r\n\r\n\terror TrustScriptToken__UnauthorizedMinter(address minterAddress);\r\n\r\n\tmodifier onlyAllowedMinters() {\r\n\t\tif (!allowedMinters[msg.sender])\r\n\t\t\trevert TrustScriptToken__UnauthorizedMinter(msg.sender);\r\n\t\t_;\r\n\t}\r\n\r\n\tconstructor(address ownerAddress) ERC20(\"TrustScript\", \"TST\") {\r\n\t\tsuper.transferOwnership(ownerAddress);\r\n\r\n\t\tallowedMinters[ownerAddress] = true;\r\n\t\t_mint(ownerAddress, 1000 * 10 ** decimals());\r\n\t}\r\n\r\n\tfunction mint(\r\n\t\taddress beneficiary,\r\n\t\tuint256 amountOfToken\r\n\t) external onlyAllowedMinters {\r\n\t\t_mint(beneficiary, amountOfToken);\r\n\t}\r\n\r\n\tfunction allowMinter(address minter) public onlyOwner {\r\n\t\tallowedMinters[minter] = true;\r\n\t}\r\n}\r\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/packages/hardhat/package.json b/packages/hardhat/package.json index 0b619c59c..a4be72207 100644 --- a/packages/hardhat/package.json +++ b/packages/hardhat/package.json @@ -47,6 +47,7 @@ "typescript": "^5.1.6" }, "dependencies": { + "@ethereum-attestation-service/eas-contracts": "^1.7.1", "@openzeppelin/contracts": "^4.8.1", "@typechain/ethers-v6": "^0.5.1", "dotenv": "^16.0.3", diff --git a/packages/nextjs/app/addReview/page.tsx b/packages/nextjs/app/addReview/page.tsx new file mode 100644 index 000000000..5bca01729 --- /dev/null +++ b/packages/nextjs/app/addReview/page.tsx @@ -0,0 +1,9 @@ +"use client"; + +import type { NextPage } from "next"; + +const AddReview: NextPage = () => { + return

Hello from add a review

; +}; + +export default AddReview; diff --git a/packages/nextjs/app/debug/page.tsx b/packages/nextjs/app/debug/page.tsx index e6fb89f50..e1176dde3 100644 --- a/packages/nextjs/app/debug/page.tsx +++ b/packages/nextjs/app/debug/page.tsx @@ -1,13 +1,73 @@ +"use client"; + import { DebugContracts } from "./_components/DebugContracts"; import type { NextPage } from "next"; -import { getMetadata } from "~~/utils/scaffold-eth/getMetadata"; +// import { getMetadata } from "~~/utils/scaffold-eth/getMetadata"; +import { useScaffoldEventHistory } from "~~/hooks/scaffold-eth"; -export const metadata = getMetadata({ - title: "Debug Contracts", - description: "Debug your deployed ๐Ÿ— Scaffold-ETH 2 contracts in an easy way", -}); +// export const metadata = getMetadata({ +// title: "Debug Contracts", +// description: "Debug your deployed ๐Ÿ— Scaffold-ETH 2 contracts in an easy way", +// }); const Debug: NextPage = () => { + const { data: addProductEvent } = useScaffoldEventHistory({ + contractName: "TrustScriptShop", + eventName: "AddProduct", + fromBlock: 0n, + watch: true, + }); + + const { data: buyProductWithETHEvent } = useScaffoldEventHistory({ + contractName: "TrustScriptShop", + eventName: "BuyProductWithETH", + fromBlock: 0n, + watch: true, + }); + + const { data: buyProductWithTokenEvent } = useScaffoldEventHistory({ + contractName: "TrustScriptShop", + eventName: "BuyProductWithToken", + fromBlock: 0n, + watch: true, + }); + + const { data: reviewProductEvent } = useScaffoldEventHistory({ + contractName: "TrustScriptShop", + eventName: "ReviewProduct", + fromBlock: 0n, + watch: true, + }); + + const { data: mintTokenToBuyerEvent } = useScaffoldEventHistory({ + contractName: "TrustScriptShop", + eventName: "MintTokenToBuyer", + fromBlock: 0n, + watch: true, + }); + + const { data: withdrawETHEvent } = useScaffoldEventHistory({ + contractName: "TrustScriptShop", + eventName: "WithdrawETH", + fromBlock: 0n, + watch: true, + }); + + const { data: withdrawTokenEvent } = useScaffoldEventHistory({ + contractName: "TrustScriptShop", + eventName: "WithdrawToken", + fromBlock: 0n, + watch: true, + }); + + addProductEvent && console.log("addProductEvent", addProductEvent); + buyProductWithETHEvent && console.log("buyProductWithETHEvent", buyProductWithETHEvent); + buyProductWithTokenEvent && console.log("buyProductWithTokenEvent", buyProductWithTokenEvent); + reviewProductEvent && console.log("reviewProductEvent", reviewProductEvent); + mintTokenToBuyerEvent && console.log("mintTokenToBuyerEvent", mintTokenToBuyerEvent); + withdrawETHEvent && console.log("withdrawETHEvent", withdrawETHEvent); + withdrawTokenEvent && console.log("withdrawTokenEvent", withdrawTokenEvent); + return ( <> diff --git a/packages/nextjs/app/events/page.tsx b/packages/nextjs/app/events/page.tsx new file mode 100644 index 000000000..57b26f97e --- /dev/null +++ b/packages/nextjs/app/events/page.tsx @@ -0,0 +1,72 @@ +"use client"; + +import type { NextPage } from "next"; + +//import { useScaffoldEventHistory } from "~~/hooks/scaffold-eth"; + +const Events: NextPage = () => { + // const { data: addProductEvent } = useScaffoldEventHistory({ + // contractName: "TrustScriptShop", + // eventName: "AddProduct", + // fromBlock: 0n, + // watch: true, + // }); + + // const { data: buyProductWithETHEvent } = useScaffoldEventHistory({ + // contractName: "TrustScriptShop", + // eventName: "BuyProductWithETH", + // fromBlock: 0n, + // watch: true, + // }); + + // const { data: buyProductWithTokenEvent } = useScaffoldEventHistory({ + // contractName: "TrustScriptShop", + // eventName: "BuyProductWithToken", + // fromBlock: 0n, + // watch: true, + // }); + + // const { data: reviewProductEvent } = useScaffoldEventHistory({ + // contractName: "TrustScriptShop", + // eventName: "ReviewProduct", + // fromBlock: 0n, + // watch: true, + // }); + + // const { data: mintTokenToBuyerEvent } = useScaffoldEventHistory({ + // contractName: "TrustScriptShop", + // eventName: "MintTokenToBuyer", + // fromBlock: 0n, + // watch: true, + // }); + + // const { data: withdrawETHEvent } = useScaffoldEventHistory({ + // contractName: "TrustScriptShop", + // eventName: "WithdrawETH", + // fromBlock: 0n, + // watch: true, + // }); + + // const { data: withdrawTokenEvent } = useScaffoldEventHistory({ + // contractName: "TrustScriptShop", + // eventName: "WithdrawToken", + // fromBlock: 0n, + // watch: true, + // }); + + // addProductEvent && console.log(addProductEvent); + // buyProductWithETHEvent && console.log(buyProductWithETHEvent); + // buyProductWithTokenEvent && console.log(buyProductWithTokenEvent); + // reviewProductEvent && console.log(reviewProductEvent); + // mintTokenToBuyerEvent && console.log(mintTokenToBuyerEvent); + // withdrawETHEvent && console.log(withdrawETHEvent); + // withdrawTokenEvent && console.log(withdrawTokenEvent); + + return ( + <> +
Events
+ + ); +}; + +export default Events; diff --git a/packages/nextjs/app/page.tsx b/packages/nextjs/app/page.tsx index ce5e3e7a0..ba7cad3a3 100644 --- a/packages/nextjs/app/page.tsx +++ b/packages/nextjs/app/page.tsx @@ -1,74 +1,46 @@ "use client"; -import Image from "next/image"; -import Link from "next/link"; +import { ProductCard } from "../components/ProductCard"; import type { NextPage } from "next"; -import { useAccount } from "wagmi"; -import { BugAntIcon, MagnifyingGlassIcon } from "@heroicons/react/24/outline"; -import { Address } from "~~/components/scaffold-eth"; +import { useScaffoldReadContract } from "~~/hooks/scaffold-eth"; const Home: NextPage = () => { - const { address: connectedAddress } = useAccount(); + // const productsTest = [ + // { + // id: "1", + // name: "Bitcoin Hoodie", + // priceInETH: 0.01, + // priceInToken: 0.05, + // }, + // { + // id: "2", + // name: "Coin Cap", + // priceInETH: 0.02, + // priceInToken: 0.1, + // }, + // // Add more products as needed + // ]; + + const { data: allProducts, isLoading: isProductsLoading } = useScaffoldReadContract({ + contractName: "TrustScriptShop", + functionName: "getAllProducts", + }); return ( <>
-
-

- Welcome to -
-
- Base logo -
- Scaffold-Base -
-

-
-

Connected Address:

-
-
-

- Get started by editing{" "} - - packages/nextjs/app/page.tsx - -

-

- Edit your smart contract{" "} - - YourContract.sol - {" "} - in{" "} - - packages/hardhat/contracts - -

-
- -
-
-
- -

- Tinker with your smart contract using the{" "} - - Debug Contracts - {" "} - tab. -

-
-
- -

- Explore your local transactions with the{" "} - - Block Explorer - {" "} - tab. -

+ {isProductsLoading ? ( + + ) : ( +
+

Trust Products

+
+ {allProducts?.map(item => ( + + ))}
-
+ )}
); diff --git a/packages/nextjs/app/product/page.tsx b/packages/nextjs/app/product/page.tsx new file mode 100644 index 000000000..bf9a0e004 --- /dev/null +++ b/packages/nextjs/app/product/page.tsx @@ -0,0 +1,56 @@ +"use client"; + +import { EAS, SchemaEncoder } from "@ethereum-attestation-service/eas-sdk"; +import type { NextPage } from "next"; +import { useSigner } from "~~/utils/eas-wagmi-utils"; + +const Product: NextPage = () => { + const signer = useSigner(); + + const attestProductReview = async () => { + const easContractAddress = "0x4200000000000000000000000000000000000021"; + const schemaUID = "0x9f6f2eb2bddf3726a58b6254b697ab24b3527fdaabc01a65765ede0d10ddabc7"; + const eas = new EAS(easContractAddress); + + // Signer must be an ethers-like signer. + if (signer) { + eas.connect(signer); + // Initialize SchemaEncoder with the schema string + const schemaEncoder = new SchemaEncoder("bytes32 productId,string review,bool liked"); + const encodedData = schemaEncoder.encodeData([ + { + name: "productId", + value: "0x3100000000000000000000000000000000000000000000000000000000000000", + type: "bytes32", + }, + { name: "review", value: "bla bla bla...", type: "string" }, + { name: "liked", value: true, type: "bool" }, + ]); + const tx = await eas.attest({ + schema: schemaUID, + data: { + recipient: "0xe84680C37f320c56d9F26E549155D33Bd412e7E3", + expirationTime: 0n, + revocable: true, // Be aware that if your schema is not revocable, this MUST be false + data: encodedData, + }, + }); + const newAttestationUID = await tx.wait(); + console.log("New attestation UID:", newAttestationUID); + } + }; + + return ( + <> +
+
+ +
+
+ + ); +}; + +export default Product; diff --git a/packages/nextjs/app/viewReview/page.tsx b/packages/nextjs/app/viewReview/page.tsx new file mode 100644 index 000000000..7d8217f5b --- /dev/null +++ b/packages/nextjs/app/viewReview/page.tsx @@ -0,0 +1,138 @@ +"use client"; + +import { useEffect, useState } from "react"; +import Image from "next/image"; +import { NextPage } from "next"; +import { Address } from "~~/components/scaffold-eth"; +import { useScaffoldReadContract } from "~~/hooks/scaffold-eth"; + +interface Review { + buyerAddress: string; + comment: string; +} +interface Product { + id: string; + name: string; + priceInETH: bigint; + priceInToken: bigint; +} + +interface ProductReview { + productId: string; + name: string; + image: string; + attestationUID: string; + reviews: Review[]; +} + +const mockAllProductReviews: ProductReview[] = [ + { + attestationUID: "0x0d455486a3dadeacfba5f340fe5bf84d1f6678b2e2af53536acc8a4274626f82", + productId: "1", + name: "Coin Cap", + image: "/coin-cap.png", + reviews: [ + { + buyerAddress: "0x3240707d60E033230dC736a8022B17f04F95A564", + comment: "This is a great product!", + }, + { buyerAddress: "0x80550a82Ba8F733399Ce35d0D14a765aD16Ddde7", comment: "Love my coin cap!" }, + ], + }, + { + attestationUID: "0x0d455486a3dadeacfba5f340fe5bf84d1f6678b2e2af53536acc8a4274626f82", + productId: "2", + name: "Bitcoin Hoodie", + image: "/bitcoin-hoodie.png", + reviews: [ + { buyerAddress: "0x3240707d60E033230dC736a8022B17f04F95A564", comment: "I rep Bitcoin!" }, + { buyerAddress: "0x80550a82Ba8F733399Ce35d0D14a765aD16Ddde7", comment: "Love my hoodie!" }, + ], + }, +]; + +const mockProducts: Product[] = [ + { + id: "1", + name: "Coin Cap", + priceInETH: 1000000000000000n, + priceInToken: 1000000000000000000n, + }, + { + id: "2", + name: "Bitcoin Hoodie", + priceInETH: 2000000000000000n, + priceInToken: 2000000000000000000n, + }, +]; + +const ProductReviews: NextPage = () => { + const [productReviews, setProductReviews] = useState(mockAllProductReviews); + + const { data: allProductReviews, isLoading: isProductReviewsLoading } = useScaffoldReadContract({ + contractName: "TrustScriptShop", + functionName: "getAllProductReviews", + }); + + useEffect(() => { + if (allProductReviews) { + // Assuming `allProductReviews` is in the same format as `mockAllProductReviews` + const newReviews = (allProductReviews as unknown as ProductReview[]).filter( + (newReview: { attestationUID: string }) => + !productReviews.some(existingReview => existingReview.attestationUID === newReview.attestationUID), + ); + if (newReviews.length > 0) { + setProductReviews(prevReviews => [...prevReviews, ...(newReviews as ProductReview[])]); + } + } + }, [allProductReviews, productReviews]); + + if (isProductReviewsLoading) { + return
Loading...
; + } + + const productReviewData = productReviews + .map(review => { + const product = mockProducts.find(p => p.id === review.productId); + return product ? { review, product } : null; + }) + .filter((item): item is { review: ProductReview; product: Product } => item !== null); + + return ( +
+

Product Reviews

+ {productReviewData.length > 0 ? ( + productReviewData.map(({ review, product }, index) => ( +
+
+ {product.name} +

{product.name}

+
+ {review.reviews.map((r, i) => ( +
+ +
+ + + said: {r.comment} + + + ๐Ÿ” + +
+ ))} +
+ )) + ) : ( +

No reviews available.

+ )} +
+ ); +}; + +export default ProductReviews; diff --git a/packages/nextjs/components/Header.tsx b/packages/nextjs/components/Header.tsx index 2bbc07b5d..0e9a00e17 100644 --- a/packages/nextjs/components/Header.tsx +++ b/packages/nextjs/components/Header.tsx @@ -5,14 +5,10 @@ import Image from "next/image"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { useTheme } from "next-themes"; -import { Bars3Icon, BugAntIcon } from "@heroicons/react/24/outline"; -import { - BaseFaucetsButton, - FaucetButton, - RainbowKitCustomConnectButton, - SuperchainFaucetButton, -} from "~~/components/scaffold-eth"; -import { useOutsideClick } from "~~/hooks/scaffold-eth"; +import { useAccount } from "wagmi"; +import { Bars3Icon, BoltIcon, BugAntIcon, CheckIcon, XMarkIcon } from "@heroicons/react/24/outline"; +import { BaseFaucetsButton, FaucetButton, RainbowKitCustomConnectButton } from "~~/components/scaffold-eth"; +import { useOutsideClick, useScaffoldReadContract } from "~~/hooks/scaffold-eth"; type HeaderMenuLink = { label: string; @@ -25,6 +21,16 @@ export const menuLinks: HeaderMenuLink[] = [ label: "Home", href: "/", }, + { + label: "Events", + href: "/events", + icon: , + }, + { + label: "Review", + href: "/viewReview", + icon: , + }, { label: "Debug Contracts", href: "/debug", @@ -72,6 +78,14 @@ export const Header = () => { const { resolvedTheme } = useTheme(); const isDarkMode = resolvedTheme === "dark"; + const { address } = useAccount(); + + const { data: isAllowedAttester } = useScaffoldReadContract({ + contractName: "TrustScriptShop", + functionName: "allowedAttesters", + args: [address], + }); + return (
@@ -107,8 +121,8 @@ export const Header = () => { />
- Scaffold-Base - Ethereum dev stack + Trust Script + On-Chain Check
    @@ -116,9 +130,21 @@ export const Header = () => {
+ {address ? ( + isAllowedAttester ? ( + + ) : ( + + ) + ) : null} -
diff --git a/packages/nextjs/components/ProductCard.tsx b/packages/nextjs/components/ProductCard.tsx new file mode 100644 index 000000000..c40c488f5 --- /dev/null +++ b/packages/nextjs/components/ProductCard.tsx @@ -0,0 +1,42 @@ +import { FC } from "react"; +import Image from "next/image"; +import { formatEther } from "viem"; + +interface Product { + id: bigint; + name: string; + priceInETH: bigint; + priceInToken: bigint; +} + +export const ProductCard: FC<{ product: Product }> = ({ product }) => { + return ( +
+
+
+ {product.name} +
+
+
+

{product.name}

+
+
+

{formatEther(product.priceInETH)} ETH

+ +
+ +
+

{formatEther(product.priceInToken)} TST

+ +
+
+
+
+ ); +}; diff --git a/packages/nextjs/contracts/deployedContracts.ts b/packages/nextjs/contracts/deployedContracts.ts index 008d4eb06..8b95a78d9 100644 --- a/packages/nextjs/contracts/deployedContracts.ts +++ b/packages/nextjs/contracts/deployedContracts.ts @@ -4,6 +4,2517 @@ */ import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract"; -const deployedContracts = {} as const; +const deployedContracts = { + 31337: { + TrustScriptProductReviewAttester: { + address: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", + abi: [ + { + inputs: [ + { + internalType: "contract IEAS", + name: "easAddress", + type: "address", + }, + { + internalType: "bytes32", + name: "_productReviewSchemaUID", + type: "bytes32", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [], + name: "InvalidEAS", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "productId", + type: "uint256", + }, + { + internalType: "address", + name: "buyerAddress", + type: "address", + }, + { + internalType: "string", + name: "review", + type: "string", + }, + { + internalType: "address", + name: "sellerAddress", + type: "address", + }, + ], + name: "attestProductReview", + outputs: [ + { + internalType: "bytes32", + name: "attestationUID", + type: "bytes32", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "eas", + outputs: [ + { + internalType: "contract IEAS", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "productReviewSchemaUID", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + ], + inheritedFunctions: {}, + }, + TrustScriptShop: { + address: "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0", + abi: [ + { + inputs: [ + { + internalType: "address", + name: "ownerAddress", + type: "address", + }, + { + internalType: "address", + name: "trustScriptTokenAddress", + type: "address", + }, + { + internalType: "address", + name: "trustScriptProductReviewAttesterAddress", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [ + { + internalType: "address", + name: "attesterAddress", + type: "address", + }, + ], + name: "TrustScriptShop__DisallowedAttester", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "productId", + type: "uint256", + }, + ], + name: "TrustScriptShop__ExistedProductId", + type: "error", + }, + { + inputs: [], + name: "TrustScriptShop__FailedToSendETH", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "productId", + type: "uint256", + }, + ], + name: "TrustScriptShop__NotExistedProductId", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOfETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + ], + name: "TrustScriptShop__UnequalAmountOfETHAndPriceInETH", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOfToken", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + name: "TrustScriptShop__UnequalAmountOfTokenAndPriceInToken", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + name: "TrustScriptShop__UnequalPriceInETHAndPriceInToken", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "sellerAddress", + type: "address", + }, + { + components: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + indexed: false, + internalType: "struct TrustScriptShop.Product", + name: "product", + type: "tuple", + }, + ], + name: "AddProduct", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "buyerAddress", + type: "address", + }, + { + components: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + indexed: false, + internalType: "struct TrustScriptShop.Product", + name: "product", + type: "tuple", + }, + ], + name: "BuyProductWithETH", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "buyerAddress", + type: "address", + }, + { + components: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + indexed: false, + internalType: "struct TrustScriptShop.Product", + name: "product", + type: "tuple", + }, + ], + name: "BuyProductWithToken", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "buyerAddress", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amountOfToken", + type: "uint256", + }, + ], + name: "MintTokenToBuyer", + 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: false, + internalType: "address", + name: "buyerAddress", + type: "address", + }, + { + components: [ + { + internalType: "bytes32", + name: "attestationUID", + type: "bytes32", + }, + { + internalType: "uint256", + name: "productId", + type: "uint256", + }, + { + internalType: "address", + name: "buyerAddress", + type: "address", + }, + { + internalType: "string", + name: "review", + type: "string", + }, + ], + indexed: false, + internalType: "struct TrustScriptShop.ProductReview", + name: "productReview", + type: "tuple", + }, + ], + name: "ReviewProduct", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "amountOfETH", + type: "uint256", + }, + ], + name: "WithdrawETH", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "amountOfToken", + type: "uint256", + }, + ], + name: "WithdrawToken", + type: "event", + }, + { + inputs: [], + name: "REVIEW_PRODUCT_REWARD", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "TOKENS_PER_ETH", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + internalType: "struct TrustScriptShop.Product", + name: "product", + type: "tuple", + }, + ], + name: "addProduct", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + name: "allowedAttesters", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + ], + name: "buyProductWithETH", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountOfToken", + type: "uint256", + }, + ], + name: "buyProductWithToken", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "getAllProductReviews", + outputs: [ + { + components: [ + { + internalType: "bytes32", + name: "attestationUID", + type: "bytes32", + }, + { + internalType: "uint256", + name: "productId", + type: "uint256", + }, + { + internalType: "address", + name: "buyerAddress", + type: "address", + }, + { + internalType: "string", + name: "review", + type: "string", + }, + ], + internalType: "struct TrustScriptShop.ProductReview[]", + name: "allProductReviews", + type: "tuple[]", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getAllProducts", + outputs: [ + { + components: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + internalType: "struct TrustScriptShop.Product[]", + name: "allProducts", + type: "tuple[]", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "numberOfProductReviews", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "numberOfProducts", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "owner", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + name: "productReviewsArray", + outputs: [ + { + internalType: "bytes32", + name: "attestationUID", + type: "bytes32", + }, + { + internalType: "uint256", + name: "productId", + type: "uint256", + }, + { + internalType: "address", + name: "buyerAddress", + type: "address", + }, + { + internalType: "string", + name: "review", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + name: "products", + outputs: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + name: "productsArray", + outputs: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + name: "productsMapping", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "renounceOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "review", + type: "string", + }, + ], + name: "reviewProduct", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "trustScriptProductReviewAttester", + outputs: [ + { + internalType: "contract TrustScriptProductReviewAttester", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "trustScriptToken", + outputs: [ + { + internalType: "contract TrustScriptToken", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "withdrawETH", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "withdrawToken", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + ], + inheritedFunctions: { + owner: "@openzeppelin/contracts/access/Ownable.sol", + renounceOwnership: "@openzeppelin/contracts/access/Ownable.sol", + transferOwnership: "@openzeppelin/contracts/access/Ownable.sol", + }, + }, + TrustScriptToken: { + address: "0x5FbDB2315678afecb367f032d93F642f64180aa3", + abi: [ + { + inputs: [ + { + internalType: "address", + name: "ownerAddress", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [ + { + internalType: "address", + name: "minterAddress", + type: "address", + }, + ], + name: "TrustScriptToken__DisallowedMinter", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "owner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "spender", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "Approval", + 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: "from", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "Transfer", + type: "event", + }, + { + inputs: [ + { + internalType: "address", + name: "minter", + type: "address", + }, + ], + name: "allowMinter", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + { + internalType: "address", + name: "spender", + type: "address", + }, + ], + name: "allowance", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + name: "allowedMinters", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "approve", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "balanceOf", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "decimals", + outputs: [ + { + internalType: "uint8", + name: "", + type: "uint8", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + { + internalType: "uint256", + name: "subtractedValue", + type: "uint256", + }, + ], + name: "decreaseAllowance", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + { + internalType: "uint256", + name: "addedValue", + type: "uint256", + }, + ], + name: "increaseAllowance", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "beneficiary", + type: "address", + }, + { + internalType: "uint256", + name: "amountOfToken", + type: "uint256", + }, + ], + name: "mint", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "name", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + 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: [], + name: "symbol", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "totalSupply", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "transfer", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "transferFrom", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + ], + inheritedFunctions: { + allowance: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + approve: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + balanceOf: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + decimals: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + decreaseAllowance: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + increaseAllowance: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + name: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + symbol: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + totalSupply: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + transfer: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + transferFrom: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + owner: "@openzeppelin/contracts/access/Ownable.sol", + renounceOwnership: "@openzeppelin/contracts/access/Ownable.sol", + transferOwnership: "@openzeppelin/contracts/access/Ownable.sol", + }, + }, + }, + 84532: { + TrustScriptProductReviewAttester: { + address: "0x80Eb3ccE63E5beDFe067e56e8c3dCCcbf1522247", + abi: [ + { + inputs: [ + { + internalType: "contract IEAS", + name: "easAddress", + type: "address", + }, + { + internalType: "bytes32", + name: "_productReviewSchemaUID", + type: "bytes32", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [], + name: "InvalidEAS", + type: "error", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "productId", + type: "uint256", + }, + { + internalType: "address", + name: "buyerAddress", + type: "address", + }, + { + internalType: "string", + name: "review", + type: "string", + }, + ], + internalType: "struct ProductReview", + name: "productReview", + type: "tuple", + }, + { + internalType: "address", + name: "sellerAddress", + type: "address", + }, + ], + name: "attestProductReview", + outputs: [ + { + internalType: "bytes32", + name: "attestationUID", + type: "bytes32", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "eas", + outputs: [ + { + internalType: "contract IEAS", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "productReviewSchemaUID", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + ], + inheritedFunctions: {}, + }, + TrustScriptShop: { + address: "0x97D12fC6cdfa2232AA5AEa3Eea9872ddE8D78E3D", + abi: [ + { + inputs: [ + { + internalType: "address", + name: "ownerAddress", + type: "address", + }, + { + internalType: "address", + name: "trustScriptTokenAddress", + type: "address", + }, + { + internalType: "address", + name: "trustScriptProductReviewAttesterAddress", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [ + { + internalType: "uint256", + name: "productId", + type: "uint256", + }, + ], + name: "TrustScriptShop__ExistedProductId", + type: "error", + }, + { + inputs: [], + name: "TrustScriptShop__FailedToSendETH", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "productId", + type: "uint256", + }, + ], + name: "TrustScriptShop__NotExistedProductId", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "attesterAddress", + type: "address", + }, + ], + name: "TrustScriptShop__UnauthorizedAttester", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOfETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + ], + name: "TrustScriptShop__UnequalAmountOfETHAndPriceInETH", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOfToken", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + name: "TrustScriptShop__UnequalAmountOfTokenAndPriceInToken", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + name: "TrustScriptShop__UnequalPriceInETHAndPriceInToken", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + indexed: false, + internalType: "struct TrustScriptShop.Product", + name: "product", + type: "tuple", + }, + ], + name: "AddProduct", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + indexed: false, + internalType: "struct TrustScriptShop.Product", + name: "product", + type: "tuple", + }, + ], + name: "BuyProductWithETH", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + indexed: false, + internalType: "struct TrustScriptShop.Product", + name: "product", + type: "tuple", + }, + ], + name: "BuyProductWithToken", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "beneficiary", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amountOfToken", + type: "uint256", + }, + ], + name: "MintTokenToBuyer", + 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: [ + { + components: [ + { + internalType: "uint256", + name: "productId", + type: "uint256", + }, + { + internalType: "address", + name: "buyerAddress", + type: "address", + }, + { + internalType: "string", + name: "review", + type: "string", + }, + ], + indexed: false, + internalType: "struct ProductReview", + name: "productReview", + type: "tuple", + }, + { + indexed: false, + internalType: "bytes32", + name: "uid", + type: "bytes32", + }, + ], + name: "ReviewProduct", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "amountOfETH", + type: "uint256", + }, + ], + name: "WithdrawETH", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "amountOfToken", + type: "uint256", + }, + ], + name: "WithdrawToken", + type: "event", + }, + { + inputs: [], + name: "REVIEW_PRODUCT_REWARD", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "TOKENS_PER_ETH", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + internalType: "struct TrustScriptShop.Product", + name: "product", + type: "tuple", + }, + ], + name: "addProduct", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + name: "allowedAttesters", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + ], + name: "buyProductWithETH", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountOfToken", + type: "uint256", + }, + ], + name: "buyProductWithToken", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "getAllProductReviews", + outputs: [ + { + components: [ + { + internalType: "uint256", + name: "productId", + type: "uint256", + }, + { + internalType: "address", + name: "buyerAddress", + type: "address", + }, + { + internalType: "string", + name: "review", + type: "string", + }, + ], + internalType: "struct ProductReview[]", + name: "allProductReviews", + type: "tuple[]", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getAllProducts", + outputs: [ + { + components: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + internalType: "struct TrustScriptShop.Product[]", + name: "allProducts", + type: "tuple[]", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "numberOfProductReviews", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "numberOfProducts", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "owner", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + name: "productReviewsArray", + outputs: [ + { + internalType: "uint256", + name: "productId", + type: "uint256", + }, + { + internalType: "address", + name: "buyerAddress", + type: "address", + }, + { + internalType: "string", + name: "review", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + name: "products", + outputs: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + name: "productsArray", + outputs: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + { + internalType: "uint256", + name: "priceInETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "priceInToken", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + name: "productsMapping", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "renounceOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + { + internalType: "string", + name: "review", + type: "string", + }, + ], + name: "reviewProduct", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "trustScriptProductReviewAttester", + outputs: [ + { + internalType: "contract TrustScriptProductReviewAttester", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "trustScriptToken", + outputs: [ + { + internalType: "contract TrustScriptToken", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "withdrawETH", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "withdrawToken", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + ], + inheritedFunctions: { + owner: "@openzeppelin/contracts/access/Ownable.sol", + renounceOwnership: "@openzeppelin/contracts/access/Ownable.sol", + transferOwnership: "@openzeppelin/contracts/access/Ownable.sol", + }, + }, + TrustScriptToken: { + address: "0x519bFCA72320728dFfD698D9cE8b7FC6f4955431", + abi: [ + { + inputs: [ + { + internalType: "address", + name: "ownerAddress", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [ + { + internalType: "address", + name: "minterAddress", + type: "address", + }, + ], + name: "TrustScriptToken__UnauthorizedMinter", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "owner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "spender", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "Approval", + 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: "from", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "Transfer", + type: "event", + }, + { + inputs: [ + { + internalType: "address", + name: "minter", + type: "address", + }, + ], + name: "allowMinter", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + { + internalType: "address", + name: "spender", + type: "address", + }, + ], + name: "allowance", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + name: "allowedMinters", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "approve", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "balanceOf", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "decimals", + outputs: [ + { + internalType: "uint8", + name: "", + type: "uint8", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + { + internalType: "uint256", + name: "subtractedValue", + type: "uint256", + }, + ], + name: "decreaseAllowance", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + { + internalType: "uint256", + name: "addedValue", + type: "uint256", + }, + ], + name: "increaseAllowance", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "beneficiary", + type: "address", + }, + { + internalType: "uint256", + name: "amountOfToken", + type: "uint256", + }, + ], + name: "mint", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "name", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + 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: [], + name: "symbol", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "totalSupply", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "transfer", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "transferFrom", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + ], + inheritedFunctions: { + allowance: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + approve: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + balanceOf: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + decimals: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + decreaseAllowance: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + increaseAllowance: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + name: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + symbol: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + totalSupply: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + transfer: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + transferFrom: "@openzeppelin/contracts/token/ERC20/ERC20.sol", + owner: "@openzeppelin/contracts/access/Ownable.sol", + renounceOwnership: "@openzeppelin/contracts/access/Ownable.sol", + transferOwnership: "@openzeppelin/contracts/access/Ownable.sol", + }, + }, + }, +} as const; export default deployedContracts satisfies GenericContractsDeclaration; diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index 37af6f6f3..2fcd4faab 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -14,6 +14,7 @@ "vercel:yolo": "vercel --build-env NEXT_PUBLIC_IGNORE_BUILD_ERROR=true" }, "dependencies": { + "@ethereum-attestation-service/eas-sdk": "^2.2.0", "@heroicons/react": "^2.0.11", "@rainbow-me/rainbowkit": "^2.0.2", "@tanstack/react-query": "^5.28.6", diff --git a/packages/nextjs/public/merch/Bitcoin Hoodie.png b/packages/nextjs/public/merch/Bitcoin Hoodie.png new file mode 100644 index 000000000..7651e860d Binary files /dev/null and b/packages/nextjs/public/merch/Bitcoin Hoodie.png differ diff --git a/packages/nextjs/public/merch/Brian Beanie.png b/packages/nextjs/public/merch/Brian Beanie.png new file mode 100644 index 000000000..0503b0ee4 Binary files /dev/null and b/packages/nextjs/public/merch/Brian Beanie.png differ diff --git a/packages/nextjs/public/merch/Coin Cap.png b/packages/nextjs/public/merch/Coin Cap.png new file mode 100644 index 000000000..ad0ae3748 Binary files /dev/null and b/packages/nextjs/public/merch/Coin Cap.png differ diff --git a/packages/nextjs/public/merch/Coinbrew.png b/packages/nextjs/public/merch/Coinbrew.png new file mode 100644 index 000000000..ff41adc0c Binary files /dev/null and b/packages/nextjs/public/merch/Coinbrew.png differ diff --git a/packages/nextjs/public/merch/Onchain Pin.png b/packages/nextjs/public/merch/Onchain Pin.png new file mode 100644 index 000000000..577df2e8a Binary files /dev/null and b/packages/nextjs/public/merch/Onchain Pin.png differ diff --git a/packages/nextjs/public/merch/T-shirt.png b/packages/nextjs/public/merch/T-shirt.png new file mode 100644 index 000000000..4f5a8bb0d Binary files /dev/null and b/packages/nextjs/public/merch/T-shirt.png differ diff --git a/packages/nextjs/scaffold.config.ts b/packages/nextjs/scaffold.config.ts index 09471a9ce..1f0afb6e1 100644 --- a/packages/nextjs/scaffold.config.ts +++ b/packages/nextjs/scaffold.config.ts @@ -10,7 +10,8 @@ export type ScaffoldConfig = { const scaffoldConfig = { // The networks on which your DApp is live - targetNetworks: [chains.hardhat /*, chains.baseSepolia, chains.base*/], + targetNetworks: [chains.hardhat /*chains.baseSepolia, chains.base*/], + // targetNetworks: [chains.baseSepolia /*chains.hardhat, chains.base*/], // The interval at which your front-end polls the RPC servers for new data // it has no effect if you only target the local network (default is 4000) diff --git a/packages/nextjs/utils/eas-wagmi-utils.ts b/packages/nextjs/utils/eas-wagmi-utils.ts new file mode 100644 index 000000000..d8d4c1790 --- /dev/null +++ b/packages/nextjs/utils/eas-wagmi-utils.ts @@ -0,0 +1,69 @@ +import { useEffect, useState } from "react"; +import { BrowserProvider, FallbackProvider, JsonRpcProvider, JsonRpcSigner } from "ethers"; +import { type HttpTransport, type PublicClient, type WalletClient } from "viem"; +import { usePublicClient, useWalletClient } from "wagmi"; + +export function publicClientToProvider(publicClient: PublicClient) { + const { chain, transport } = publicClient; + const network = { + chainId: chain?.id, + name: chain?.name, + ensAddress: chain?.contracts?.ensRegistry?.address, + }; + if (transport.type === "fallback") + return new FallbackProvider( + (transport.transports as ReturnType[]).map( + ({ value }) => new JsonRpcProvider(value?.url, network), + ), + ); + return new JsonRpcProvider(transport.url, network); +} + +export function walletClientToSigner(walletClient: WalletClient) { + const { account, chain, transport } = walletClient; + const network = { + chainId: chain?.id, + name: chain?.name, + ensAddress: chain?.contracts?.ensRegistry?.address, + }; + const provider = new BrowserProvider(transport, network); + const signer = provider.getSigner(account?.address); + + return signer; +} + +export function useSigner() { + const { data: walletClient } = useWalletClient(); + + const [signer, setSigner] = useState(undefined); + useEffect(() => { + async function getSigner() { + if (!walletClient) return; + + const tmpSigner = await walletClientToSigner(walletClient); + + setSigner(tmpSigner); + } + + getSigner(); + }, [walletClient]); + return signer; +} + +export function useProvider() { + const publicClient = usePublicClient(); + + const [provider, setProvider] = useState(undefined); + useEffect(() => { + async function getSigner() { + if (!publicClient) return; + + const tmpProvider = publicClientToProvider(publicClient); + + setProvider(tmpProvider as JsonRpcProvider); + } + + getSigner(); + }, [publicClient]); + return provider; +} diff --git a/yarn.lock b/yarn.lock index f2486a022..d0f60a441 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19,6 +19,13 @@ __metadata: languageName: node linkType: hard +"@adraffy/ens-normalize@npm:1.10.1": + version: 1.10.1 + resolution: "@adraffy/ens-normalize@npm:1.10.1" + checksum: 0836f394ea256972ec19a0b5e78cb7f5bcdfd48d8a32c7478afc94dd53ae44c04d1aa2303d7f3077b4f3ac2323b1f557ab9188e8059978748fdcd83e04a80dcc + languageName: node + linkType: hard + "@adraffy/ens-normalize@npm:1.9.4": version: 1.9.4 resolution: "@adraffy/ens-normalize@npm:1.9.4" @@ -529,6 +536,55 @@ __metadata: languageName: node linkType: hard +"@ethereum-attestation-service/eas-contracts@npm:1.4.1": + version: 1.4.1 + resolution: "@ethereum-attestation-service/eas-contracts@npm:1.4.1" + dependencies: + hardhat: 2.22.1 + checksum: 9b78873bbb9efd8540fd332bedd660750c7bba0202ee894a1eaec5f13fc6f691332bf8cdedefe49b043e5be748c2ed7889b5e53f617a8585c5ae1d2e4351a350 + languageName: node + linkType: hard + +"@ethereum-attestation-service/eas-contracts@npm:^1.7.1": + version: 1.7.1 + resolution: "@ethereum-attestation-service/eas-contracts@npm:1.7.1" + dependencies: + hardhat: 2.22.4 + checksum: 2d9e948261359892b4e8bf416c1a43c9606c93edec35539d941e43f668e692002948f67a127b9cf6995d7c602ad70f7879c39e344682b12e8dee81b208c14620 + languageName: node + linkType: hard + +"@ethereum-attestation-service/eas-sdk@npm:^2.2.0": + version: 2.2.0 + resolution: "@ethereum-attestation-service/eas-sdk@npm:2.2.0" + dependencies: + "@ethereum-attestation-service/eas-contracts": 1.4.1 + ethers: ^6.11.1 + js-base64: ^3.7.7 + lodash: ^4.17.21 + multiformats: 9.9.0 + pako: ^2.1.0 + semver: ^7.6.0 + checksum: 69effa0812b6c62bfb1b5b1492992b277f6b481f27aed8e030fadf03741f13907bb9e0ae4a472443fb99dcac6c0c14175e531bef6f0de9c6fa919efad88e8782 + languageName: node + linkType: hard + +"@ethereum-attestation-service/eas-sdk@npm:^2.3.0": + version: 2.3.0 + resolution: "@ethereum-attestation-service/eas-sdk@npm:2.3.0" + dependencies: + "@ethereum-attestation-service/eas-contracts": 1.4.1 + "@openzeppelin/merkle-tree": ^1.0.6 + ethers: ^6.11.1 + js-base64: ^3.7.7 + lodash: ^4.17.21 + multiformats: 9.9.0 + pako: ^2.1.0 + semver: ^7.6.0 + checksum: b78dc1495e2f6aa39d0caf3a5008915e7e6b1c01857395ce359fa343725408b6af082e762febb5327d0e460d549ff703e99806432f56c12bbcafb5749a6e8867 + languageName: node + linkType: hard + "@ethereumjs/common@npm:^3.2.0": version: 3.2.0 resolution: "@ethereumjs/common@npm:3.2.0" @@ -1514,6 +1570,70 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/edr-darwin-arm64@npm:0.3.8": + version: 0.3.8 + resolution: "@nomicfoundation/edr-darwin-arm64@npm:0.3.8" + checksum: 20166c1cd0413fb3078c8240ad3604fb6ff6076b8142dfff14e51715ed313c73ec90486fe0a3b5a48ca3031e98e92339cd2bf825f6f199bfdf9b41bec906ebb8 + languageName: node + linkType: hard + +"@nomicfoundation/edr-darwin-x64@npm:0.3.8": + version: 0.3.8 + resolution: "@nomicfoundation/edr-darwin-x64@npm:0.3.8" + checksum: c9ba1c9eeda71876f6c69550b20f7b0d865f6249cb88c0a3dc853d7ca32061d9a71f40f14cc628fa7f286786fc2cd48c5a2a9527a6d0f55939f2a9565809b561 + languageName: node + linkType: hard + +"@nomicfoundation/edr-linux-arm64-gnu@npm:0.3.8": + version: 0.3.8 + resolution: "@nomicfoundation/edr-linux-arm64-gnu@npm:0.3.8" + checksum: bebb780f8c22ca13af9b336873a6d00091139f88669ba4c569d03efd7a6671f10b4c6afd7ee9444d9b18364d05eedf46f4dd82d1e7329de32267175127a6989b + languageName: node + linkType: hard + +"@nomicfoundation/edr-linux-arm64-musl@npm:0.3.8": + version: 0.3.8 + resolution: "@nomicfoundation/edr-linux-arm64-musl@npm:0.3.8" + checksum: 6cf009e4686780c41c6af271e67d1414b5e5096e5422f64980b8c3a4ddd6273b3289a5d228d976b217d6c1d8da52af912f599d923a098225b9dd906f03b889c8 + languageName: node + linkType: hard + +"@nomicfoundation/edr-linux-x64-gnu@npm:0.3.8": + version: 0.3.8 + resolution: "@nomicfoundation/edr-linux-x64-gnu@npm:0.3.8" + checksum: 6afb66601880bee40a254272ecb88d3c00b1acd97bde503127b2d900d15aa2707926b56e652abdfb0c0e75dde53e201aaef40ae0fd3bd7c6e48163eaa6ed3a17 + languageName: node + linkType: hard + +"@nomicfoundation/edr-linux-x64-musl@npm:0.3.8": + version: 0.3.8 + resolution: "@nomicfoundation/edr-linux-x64-musl@npm:0.3.8" + checksum: 72cd4be88ea30fd47fa1f984f446d80bf6d33e928e35df02ae4b842701b459dd92d7ba4071e388c95739a9688d6247100cb7155f3e67a5e624f54b2b42098dfd + languageName: node + linkType: hard + +"@nomicfoundation/edr-win32-x64-msvc@npm:0.3.8": + version: 0.3.8 + resolution: "@nomicfoundation/edr-win32-x64-msvc@npm:0.3.8" + checksum: d7b5bbe71f2347075a9e4d88d22609ec9b8058734ee048ff94300fecb51afad96d0d596686ad9cf6cf8ee74d1c117bf53ce5d77bf077cb472977d4a9bd88eb43 + languageName: node + linkType: hard + +"@nomicfoundation/edr@npm:^0.3.1, @nomicfoundation/edr@npm:^0.3.7": + version: 0.3.8 + resolution: "@nomicfoundation/edr@npm:0.3.8" + dependencies: + "@nomicfoundation/edr-darwin-arm64": 0.3.8 + "@nomicfoundation/edr-darwin-x64": 0.3.8 + "@nomicfoundation/edr-linux-arm64-gnu": 0.3.8 + "@nomicfoundation/edr-linux-arm64-musl": 0.3.8 + "@nomicfoundation/edr-linux-x64-gnu": 0.3.8 + "@nomicfoundation/edr-linux-x64-musl": 0.3.8 + "@nomicfoundation/edr-win32-x64-msvc": 0.3.8 + checksum: 31047fdde18034e2c6bd65dfbe3192c149b2af7f06a108e8c7b829c45bc5071c9d536c68d2d3b988bc67c7f7d331f0a88eee49ce3c882b3bcd5e20bc301d32a8 + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-block@npm:5.0.2": version: 5.0.2 resolution: "@nomicfoundation/ethereumjs-block@npm:5.0.2" @@ -1560,6 +1680,15 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-common@npm:4.0.4": + version: 4.0.4 + resolution: "@nomicfoundation/ethereumjs-common@npm:4.0.4" + dependencies: + "@nomicfoundation/ethereumjs-util": 9.0.4 + checksum: ce3f6e4ae15b976efdb7ccda27e19aadb62b5ffee209f9503e68b4fd8633715d4d697c0cc10ccd35f5e4e977edd05100d0f214e28880ec64fff77341dc34fcdf + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-ethash@npm:3.0.2": version: 3.0.2 resolution: "@nomicfoundation/ethereumjs-ethash@npm:3.0.2" @@ -1599,6 +1728,15 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-rlp@npm:5.0.4": + version: 5.0.4 + resolution: "@nomicfoundation/ethereumjs-rlp@npm:5.0.4" + bin: + rlp: bin/rlp.cjs + checksum: ee2c2e5776c73801dc5ed636f4988b599b4563c2d0037da542ea57eb237c69dd1ac555f6bcb5e06f70515b6459779ba0d68252a6e105132b4659ab4bf62919b0 + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-statemanager@npm:2.0.2": version: 2.0.2 resolution: "@nomicfoundation/ethereumjs-statemanager@npm:2.0.2" @@ -1640,6 +1778,23 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-tx@npm:5.0.4": + version: 5.0.4 + resolution: "@nomicfoundation/ethereumjs-tx@npm:5.0.4" + dependencies: + "@nomicfoundation/ethereumjs-common": 4.0.4 + "@nomicfoundation/ethereumjs-rlp": 5.0.4 + "@nomicfoundation/ethereumjs-util": 9.0.4 + ethereum-cryptography: 0.1.3 + peerDependencies: + c-kzg: ^2.1.2 + peerDependenciesMeta: + c-kzg: + optional: true + checksum: 0f1c87716682ccbcf4d92ffc6cf8ab557e658b90319d82be3219a091a736859f8803c73c98e4863682e3e86d264751c472d33ff6d3c3daf4e75b5f01d0af8fa3 + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-util@npm:9.0.2": version: 9.0.2 resolution: "@nomicfoundation/ethereumjs-util@npm:9.0.2" @@ -1651,6 +1806,21 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-util@npm:9.0.4": + version: 9.0.4 + resolution: "@nomicfoundation/ethereumjs-util@npm:9.0.4" + dependencies: + "@nomicfoundation/ethereumjs-rlp": 5.0.4 + ethereum-cryptography: 0.1.3 + peerDependencies: + c-kzg: ^2.1.2 + peerDependenciesMeta: + c-kzg: + optional: true + checksum: 754439f72b11cad2d8986707ad020077dcc763c4055f73e2668a0b4cadb22aa4407faa9b3c587d9eb5b97ac337afbe037eb642bc1d5a16197284f83db3462cbe + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-vm@npm:7.0.2": version: 7.0.2 resolution: "@nomicfoundation/ethereumjs-vm@npm:7.0.2" @@ -1857,6 +2027,16 @@ __metadata: languageName: node linkType: hard +"@openzeppelin/merkle-tree@npm:^1.0.6": + version: 1.0.6 + resolution: "@openzeppelin/merkle-tree@npm:1.0.6" + dependencies: + "@ethersproject/abi": ^5.7.0 + ethereum-cryptography: ^1.1.2 + checksum: 1f6bfd986e10fa9b699de878ae606c5bffbf21b47b10c52ca9efb5de8d42fc2df0221c05ddbb6a7a617e4c2f758b151b8624806f4184a3084d66de418c9d9c28 + languageName: node + linkType: hard + "@parcel/watcher-android-arm64@npm:2.3.0": version: 2.3.0 resolution: "@parcel/watcher-android-arm64@npm:2.3.0" @@ -2148,6 +2328,7 @@ __metadata: version: 0.0.0-use.local resolution: "@se-2/hardhat@workspace:packages/hardhat" dependencies: + "@ethereum-attestation-service/eas-contracts": ^1.7.1 "@ethersproject/abi": ^5.7.0 "@ethersproject/providers": ^5.7.1 "@nomicfoundation/hardhat-chai-matchers": ^2.0.3 @@ -2188,6 +2369,7 @@ __metadata: version: 0.0.0-use.local resolution: "@se-2/nextjs@workspace:packages/nextjs" dependencies: + "@ethereum-attestation-service/eas-sdk": ^2.2.0 "@heroicons/react": ^2.0.11 "@rainbow-me/rainbowkit": ^2.0.2 "@tanstack/react-query": ^5.28.6 @@ -4067,6 +4249,15 @@ __metadata: languageName: node linkType: hard +"ansi-align@npm:^3.0.0": + version: 3.0.1 + resolution: "ansi-align@npm:3.0.1" + dependencies: + string-width: ^4.1.0 + checksum: 6abfa08f2141d231c257162b15292467081fa49a208593e055c866aa0455b57f3a86b5a678c190c618faa79b4c59e254493099cb700dd9cf2293c6be2c8f5d8d + languageName: node + linkType: hard + "ansi-colors@npm:3.2.3": version: 3.2.3 resolution: "ansi-colors@npm:3.2.3" @@ -4689,6 +4880,22 @@ __metadata: languageName: node linkType: hard +"boxen@npm:^5.1.2": + version: 5.1.2 + resolution: "boxen@npm:5.1.2" + dependencies: + ansi-align: ^3.0.0 + camelcase: ^6.2.0 + chalk: ^4.1.0 + cli-boxes: ^2.2.1 + string-width: ^4.2.2 + type-fest: ^0.20.2 + widest-line: ^3.1.0 + wrap-ansi: ^7.0.0 + checksum: 82d03e42a72576ff235123f17b7c505372fe05c83f75f61e7d4fa4bcb393897ec95ce766fecb8f26b915f0f7a7227d66e5ec7cef43f5b2bd9d3aeed47ec55877 + languageName: node + linkType: hard + "brace-expansion@npm:^1.1.7": version: 1.1.11 resolution: "brace-expansion@npm:1.1.11" @@ -4906,7 +5113,7 @@ __metadata: languageName: node linkType: hard -"camelcase@npm:^6.0.0": +"camelcase@npm:^6.0.0, camelcase@npm:^6.2.0": version: 6.3.0 resolution: "camelcase@npm:6.3.0" checksum: 8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d @@ -5138,6 +5345,13 @@ __metadata: languageName: node linkType: hard +"cli-boxes@npm:^2.2.1": + version: 2.2.1 + resolution: "cli-boxes@npm:2.2.1" + checksum: be79f8ec23a558b49e01311b39a1ea01243ecee30539c880cf14bf518a12e223ef40c57ead0cb44f509bffdffc5c129c746cd50d863ab879385370112af4f585 + languageName: node + linkType: hard + "cli-cursor@npm:^4.0.0": version: 4.0.0 resolution: "cli-cursor@npm:4.0.0" @@ -6946,7 +7160,7 @@ __metadata: languageName: node linkType: hard -"ethereum-cryptography@npm:^1.0.3": +"ethereum-cryptography@npm:^1.0.3, ethereum-cryptography@npm:^1.1.2": version: 1.2.0 resolution: "ethereum-cryptography@npm:1.2.0" dependencies: @@ -7078,6 +7292,21 @@ __metadata: languageName: node linkType: hard +"ethers@npm:^6.11.1, ethers@npm:^6.13.1": + version: 6.13.1 + resolution: "ethers@npm:6.13.1" + dependencies: + "@adraffy/ens-normalize": 1.10.1 + "@noble/curves": 1.2.0 + "@noble/hashes": 1.3.2 + "@types/node": 18.15.13 + aes-js: 4.0.0-beta.5 + tslib: 2.4.0 + ws: 8.17.1 + checksum: beef4b6d117f64c369f44be631e0f666b966374eac0cc0446fa7abe114b11d6b3019060022eec65c031f150711f4913d249de507ff3da3204e654635db80a07e + languageName: node + linkType: hard + "ethjs-unit@npm:0.1.6": version: 0.1.6 resolution: "ethjs-unit@npm:0.1.6" @@ -8231,6 +8460,128 @@ __metadata: languageName: node linkType: hard +"hardhat@npm:2.22.1": + version: 2.22.1 + resolution: "hardhat@npm:2.22.1" + dependencies: + "@ethersproject/abi": ^5.1.2 + "@metamask/eth-sig-util": ^4.0.0 + "@nomicfoundation/edr": ^0.3.1 + "@nomicfoundation/ethereumjs-common": 4.0.4 + "@nomicfoundation/ethereumjs-tx": 5.0.4 + "@nomicfoundation/ethereumjs-util": 9.0.4 + "@nomicfoundation/solidity-analyzer": ^0.1.0 + "@sentry/node": ^5.18.1 + "@types/bn.js": ^5.1.0 + "@types/lru-cache": ^5.1.0 + adm-zip: ^0.4.16 + aggregate-error: ^3.0.0 + ansi-escapes: ^4.3.0 + boxen: ^5.1.2 + chalk: ^2.4.2 + chokidar: ^3.4.0 + ci-info: ^2.0.0 + debug: ^4.1.1 + enquirer: ^2.3.0 + env-paths: ^2.2.0 + ethereum-cryptography: ^1.0.3 + ethereumjs-abi: ^0.6.8 + find-up: ^2.1.0 + fp-ts: 1.19.3 + fs-extra: ^7.0.1 + glob: 7.2.0 + immutable: ^4.0.0-rc.12 + io-ts: 1.10.4 + keccak: ^3.0.2 + lodash: ^4.17.11 + mnemonist: ^0.38.0 + mocha: ^10.0.0 + p-map: ^4.0.0 + raw-body: ^2.4.1 + resolve: 1.17.0 + semver: ^6.3.0 + solc: 0.7.3 + source-map-support: ^0.5.13 + stacktrace-parser: ^0.1.10 + tsort: 0.0.1 + undici: ^5.14.0 + uuid: ^8.3.2 + ws: ^7.4.6 + peerDependencies: + ts-node: "*" + typescript: "*" + peerDependenciesMeta: + ts-node: + optional: true + typescript: + optional: true + bin: + hardhat: internal/cli/bootstrap.js + checksum: 6494697d37198d32b9151e8303b8e771f1d10f50ddd5488c619a8b6d36c6ee391a274ce75f7ac17b574fec84e6e1dc11f63487d308013873183cd2af58865200 + languageName: node + linkType: hard + +"hardhat@npm:2.22.4": + version: 2.22.4 + resolution: "hardhat@npm:2.22.4" + dependencies: + "@ethersproject/abi": ^5.1.2 + "@metamask/eth-sig-util": ^4.0.0 + "@nomicfoundation/edr": ^0.3.7 + "@nomicfoundation/ethereumjs-common": 4.0.4 + "@nomicfoundation/ethereumjs-tx": 5.0.4 + "@nomicfoundation/ethereumjs-util": 9.0.4 + "@nomicfoundation/solidity-analyzer": ^0.1.0 + "@sentry/node": ^5.18.1 + "@types/bn.js": ^5.1.0 + "@types/lru-cache": ^5.1.0 + adm-zip: ^0.4.16 + aggregate-error: ^3.0.0 + ansi-escapes: ^4.3.0 + boxen: ^5.1.2 + chalk: ^2.4.2 + chokidar: ^3.4.0 + ci-info: ^2.0.0 + debug: ^4.1.1 + enquirer: ^2.3.0 + env-paths: ^2.2.0 + ethereum-cryptography: ^1.0.3 + ethereumjs-abi: ^0.6.8 + find-up: ^2.1.0 + fp-ts: 1.19.3 + fs-extra: ^7.0.1 + glob: 7.2.0 + immutable: ^4.0.0-rc.12 + io-ts: 1.10.4 + keccak: ^3.0.2 + lodash: ^4.17.11 + mnemonist: ^0.38.0 + mocha: ^10.0.0 + p-map: ^4.0.0 + raw-body: ^2.4.1 + resolve: 1.17.0 + semver: ^6.3.0 + solc: 0.7.3 + source-map-support: ^0.5.13 + stacktrace-parser: ^0.1.10 + tsort: 0.0.1 + undici: ^5.14.0 + uuid: ^8.3.2 + ws: ^7.4.6 + peerDependencies: + ts-node: "*" + typescript: "*" + peerDependenciesMeta: + ts-node: + optional: true + typescript: + optional: true + bin: + hardhat: internal/cli/bootstrap.js + checksum: c10deb21dac800fe4356f7325646ffef6542704894bd5712fe91246ba307d1f9b02a26998cf2e2adddf299c82e2f19afce33dadbc1afcd7de1692296157fdefc + languageName: node + linkType: hard + "hardhat@npm:^2.19.4": version: 2.19.4 resolution: "hardhat@npm:2.19.4" @@ -9231,6 +9582,13 @@ __metadata: languageName: node linkType: hard +"js-base64@npm:^3.7.7": + version: 3.7.7 + resolution: "js-base64@npm:3.7.7" + checksum: d1b02971db9dc0fd35baecfaf6ba499731fb44fe3373e7e1d6681fbd3ba665f29e8d9d17910254ef8104e2cb8b44117fe4202d3dc54c7cafe9ba300fe5433358 + languageName: node + linkType: hard + "js-sdsl@npm:^4.1.4": version: 4.4.2 resolution: "js-sdsl@npm:4.4.2" @@ -10443,7 +10801,7 @@ __metadata: languageName: node linkType: hard -"multiformats@npm:^9.4.2": +"multiformats@npm:9.9.0, multiformats@npm:^9.4.2": version: 9.9.0 resolution: "multiformats@npm:9.9.0" checksum: d3e8c1be400c09a014f557ea02251a2710dbc9fca5aa32cc702ff29f636c5471e17979f30bdcb0a9cbb556f162a8591dc2e1219c24fc21394a56115b820bb84e @@ -11212,6 +11570,13 @@ __metadata: languageName: node linkType: hard +"pako@npm:^2.1.0": + version: 2.1.0 + resolution: "pako@npm:2.1.0" + checksum: 71666548644c9a4d056bcaba849ca6fd7242c6cf1af0646d3346f3079a1c7f4a66ffec6f7369ee0dc88f61926c10d6ab05da3e1fca44b83551839e89edd75a3e + languageName: node + linkType: hard + "parent-module@npm:^1.0.0": version: 1.0.1 resolution: "parent-module@npm:1.0.1" @@ -12594,6 +12959,8 @@ __metadata: version: 0.0.0-use.local resolution: "se-2@workspace:." dependencies: + "@ethereum-attestation-service/eas-sdk": ^2.3.0 + ethers: ^6.13.1 husky: ^8.0.1 lint-staged: ^13.0.3 languageName: unknown @@ -12663,6 +13030,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.6.0": + version: 7.6.2 + resolution: "semver@npm:7.6.2" + bin: + semver: bin/semver.js + checksum: 40f6a95101e8d854357a644da1b8dd9d93ce786d5c6a77227bc69dbb17bea83d0d1d1d7c4cd5920a6df909f48e8bd8a5909869535007f90278289f2451d0292d + languageName: node + linkType: hard + "serialize-javascript@npm:6.0.0": version: 6.0.0 resolution: "serialize-javascript@npm:6.0.0" @@ -13143,7 +13519,7 @@ __metadata: languageName: node linkType: hard -"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.0.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.2, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" dependencies: @@ -14770,6 +15146,15 @@ __metadata: languageName: node linkType: hard +"widest-line@npm:^3.1.0": + version: 3.1.0 + resolution: "widest-line@npm:3.1.0" + dependencies: + string-width: ^4.0.0 + checksum: 03db6c9d0af9329c37d74378ff1d91972b12553c7d72a6f4e8525fe61563fa7adb0b9d6e8d546b7e059688712ea874edd5ded475999abdeedf708de9849310e0 + languageName: node + linkType: hard + "word-wrap@npm:~1.2.3": version: 1.2.5 resolution: "word-wrap@npm:1.2.5" @@ -14882,6 +15267,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:8.17.1": + version: 8.17.1 + resolution: "ws@npm:8.17.1" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 442badcce1f1178ec87a0b5372ae2e9771e07c4929a3180321901f226127f252441e8689d765aa5cfba5f50ac60dd830954afc5aeae81609aefa11d3ddf5cecf + languageName: node + linkType: hard + "ws@npm:8.5.0": version: 8.5.0 resolution: "ws@npm:8.5.0"