Skip to content

Commit 2150f74

Browse files
r0qscameel
andcommitted
Add blobhash opcode
Co-authored-by: Kamil Śliwak <kamil.sliwak@codepoets.it>
1 parent 5aace4f commit 2150f74

28 files changed

+204
-6
lines changed

Changelog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Language Features:
44
* Introduce global ``block.blobbasefee`` for retrieving the blob base fee of the current block.
55
* Yul: Introduce builtin ``blobbasefee()`` for retrieving the blob base fee of the current block.
6-
6+
* Yul: Introduce builtin ``blobhash()`` for retrieving versioned hashes of blobs associated with the transaction.
77

88
Compiler Features:
99
* EVM: Support for the EVM Version "Cancun".

docs/grammar/SolidityLexer.g4

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,8 @@ YulEVMBuiltin:
304304
| 'returndatacopy' | 'extcodehash' | 'create' | 'create2' | 'call' | 'callcode'
305305
| 'delegatecall' | 'staticcall' | 'return' | 'revert' | 'selfdestruct' | 'invalid'
306306
| 'log0' | 'log1' | 'log2' | 'log3' | 'log4' | 'chainid' | 'origin' | 'gasprice'
307-
| 'blockhash' | 'coinbase' | 'timestamp' | 'number' | 'difficulty' | 'prevrandao'
308-
| 'gaslimit' | 'basefee' | 'blobbasefee';
307+
| 'blockhash' | 'blobhash' | 'coinbase' | 'timestamp' | 'number' | 'difficulty'
308+
| 'prevrandao' | 'gaslimit' | 'basefee' | 'blobbasefee';
309309
310310
YulLBrace: '{' -> pushMode(YulMode);
311311
YulRBrace: '}' -> popMode;

docs/yul.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,8 @@ the ``dup`` and ``swap`` instructions as well as ``jump`` instructions, labels a
927927
+-------------------------+-----+---+-----------------------------------------------------------------+
928928
| blockhash(b) | | F | hash of block nr b - only for last 256 blocks excluding current |
929929
+-------------------------+-----+---+-----------------------------------------------------------------+
930+
| blobhash(i) | | N | versioned hash of transaction's i-th blob |
931+
+-------------------------+-----+---+-----------------------------------------------------------------+
930932
| coinbase() | | F | current mining beneficiary |
931933
+-------------------------+-----+---+-----------------------------------------------------------------+
932934
| timestamp() | | F | timestamp of the current block in seconds since the epoch |

libevmasm/Instruction.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ std::map<std::string, Instruction> const solidity::evmasm::c_instructions =
7272
{ "RETURNDATACOPY", Instruction::RETURNDATACOPY },
7373
{ "EXTCODEHASH", Instruction::EXTCODEHASH },
7474
{ "BLOCKHASH", Instruction::BLOCKHASH },
75+
{ "BLOBHASH", Instruction::BLOBHASH },
7576
{ "COINBASE", Instruction::COINBASE },
7677
{ "TIMESTAMP", Instruction::TIMESTAMP },
7778
{ "NUMBER", Instruction::NUMBER },
@@ -223,6 +224,7 @@ static std::map<Instruction, InstructionInfo> const c_instructionInfo =
223224
{ Instruction::RETURNDATACOPY, {"RETURNDATACOPY", 0, 3, 0, true, Tier::VeryLow } },
224225
{ Instruction::EXTCODEHASH, { "EXTCODEHASH", 0, 1, 1, false, Tier::Balance } },
225226
{ Instruction::BLOCKHASH, { "BLOCKHASH", 0, 1, 1, false, Tier::Ext } },
227+
{ Instruction::BLOBHASH, { "BLOBHASH", 0, 1, 1, false, Tier::VeryLow } },
226228
{ Instruction::COINBASE, { "COINBASE", 0, 0, 1, false, Tier::Base } },
227229
{ Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1, false, Tier::Base } },
228230
{ Instruction::NUMBER, { "NUMBER", 0, 0, 1, false, Tier::Base } },

libevmasm/Instruction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ enum class Instruction: uint8_t
8989
CHAINID, ///< get the config's chainid param
9090
SELFBALANCE, ///< get balance of the current account
9191
BASEFEE, ///< get the block's basefee
92+
BLOBHASH = 0x49, ///< get a versioned hash of one of the blobs associated with the transaction
9293
BLOBBASEFEE = 0x4a, ///< get the block's blob basefee
9394

9495
POP = 0x50, ///< remove item from stack

libevmasm/SemanticInformation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ bool SemanticInformation::invalidInPureFunctions(Instruction _instruction)
480480
case Instruction::EXTCODECOPY:
481481
case Instruction::EXTCODEHASH:
482482
case Instruction::BLOCKHASH:
483+
case Instruction::BLOBHASH:
483484
case Instruction::COINBASE:
484485
case Instruction::TIMESTAMP:
485486
case Instruction::NUMBER:

libevmasm/SimplificationRule.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ struct EVMBuiltins
119119
static auto constexpr RETURNDATACOPY = PatternGenerator<Instruction::RETURNDATACOPY>{};
120120
static auto constexpr EXTCODEHASH = PatternGenerator<Instruction::EXTCODEHASH>{};
121121
static auto constexpr BLOCKHASH = PatternGenerator<Instruction::BLOCKHASH>{};
122+
static auto constexpr BLOBHASH = PatternGenerator<Instruction::BLOBHASH>{};
122123
static auto constexpr COINBASE = PatternGenerator<Instruction::COINBASE>{};
123124
static auto constexpr TIMESTAMP = PatternGenerator<Instruction::TIMESTAMP>{};
124125
static auto constexpr NUMBER = PatternGenerator<Instruction::NUMBER>{};

liblangutil/EVMVersion.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ bool EVMVersion::hasOpcode(Instruction _opcode) const
4949
return hasSelfBalance();
5050
case Instruction::BASEFEE:
5151
return hasBaseFee();
52+
case Instruction::BLOBHASH:
53+
return hasBlobHash();
5254
case Instruction::BLOBBASEFEE:
5355
return hasBlobBaseFee();
5456
default:

liblangutil/EVMVersion.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class EVMVersion:
104104
bool hasBlobBaseFee() const { return *this >= cancun(); }
105105
bool hasPrevRandao() const { return *this >= paris(); }
106106
bool hasPush0() const { return *this >= shanghai(); }
107+
bool hasBlobHash() const { return *this >= cancun(); }
107108

108109
bool hasOpcode(evmasm::Instruction _opcode) const;
109110

libyul/AsmAnalysis.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,7 @@ void AsmAnalyzer::expectType(YulString _expectedType, YulString _givenType, Sour
670670

671671
bool AsmAnalyzer::validateInstructions(std::string const& _instructionIdentifier, langutil::SourceLocation const& _location)
672672
{
673+
// NOTE: This function uses the default EVM version instead of the currently selected one.
673674
auto const builtin = EVMDialect::strictAssemblyForEVM(EVMVersion{}).builtin(YulString(_instructionIdentifier));
674675
if (builtin && builtin->instruction.has_value())
675676
return validateInstructions(builtin->instruction.value(), _location);
@@ -705,6 +706,16 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio
705706
);
706707
};
707708

709+
// The errors below are meant to be issued when processing an undeclared identifier matching a builtin name
710+
// present on the default EVM version but not on the currently selected one,
711+
// since the other `validateInstructions()` overload uses the default EVM version.
712+
if (_instr == evmasm::Instruction::BLOBHASH)
713+
{
714+
// TODO: Upgrade this assertion to an error, similar to the ones above, when Cancun becomes the default EVM version.
715+
yulAssert(m_evmVersion.hasBlobHash(), "only available for Cancun-compatible");
716+
return true;
717+
}
718+
708719
if (_instr == evmasm::Instruction::RETURNDATACOPY && !m_evmVersion.supportsReturndata())
709720
errorForVM(7756_error, "only available for Byzantium-compatible");
710721
else if (_instr == evmasm::Instruction::RETURNDATASIZE && !m_evmVersion.supportsReturndata())

0 commit comments

Comments
 (0)