mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Remove low-level log functions.
This commit is contained in:
parent
c20beaf2c9
commit
bfc8e26007
@ -3,6 +3,7 @@
|
||||
Breaking Changes:
|
||||
* Assembler: The artificial ASSIGNIMMUTABLE opcode and the corresponding builtin in the "EVM with object access" dialect of Yul take the base offset of the code to modify as additional argument.
|
||||
* Code Generator: All arithmetic is checked by default. These checks can be disabled using ``unchecked { ... }``.
|
||||
* General: Remove global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4``.
|
||||
* Type System: Unary negation can only be used on signed integers, not on unsigned integers.
|
||||
* Type System: Disallow explicit conversions from negative literals and literals larger than ``type(uint160).max`` to ``address`` type.
|
||||
* Parser: Exponentiation is right associative. ``a**b**c`` is parsed as ``a**(b**c)``.
|
||||
|
@ -17,3 +17,10 @@ and it does something else afterwards.
|
||||
* Explicit conversions from negative literals and literals larger than ``type(uint160).max`` to ``address`` are now disallowed.
|
||||
* Exponentiation is right associative, i.e., the expression ``a**b**c`` is parsed as ``a**(b**c)``.
|
||||
Before 0.8.0, it was parsed as ``(a**b)**c``.
|
||||
|
||||
Syntactic Only Changes
|
||||
======================
|
||||
|
||||
* The global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4`` have been removed.
|
||||
|
||||
These are low-level functions that were largely unused. Their behaviour can be accessed from inline assembly.
|
@ -126,37 +126,6 @@ The output of the above looks like the following (trimmed):
|
||||
}
|
||||
}
|
||||
|
||||
.. index:: ! log
|
||||
|
||||
Low-Level Interface to Logs
|
||||
===========================
|
||||
|
||||
It is also possible to access the low-level interface to the logging
|
||||
mechanism via the functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4``.
|
||||
Each function ``logi`` takes ``i + 1`` parameter of type ``bytes32``, where the first
|
||||
argument will be used for the data part of the log and the others
|
||||
as topics. The event call above can be performed in the same way as
|
||||
|
||||
::
|
||||
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.4.10 <0.9.0;
|
||||
|
||||
contract C {
|
||||
function f() public payable {
|
||||
uint256 _id = 0x420042;
|
||||
log3(
|
||||
bytes32(msg.value),
|
||||
bytes32(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20),
|
||||
bytes32(uint256(msg.sender)),
|
||||
bytes32(_id)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
where the long hexadecimal number is equal to
|
||||
``keccak256("Deposit(address,bytes32,uint256)")``, the signature of the event.
|
||||
|
||||
Additional Resources for Understanding Events
|
||||
==============================================
|
||||
|
||||
|
@ -45,11 +45,6 @@ int magicVariableToID(std::string const& _name)
|
||||
else if (_name == "ecrecover") return -6;
|
||||
else if (_name == "gasleft") return -7;
|
||||
else if (_name == "keccak256") return -8;
|
||||
else if (_name == "log0") return -10;
|
||||
else if (_name == "log1") return -11;
|
||||
else if (_name == "log2") return -12;
|
||||
else if (_name == "log3") return -13;
|
||||
else if (_name == "log4") return -14;
|
||||
else if (_name == "msg") return -15;
|
||||
else if (_name == "mulmod") return -16;
|
||||
else if (_name == "now") return -17;
|
||||
@ -83,11 +78,6 @@ inline vector<shared_ptr<MagicVariableDeclaration const>> constructMagicVariable
|
||||
magicVarDecl("ecrecover", TypeProvider::function(strings{"bytes32", "uint8", "bytes32", "bytes32"}, strings{"address"}, FunctionType::Kind::ECRecover, false, StateMutability::Pure)),
|
||||
magicVarDecl("gasleft", TypeProvider::function(strings(), strings{"uint256"}, FunctionType::Kind::GasLeft, false, StateMutability::View)),
|
||||
magicVarDecl("keccak256", TypeProvider::function(strings{"bytes memory"}, strings{"bytes32"}, FunctionType::Kind::KECCAK256, false, StateMutability::Pure)),
|
||||
magicVarDecl("log0", TypeProvider::function(strings{"bytes32"}, strings{}, FunctionType::Kind::Log0)),
|
||||
magicVarDecl("log1", TypeProvider::function(strings{"bytes32", "bytes32"}, strings{}, FunctionType::Kind::Log1)),
|
||||
magicVarDecl("log2", TypeProvider::function(strings{"bytes32", "bytes32", "bytes32"}, strings{}, FunctionType::Kind::Log2)),
|
||||
magicVarDecl("log3", TypeProvider::function(strings{"bytes32", "bytes32", "bytes32", "bytes32"}, strings{}, FunctionType::Kind::Log3)),
|
||||
magicVarDecl("log4", TypeProvider::function(strings{"bytes32", "bytes32", "bytes32", "bytes32", "bytes32"}, strings{}, FunctionType::Kind::Log4)),
|
||||
magicVarDecl("msg", TypeProvider::magic(MagicType::Kind::Message)),
|
||||
magicVarDecl("mulmod", TypeProvider::function(strings{"uint256", "uint256", "uint256"}, strings{"uint256"}, FunctionType::Kind::MulMod, false, StateMutability::Pure)),
|
||||
magicVarDecl("now", TypeProvider::uint256()),
|
||||
|
@ -3044,11 +3044,6 @@ string FunctionType::richIdentifier() const
|
||||
case Kind::ECRecover: id += "ecrecover"; break;
|
||||
case Kind::SHA256: id += "sha256"; break;
|
||||
case Kind::RIPEMD160: id += "ripemd160"; break;
|
||||
case Kind::Log0: id += "log0"; break;
|
||||
case Kind::Log1: id += "log1"; break;
|
||||
case Kind::Log2: id += "log2"; break;
|
||||
case Kind::Log3: id += "log3"; break;
|
||||
case Kind::Log4: id += "log4"; break;
|
||||
case Kind::GasLeft: id += "gasleft"; break;
|
||||
case Kind::Event: id += "event"; break;
|
||||
case Kind::SetGas: id += "setgas"; break;
|
||||
|
@ -1138,11 +1138,6 @@ public:
|
||||
ECRecover, ///< CALL to special contract for ecrecover
|
||||
SHA256, ///< CALL to special contract for sha256
|
||||
RIPEMD160, ///< CALL to special contract for ripemd160
|
||||
Log0,
|
||||
Log1,
|
||||
Log2,
|
||||
Log3,
|
||||
Log4,
|
||||
Event, ///< syntactic sugar for LOG*
|
||||
SetGas, ///< modify the default gas value for the function call
|
||||
SetValue, ///< modify the default value transfer for the function call
|
||||
|
@ -851,26 +851,6 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::Log0:
|
||||
case FunctionType::Kind::Log1:
|
||||
case FunctionType::Kind::Log2:
|
||||
case FunctionType::Kind::Log3:
|
||||
case FunctionType::Kind::Log4:
|
||||
{
|
||||
unsigned logNumber = static_cast<unsigned>(function.kind()) - static_cast<unsigned>(FunctionType::Kind::Log0);
|
||||
for (unsigned arg = logNumber; arg > 0; --arg)
|
||||
acceptAndConvert(*arguments[arg], *function.parameterTypes()[arg], true);
|
||||
arguments.front()->accept(*this);
|
||||
utils().fetchFreeMemoryPointer();
|
||||
solAssert(function.parameterTypes().front()->isValueType(), "");
|
||||
utils().packedEncode(
|
||||
{arguments.front()->annotation().type},
|
||||
{function.parameterTypes().front()}
|
||||
);
|
||||
utils().toSizeAfterFreeMemoryPointer();
|
||||
m_context << logInstruction(logNumber);
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::Event:
|
||||
{
|
||||
_functionCall.expression().accept(*this);
|
||||
@ -1415,11 +1395,6 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
|
||||
case FunctionType::Kind::BareDelegateCall:
|
||||
case FunctionType::Kind::BareStaticCall:
|
||||
case FunctionType::Kind::Transfer:
|
||||
case FunctionType::Kind::Log0:
|
||||
case FunctionType::Kind::Log1:
|
||||
case FunctionType::Kind::Log2:
|
||||
case FunctionType::Kind::Log3:
|
||||
case FunctionType::Kind::Log4:
|
||||
case FunctionType::Kind::ECRecover:
|
||||
case FunctionType::Kind::SHA256:
|
||||
case FunctionType::Kind::RIPEMD160:
|
||||
|
@ -1329,34 +1329,6 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
|
||||
define(_functionCall) << functions[functionType->kind()] << "(" << args << ")\n";
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::Log0:
|
||||
case FunctionType::Kind::Log1:
|
||||
case FunctionType::Kind::Log2:
|
||||
case FunctionType::Kind::Log3:
|
||||
case FunctionType::Kind::Log4:
|
||||
{
|
||||
unsigned logNumber = static_cast<unsigned>(functionType->kind()) - static_cast<unsigned>(FunctionType::Kind::Log0);
|
||||
solAssert(arguments.size() == logNumber + 1, "");
|
||||
ABIFunctions abi(m_context.evmVersion(), m_context.revertStrings(), m_context.functionCollector());
|
||||
string indexedArgs;
|
||||
for (unsigned arg = 0; arg < logNumber; ++arg)
|
||||
indexedArgs += ", " + expressionAsType(*arguments[arg + 1], *(parameterTypes[arg + 1]));
|
||||
Whiskers templ(R"({
|
||||
let <pos> := <freeMemory>
|
||||
let <end> := <encode>(<pos>, <nonIndexedArgs>)
|
||||
<log>(<pos>, sub(<end>, <pos>) <indexedArgs>)
|
||||
})");
|
||||
templ("pos", m_context.newYulVariable());
|
||||
templ("end", m_context.newYulVariable());
|
||||
templ("freeMemory", freeMemory());
|
||||
templ("encode", abi.tupleEncoder({arguments.front()->annotation().type}, {parameterTypes.front()}));
|
||||
templ("nonIndexedArgs", IRVariable(*arguments.front()).commaSeparatedList());
|
||||
templ("log", "log" + to_string(logNumber));
|
||||
templ("indexedArgs", indexedArgs);
|
||||
m_code << templ.render();
|
||||
|
||||
break;
|
||||
}
|
||||
case FunctionType::Kind::Creation:
|
||||
{
|
||||
solAssert(!functionType->gasSet(), "Gas limit set for contract creation.");
|
||||
@ -1854,11 +1826,6 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess)
|
||||
case FunctionType::Kind::BareDelegateCall:
|
||||
case FunctionType::Kind::BareStaticCall:
|
||||
case FunctionType::Kind::Transfer:
|
||||
case FunctionType::Kind::Log0:
|
||||
case FunctionType::Kind::Log1:
|
||||
case FunctionType::Kind::Log2:
|
||||
case FunctionType::Kind::Log3:
|
||||
case FunctionType::Kind::Log4:
|
||||
case FunctionType::Kind::ECRecover:
|
||||
case FunctionType::Kind::SHA256:
|
||||
case FunctionType::Kind::RIPEMD160:
|
||||
|
@ -662,13 +662,8 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall)
|
||||
case FunctionType::Kind::ArrayPop:
|
||||
arrayPop(_funCall);
|
||||
break;
|
||||
case FunctionType::Kind::Log0:
|
||||
case FunctionType::Kind::Log1:
|
||||
case FunctionType::Kind::Log2:
|
||||
case FunctionType::Kind::Log3:
|
||||
case FunctionType::Kind::Log4:
|
||||
case FunctionType::Kind::Event:
|
||||
// These can be safely ignored.
|
||||
// This can be safely ignored.
|
||||
break;
|
||||
case FunctionType::Kind::ObjectCreation:
|
||||
visitObjectCreation(_funCall);
|
||||
|
@ -1177,139 +1177,6 @@ BOOST_AUTO_TEST_CASE(uncalled_blockhash)
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(log0)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function a() public {
|
||||
log0(bytes32(uint256(1)));
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
|
||||
BOOST_CHECK_EQUAL(numLogTopics(0), 0);
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(log1)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function a() public {
|
||||
log1(bytes32(uint256(1)), bytes32(uint256(2)));
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), h256(u256(2)));
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(log2)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function a() public {
|
||||
log2(bytes32(uint256(1)), bytes32(uint256(2)), bytes32(uint256(3)));
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 2);
|
||||
for (unsigned i = 0; i < 2; ++i)
|
||||
BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2)));
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(log3)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function a() public {
|
||||
log3(bytes32(uint256(1)), bytes32(uint256(2)), bytes32(uint256(3)), bytes32(uint256(4)));
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 3);
|
||||
for (unsigned i = 0; i < 3; ++i)
|
||||
BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2)));
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(log4)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function a() public {
|
||||
log4(bytes32(uint256(1)), bytes32(uint256(2)), bytes32(uint256(3)), bytes32(uint256(4)), bytes32(uint256(5)));
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 4);
|
||||
for (unsigned i = 0; i < 4; ++i)
|
||||
BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2)));
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(log_in_constructor)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
constructor() {
|
||||
log1(bytes32(uint256(1)), bytes32(uint256(2)));
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), h256(u256(2)));
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(selfdestruct)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@ -1883,7 +1750,12 @@ BOOST_AUTO_TEST_CASE(event)
|
||||
function deposit(bytes32 _id, bool _manually) public payable {
|
||||
if (_manually) {
|
||||
bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;
|
||||
log3(bytes32(msg.value), s, bytes32(uint256(msg.sender)), _id);
|
||||
uint value = msg.value;
|
||||
address sender = msg.sender;
|
||||
assembly {
|
||||
mstore(0, value)
|
||||
log3(0, 0x20, s, sender, _id)
|
||||
}
|
||||
} else {
|
||||
emit Deposit(msg.sender, _id, msg.value);
|
||||
}
|
||||
@ -1937,6 +1809,31 @@ BOOST_AUTO_TEST_CASE(event_emit)
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_constructor)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract ClientReceipt {
|
||||
event Deposit(address indexed _from, bytes32 indexed _id, uint _value);
|
||||
constructor() {
|
||||
emit Deposit(msg.sender, bytes32("abc"), 7);
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(7)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 3);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), util::keccak256(string("Deposit(address,bytes32,uint256)")));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 1), h256(m_sender, h256::AlignRight));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 2), h256(string{"abc"}, h256::FromBinary, h256::AlignLeft));
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_no_arguments)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
|
@ -1,40 +0,0 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract C {
|
||||
function f() external {
|
||||
bytes32 t1 = bytes32(uint256(0x1234));
|
||||
log0(t1);
|
||||
log1(t1, t1);
|
||||
log2(t1, t1, t1);
|
||||
log3(t1, t1, t1, t1);
|
||||
log4(t1, t1, t1, t1, t1);
|
||||
}
|
||||
function g_data() pure internal returns (bytes32) {
|
||||
assert(true);
|
||||
return bytes32(uint256(0x5678));
|
||||
}
|
||||
function g() external {
|
||||
// To test that the function call is actually visited.
|
||||
log0(g_data());
|
||||
log1(g_data(), g_data());
|
||||
log2(g_data(), g_data(), g_data());
|
||||
log3(g_data(), g_data(), g_data(), g_data());
|
||||
log4(g_data(), g_data(), g_data(), g_data(), g_data());
|
||||
}
|
||||
bool x = true;
|
||||
function h_data() view internal returns (bytes32) {
|
||||
assert(x);
|
||||
}
|
||||
function h() external {
|
||||
// To test that the function call is actually visited.
|
||||
x = false;
|
||||
log0(h_data());
|
||||
log1(h_data(), h_data());
|
||||
log2(h_data(), h_data(), h_data());
|
||||
log3(h_data(), h_data(), h_data(), h_data());
|
||||
log4(h_data(), h_data(), h_data(), h_data(), h_data());
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 6321: (655-662): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.
|
||||
// Warning 6328: (668-677): CHC: Assertion violation happens here.
|
@ -0,0 +1,15 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
log0;
|
||||
log1;
|
||||
log2;
|
||||
log3;
|
||||
log4;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 7576: (38-42): Undeclared identifier.
|
||||
// DeclarationError 7576: (46-50): Undeclared identifier.
|
||||
// DeclarationError 7576: (54-58): Undeclared identifier.
|
||||
// DeclarationError 7576: (62-66): Undeclared identifier.
|
||||
// DeclarationError 7576: (70-74): Undeclared identifier.
|
@ -6,4 +6,4 @@ contract c {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 7576: (101-105): Undeclared identifier. Did you mean "log8", "log9", "log0", "log1", "log2", "log3" or "log4"?
|
||||
// DeclarationError 7576: (101-105): Undeclared identifier. Did you mean "log8" or "log9"?
|
||||
|
@ -12,6 +12,6 @@ contract c {
|
||||
// DeclarationError 7576: (52-53): Undeclared identifier.
|
||||
// DeclarationError 7576: (56-60): Undeclared identifier. Did you mean "long"?
|
||||
// DeclarationError 7576: (70-71): Undeclared identifier.
|
||||
// DeclarationError 7576: (74-78): Undeclared identifier. Did you mean "long", "log0", "log1", "log2", "log3" or "log4"?
|
||||
// DeclarationError 7576: (74-78): Undeclared identifier. Did you mean "long"?
|
||||
// DeclarationError 7576: (88-89): Undeclared identifier.
|
||||
// DeclarationError 7576: (92-96): Undeclared identifier. Did you mean "long"?
|
||||
|
@ -1,13 +1,13 @@
|
||||
contract C {
|
||||
function f() public pure {
|
||||
(bool a,) = address(this).call(abi.encode(address(this).delegatecall, super));
|
||||
(a,) = address(this).delegatecall(abi.encode(log0, tx, mulmod));
|
||||
(a,) = address(this).delegatecall(abi.encode(block, tx, mulmod));
|
||||
a;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 2056: (94-120): This type cannot be encoded.
|
||||
// TypeError 2056: (122-127): This type cannot be encoded.
|
||||
// TypeError 2056: (184-188): This type cannot be encoded.
|
||||
// TypeError 2056: (190-192): This type cannot be encoded.
|
||||
// TypeError 2056: (194-200): This type cannot be encoded.
|
||||
// TypeError 2056: (184-189): This type cannot be encoded.
|
||||
// TypeError 2056: (191-193): This type cannot be encoded.
|
||||
// TypeError 2056: (195-201): This type cannot be encoded.
|
||||
|
Loading…
Reference in New Issue
Block a user