├── README.md └── contracts ├── BlobHashGetter.sol └── TestBlobHashGetter.sol /README.md: -------------------------------------------------------------------------------- 1 | # eip4844-blob-hash-getter 2 | 3 | 4 | 5 | 6 | ## Motivation 7 | EIP-4844 introduces the binary large object (BLOB) and adds DATAHASH (0x49) opcode to retrieve the hash of the BLOB. Unfortunately, it takes some time for solidity to support the new opcode. As a result, it will be difficult for developers to experiment with the BLOB features on devnet. 8 | 9 | 10 | This repo provides a simple solidity implementation to support getting the data hash of a BLOB. The basic idea is to deploy a customized assembly code in a contract, where the assembly code accepts 32-byte input as data index and outputs 32 bytes as datahash. Then a solidity library is created to hide the details of the underlying assembly code call. 11 | 12 | 13 | 14 | 15 | ## Assembly Code to Support DATAHASH opcode 16 | 17 | 18 | The assembly code we use is `0x6000354960005260206000F3`, and the disassembly description is 19 | 20 | 21 | ``` 22 | 0x6000 23 | 0x35 # calldataload msg[0:32] 24 | 0x49 # datahash 25 | 0x6000 26 | 0x52 # mstore offset=0, value=datahash 27 | 0x6020 28 | 0x6000 29 | 0xF3 # return offset=0, length=32 30 | ``` 31 | 32 | 33 | ## How to Test? 34 | 35 | 36 | First, you need to run an EIP-4844 devnet. Next, you need to deploy the assembly code by calling `BlobHashGetterDeployer.deploy()`. Now, you can use `BlobHashGetter.getBlobHash()` to retrieve the blob hash. -------------------------------------------------------------------------------- /contracts/BlobHashGetter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.11; 4 | 5 | contract ContractFactory { 6 | constructor(bytes memory code) payable { 7 | uint256 size = code.length; 8 | assembly { 9 | return(add(code, 0x020), size) 10 | } 11 | } 12 | } 13 | 14 | contract BlobHashGetterDeployer { 15 | bytes internal CODE = hex"6000354960005260206000F3"; 16 | 17 | function deploy() public returns (address) { 18 | return address(new ContractFactory(CODE)); 19 | } 20 | } 21 | 22 | library BlobHashGetter { 23 | function getBlobHash(address getter, uint256 idx) internal view returns (bytes32) { 24 | bool success; 25 | bytes32 blobHash; 26 | assembly { 27 | mstore(0x0, idx) 28 | 29 | success := staticcall(gas(), getter, 0x0, 0x20, 0x0, 0x20) 30 | 31 | blobHash := mload(0x0) 32 | } 33 | 34 | require(success, "failed to get"); 35 | return blobHash; 36 | } 37 | } -------------------------------------------------------------------------------- /contracts/TestBlobHashGetter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.11; 4 | 5 | import "./BlobHashGetter.sol"; 6 | 7 | contract TestBlobHashGetter { 8 | bytes32 public blobHash; 9 | 10 | function getAndSetBlobHash(address getter, uint256 idx) public { 11 | blobHash = BlobHashGetter.getBlobHash(getter, idx); 12 | } 13 | } --------------------------------------------------------------------------------