Merge pull request #6187 from ethereum/filter-library-abi-3409

Exclude internal functions in library ABIs
This commit is contained in:
chriseth 2019-03-11 17:39:51 +01:00 committed by GitHub
commit 8445449c7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 28 deletions

View File

@ -16,6 +16,7 @@ Compiler Features:
Bugfixes: 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. * 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 * 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. * 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 arrays in function signatures.
* Soltest: Add support for struct arrays in function signatures. * Soltest: Add support for struct arrays in function signatures.
### 0.5.5 (2019-03-05) ### 0.5.5 (2019-03-05)
Language Features: Language Features:

View File

@ -26,12 +26,31 @@ using namespace std;
using namespace dev; using namespace dev;
using namespace dev::solidity; 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::generate(ContractDefinition const& _contractDef)
{ {
Json::Value abi(Json::arrayValue); Json::Value abi(Json::arrayValue);
for (auto it: _contractDef.interfaceFunctions()) 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(); auto externalFunctionType = it.second->interfaceFunctionType();
solAssert(!!externalFunctionType, ""); solAssert(!!externalFunctionType, "");
Json::Value method; Json::Value method;

View File

@ -755,24 +755,23 @@ BOOST_AUTO_TEST_CASE(library_function)
library test { library test {
struct StructType { uint a; } 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 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"( char const* interface = R"(
[ [
{ {
"constant" : false, "constant" : true,
"payable" : false, "payable" : false,
"stateMutability": "nonpayable", "stateMutability": "pure",
"name": "f", "name": "f1",
"inputs": [ "inputs": [
{ "name": "b", "type": "test.StructType storage" }, { "name": "c", "type": "uint256[]" },
{ "name": "c", "type": "uint256[] storage" },
{ "name": "d", "type": "test" } { "name": "d", "type": "test" }
], ],
"outputs": [ "outputs": [
{ "name": "e", "type": "uint256[]" }, { "name": "e", "type": "uint256[]" }
{ "name": "f", "type": "test.StructType storage" }
], ],
"type" : "function" "type" : "function"
} }
@ -1040,13 +1039,13 @@ BOOST_AUTO_TEST_CASE(structs_in_libraries)
library L { library L {
struct S { uint a; T[] sub; bytes b; } struct S { uint a; T[] sub; bytes b; }
struct T { uint[2] x; } struct T { uint[2] x; }
function f(L.S storage s) public {} function f(L.S storage s) public view {}
function g(L.S memory s) public {} function g(L.S memory s) public view {}
} }
)"; )";
char const* interface = R"( char const* interface = R"(
[{ [{
"constant": false, "constant": true,
"inputs": [ "inputs": [
{ {
"components": [ "components": [
@ -1076,24 +1075,9 @@ BOOST_AUTO_TEST_CASE(structs_in_libraries)
"name": "g", "name": "g",
"outputs": [], "outputs": [],
"payable": false, "payable": false,
"stateMutability": "nonpayable", "stateMutability": "view",
"type": "function" "type": "function"
}, }])";
{
"constant": false,
"inputs": [
{
"name": "s",
"type": "L.S storage"
}
],
"name": "f",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}]
)";
checkInterface(sourceCode, "L", interface); checkInterface(sourceCode, "L", interface);
} }