I just want to extend the answer about theoretical memory size (32-byte address, 2^256 bytes because it's byte-addressable). In reality, if you look at the entire blockchain, it has several limits:
- it's bounded by the implementation of the client.
- it's bounded by the block gas limit.
For 1.
, the official Go Ethereum implementation uses Uint64 for memory size, so the memory size is bounded by 2^64
bytes: Go Ethereum Mstore implementation
For 2.
, it's the real limit that you will hit much sooner before the 1.
comes, and it's blockchain-dependent and function-type dependent.
For example, the Ethereum blockchain now has ~30M gas (Jan 2023). In practice, the transaction can only spend less than that. So with the approximate equation (X/32)^2/512 + 3X/32 = 30M
you found X is approximately a bit higher 0x3C0000
. It's the real limit for the current Ethereum blockchain. For BSC, it's higher (~140M Block gas limit).
Function to test gas limit :
contract Test{
function test()public {
assembly {
mstore(0x40, 0x3C0000)
}
// The above mstore doesn't cost much gas but it affects the subsequent mstore and mem alloc (the free mem pointer)
string memory dummy = "test";
// MSTORE for dummy will extend mem and spend nearly 30M gas.
}
}
Another concern is the view
function when using eth_call
directly, as far as I know there is no official upper limit gas spent by eth_call
and hence your function may hit the client gas limit in 1.
. Unofficially the client or RPC provider will have their own limit on that (e.g. 550M on alchemy). Different clients may have different implementations on this.