diff --git a/Changelog.md b/Changelog.md index d73e0083c..c14ac8534 100644 --- a/Changelog.md +++ b/Changelog.md @@ -16,6 +16,7 @@ Compiler Features: Bugfixes: + * JSON ABI: Json description of library ABIs no longer contain functions with internal types like storage structs. * SMTChecker: Fix internal compiler error when contract contains too large rational number. * Type system: Detect if a contract's base uses types that require the experimental abi encoder while the contract still uses the old encoder * Yul Optimizer: Fix visitation order bug for the structural simplifier. @@ -25,7 +26,6 @@ Build System: * Soltest: Add support for arrays in function signatures. * Soltest: Add support for struct arrays in function signatures. - ### 0.5.5 (2019-03-05) Language Features: diff --git a/libsolidity/interface/ABI.cpp b/libsolidity/interface/ABI.cpp index 3c33eae8e..f8a9c7ec8 100644 --- a/libsolidity/interface/ABI.cpp +++ b/libsolidity/interface/ABI.cpp @@ -26,12 +26,31 @@ using namespace std; using namespace dev; using namespace dev::solidity; +namespace +{ +bool anyDataStoredInStorage(TypePointers const& _pointers) +{ + for (TypePointer const& pointer: _pointers) + if (pointer->dataStoredIn(DataLocation::Storage)) + return true; + + return false; +} +} + Json::Value ABI::generate(ContractDefinition const& _contractDef) { Json::Value abi(Json::arrayValue); for (auto it: _contractDef.interfaceFunctions()) { + if ( + _contractDef.isLibrary() && + (it.second->stateMutability() > StateMutability::View || + anyDataStoredInStorage(it.second->parameterTypes() + it.second->returnParameterTypes())) + ) + continue; + auto externalFunctionType = it.second->interfaceFunctionType(); solAssert(!!externalFunctionType, ""); Json::Value method; diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp index 63f2b3a62..3acb56257 100644 --- a/test/libsolidity/SolidityABIJSON.cpp +++ b/test/libsolidity/SolidityABIJSON.cpp @@ -755,24 +755,23 @@ BOOST_AUTO_TEST_CASE(library_function) library test { struct StructType { uint a; } function f(StructType storage b, uint[] storage c, test d) public returns (uint[] memory e, StructType storage f) { f = f; } + function f1(uint[] memory c, test d) public pure returns (uint[] memory e) { } } )"; char const* interface = R"( [ { - "constant" : false, + "constant" : true, "payable" : false, - "stateMutability": "nonpayable", - "name": "f", + "stateMutability": "pure", + "name": "f1", "inputs": [ - { "name": "b", "type": "test.StructType storage" }, - { "name": "c", "type": "uint256[] storage" }, + { "name": "c", "type": "uint256[]" }, { "name": "d", "type": "test" } ], "outputs": [ - { "name": "e", "type": "uint256[]" }, - { "name": "f", "type": "test.StructType storage" } + { "name": "e", "type": "uint256[]" } ], "type" : "function" } @@ -1040,13 +1039,13 @@ BOOST_AUTO_TEST_CASE(structs_in_libraries) library L { struct S { uint a; T[] sub; bytes b; } struct T { uint[2] x; } - function f(L.S storage s) public {} - function g(L.S memory s) public {} + function f(L.S storage s) public view {} + function g(L.S memory s) public view {} } )"; char const* interface = R"( [{ - "constant": false, + "constant": true, "inputs": [ { "components": [ @@ -1076,24 +1075,9 @@ BOOST_AUTO_TEST_CASE(structs_in_libraries) "name": "g", "outputs": [], "payable": false, - "stateMutability": "nonpayable", + "stateMutability": "view", "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "s", - "type": "L.S storage" - } - ], - "name": "f", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }] - )"; + }])"; checkInterface(sourceCode, "L", interface); }