From acdeaf41dc598a4420e115a9fb5c6b5cc8774234 Mon Sep 17 00:00:00 2001 From: ryley-o <30364988+ryley-o@users.noreply.github.com> Date: Fri, 7 Mar 2025 15:49:49 -0800 Subject: [PATCH] update logic --- ...tecodeStorageReaderContractV2_Web3Call.sol | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 packages/contracts/contracts/BytecodeStorageReaders/BytecodeStorageReaderContractV2_Web3Call.sol diff --git a/packages/contracts/contracts/BytecodeStorageReaders/BytecodeStorageReaderContractV2_Web3Call.sol b/packages/contracts/contracts/BytecodeStorageReaders/BytecodeStorageReaderContractV2_Web3Call.sol new file mode 100644 index 000000000..8193cee7e --- /dev/null +++ b/packages/contracts/contracts/BytecodeStorageReaders/BytecodeStorageReaderContractV2_Web3Call.sol @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity 0.8.22; + +// Created By: Art Blocks Inc. + +import {IBytecodeStorageReaderV2} from "../interfaces/v0.8.x/IBytecodeStorageReaderV2.sol"; +import {IWeb3Call} from "../interfaces/v0.8.x/IWeb3Call.sol"; + +import {BytecodeStorageReader} from "../libs/v0.8.x/BytecodeStorageV2.sol"; + +import {ERC165Checker} from "@openzeppelin-5.0/contracts/utils/introspection/ERC165Checker.sol"; + +/** + * @title Art Blocks Bytecode Storage Reader Contract V2 w/ Web3Call Support + * @author Art Blocks Inc. + * @notice This contract is used to read the bytecode of a contract deployed by Art Blocks' BytecodeStorage library, + * for versions 0, 1, and 2 of the Art Blocks BytecodeStorage library. + * It includes support for returning the special string "#web3call_contract#" when reading a non-bytecode storage + * contract that does indicate ERC165 support for the IWeb3Call interface, enabling backwards-compatibility with + * Web3Call-based projects on exiting Art Blocks contracts. This only affects the readFromBytecode function. + * It is permissionless and can be used by anyone to read the bytecode of any contract deployed by Art Blocks. + * Future versions of BytecodeStorage will not be compatible with this reader. + * For a single location to read current and future versions of the Art Blocks BytecodeStorage library, see + * the UniversalBytecodeStorageReader contract, maintained by the Art Blocks team. + * Additional functionality is provided to read bytes data stored using the SSTORE2 library. + * This contract also provides an interface to read additional metadata stored by the Art Blocks BytecodeStorage + * library, such as the contract's version, deployer, and other metadata. + * @dev For simplicity and reduce code changes, this contract uses the BytecodeStorageReader external library to + * perform many operations. Future reader contract versions may choose to make the library internal to this contract to + * improve read operation performance. + */ +contract BytecodeStorageReaderContractV2_Web3Call is IBytecodeStorageReaderV2 { + using BytecodeStorageReader for address; + + string public constant VERSION = "BytecodeStorageReaderContractV2"; + + /** + * @notice Read a string from a data contract deployed via BytecodeStorage V2 or earlier. + * @param address_ address of contract deployed via BytecodeStorage to be read + * @return The string data stored at the specific address. + */ + function readFromBytecode( + address address_ + ) external view returns (string memory) { + try address_.readFromBytecode() returns (string memory data) { + return data; + } catch { + if ( + ERC165Checker.supportsInterface( + address_, + type(IWeb3Call).interfaceId + ) + ) { + return "#web3call_contract#"; + } + } + // reading from bytecode failed, and does not indicate Web3Call support, so revert + revert( + "BytecodeStorageReaderContractV2_Web3Call: Failed to read from bytecode" + ); + } + + /** + * @notice Read a bytes array from the SSTORE2-formatted bytecode of a contract. + * Note that this function is only compatible with contracts that have been deployed using the popular SSTORE2 + * library. + * @param address_ address of contract with SSTORE2-formatted bytecode to be read + * @return data The bytes data stored at the specific address. + */ + function readBytesFromSSTORE2Bytecode( + address address_ + ) external view returns (bytes memory) { + return address_.readBytesFromSSTORE2Bytecode(); + } + + /** + * @notice Read a bytes array from the a contract deployed via BytecodeStorage V2 or earlier. + * @param address_ address of contract with valid bytecode to be read + * @param offset offset to read from in contract bytecode, explicitly provided (not calculated) + * @return The bytes data stored at the specific address. + */ + function readBytesFromBytecode( + address address_, + uint256 offset + ) external view returns (bytes memory) { + return address_.readBytesFromBytecode(offset); + } + + //------ Metadata Functions ------// + + /** + * @notice Get address of deployer for given contract deployed via BytecodeStorage V2 or earlier. + * @param address_ address of deployed contract + * @return writerAddress address of deployer + */ + function getWriterAddressForBytecode( + address address_ + ) external view returns (address) { + return address_.getWriterAddressForBytecode(); + } + + /** + * @notice Get version for given contract deployed via BytecodeStorage V2 or earlier. + * @param address_ address of deployed contract + * @return version version of the contract + */ + function getLibraryVersionForBytecode( + address address_ + ) external view returns (bytes32) { + return address_.getLibraryVersionForBytecode(); + } + + /** + * @notice Get if data are stored in compressed format for given contract deployed via BytecodeStorage V2 or + * earlier. + * @param _address address of deployed contract + * @return isCompressed boolean indicating if the stored data are compressed + */ + function getIsCompressedForBytecode( + address _address + ) external view returns (bool) { + return _address.getIsCompressedForBytecode(); + } +}