From 22b47689d5d3db76310a7fc8dd44113f3bbd9b44 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 13 Mar 2015 17:36:00 +0100 Subject: [PATCH 1/2] Adding msg.sig Solidity Magic type msg.sig will return a bytes4 with the function signature located in CALLDATALOAD --- libsolidity/ExpressionCompiler.cpp | 2 ++ libsolidity/Types.cpp | 3 ++- test/SolidityEndToEndTest.cpp | 13 +++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 3cee40df1..07f4e94ea 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -646,6 +646,8 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) m_context << eth::Instruction::GASPRICE; else if (member == "data") m_context << u256(0) << eth::Instruction::CALLDATASIZE; + else if (member == "sig") + m_context << u256(0) << eth::Instruction::CALLDATALOAD << (u256(0xffffffff) << (256 - 32))<< eth::Instruction::AND; else BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown magic member.")); break; diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index bd55e2a8b..70cbec5d9 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -1160,7 +1160,8 @@ MagicType::MagicType(MagicType::Kind _kind): m_members = MemberList({{"sender", make_shared(0, IntegerType::Modifier::Address)}, {"gas", make_shared(256)}, {"value", make_shared(256)}, - {"data", make_shared(ArrayType::Location::CallData)}}); + {"data", make_shared(ArrayType::Location::CallData)}, + {"sig", make_shared(4)}}); break; case Kind::Transaction: m_members = MemberList({{"origin", make_shared(0, IntegerType::Modifier::Address)}, diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 2f965849b..c61833452 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -1031,6 +1031,19 @@ BOOST_AUTO_TEST_CASE(blockchain) BOOST_CHECK(callContractFunctionWithValue("someInfo()", 28) == encodeArgs(28, 0, 1)); } +BOOST_AUTO_TEST_CASE(msg_sig) +{ + char const* sourceCode = R"( + contract test { + function foo(uint256 a) returns (bytes4 value) { + return msg.sig; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunctionWithValue("foo(uint256)", 13) == encodeArgs(asString(FixedHash<4>(dev::sha3("foo(uint256)")).asBytes()))); +} + BOOST_AUTO_TEST_CASE(now) { char const* sourceCode = "contract test {\n" From 382a5878861e25b95283dbb9c29f9d8d10d662ed Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 16 Mar 2015 15:46:04 +0100 Subject: [PATCH 2/2] Additional test for msg.sig --- libsolidity/ExpressionCompiler.cpp | 3 ++- test/SolidityEndToEndTest.cpp | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 07f4e94ea..a9cacc65c 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -647,7 +647,8 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) else if (member == "data") m_context << u256(0) << eth::Instruction::CALLDATASIZE; else if (member == "sig") - m_context << u256(0) << eth::Instruction::CALLDATALOAD << (u256(0xffffffff) << (256 - 32))<< eth::Instruction::AND; + m_context << u256(0) << eth::Instruction::CALLDATALOAD + << (u256(0xffffffff) << (256 - 32)) << eth::Instruction::AND; else BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown magic member.")); break; diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index c61833452..c440b4e3d 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -1044,6 +1044,22 @@ BOOST_AUTO_TEST_CASE(msg_sig) BOOST_CHECK(callContractFunctionWithValue("foo(uint256)", 13) == encodeArgs(asString(FixedHash<4>(dev::sha3("foo(uint256)")).asBytes()))); } +BOOST_AUTO_TEST_CASE(msg_sig_after_internal_call_is_same) +{ + char const* sourceCode = R"( + contract test { + function boo() returns (bytes4 value) { + return msg.sig; + } + function foo(uint256 a) returns (bytes4 value) { + return boo(); + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunctionWithValue("foo(uint256)", 13) == encodeArgs(asString(FixedHash<4>(dev::sha3("foo(uint256)")).asBytes()))); +} + BOOST_AUTO_TEST_CASE(now) { char const* sourceCode = "contract test {\n"