Merge pull request #6473 from ethereum/libeventhash-6435

Fix external ABI type name for contracts
This commit is contained in:
chriseth
2019-04-18 12:53:34 +02:00
committed by GitHub
5 changed files with 115 additions and 24 deletions
+35 -23
View File
@@ -148,6 +148,21 @@ bool fitsIntoBits(bigint const& _value, unsigned _bits, bool _signed)
));
}
Result<TypePointers> transformParametersToExternal(TypePointers const& _parameters, bool _inLibrary)
{
TypePointers transformed;
for (auto const& type: _parameters)
{
if (TypePointer ext = type->interfaceType(_inLibrary).get())
transformed.push_back(ext);
else
return Result<TypePointers>::err("Parameter should have external type.");
}
return transformed;
}
}
void Type::clearCache() const
@@ -2840,27 +2855,22 @@ FunctionTypePointer FunctionType::interfaceFunctionType() const
{
// Note that m_declaration might also be a state variable!
solAssert(m_declaration, "Declaration needed to determine interface function type.");
bool isLibraryFunction = dynamic_cast<ContractDefinition const&>(*m_declaration->scope()).isLibrary();
bool isLibraryFunction = kind() != Kind::Event && dynamic_cast<ContractDefinition const&>(*m_declaration->scope()).isLibrary();
TypePointers paramTypes;
TypePointers retParamTypes;
Result<TypePointers> paramTypes =
transformParametersToExternal(m_parameterTypes, isLibraryFunction);
if (!paramTypes.message().empty())
return FunctionTypePointer();
Result<TypePointers> retParamTypes =
transformParametersToExternal(m_returnParameterTypes, isLibraryFunction);
if (!retParamTypes.message().empty())
return FunctionTypePointer();
for (auto type: m_parameterTypes)
{
if (auto ext = type->interfaceType(isLibraryFunction).get())
paramTypes.push_back(ext);
else
return FunctionTypePointer();
}
for (auto type: m_returnParameterTypes)
{
if (auto ext = type->interfaceType(isLibraryFunction).get())
retParamTypes.push_back(ext);
else
return FunctionTypePointer();
}
auto variable = dynamic_cast<VariableDeclaration const*>(m_declaration);
if (variable && retParamTypes.empty())
if (variable && retParamTypes.get().empty())
return FunctionTypePointer();
return TypeProvider::function(
@@ -3075,13 +3085,15 @@ string FunctionType::externalSignature() const
// "inLibrary" is only relevant if this is not an event.
bool const inLibrary = kind() != Kind::Event && dynamic_cast<ContractDefinition const&>(*m_declaration->scope()).isLibrary();
FunctionTypePointer external = interfaceFunctionType();
solAssert(!!external, "External function type requested.");
auto parameterTypes = external->parameterTypes();
auto typeStrings = parameterTypes | boost::adaptors::transformed([&](TypePointer _t) -> string
auto extParams = transformParametersToExternal(m_parameterTypes, inLibrary);
solAssert(extParams.message().empty(), extParams.message());
auto typeStrings = extParams.get() | boost::adaptors::transformed([&](TypePointer _t) -> string
{
solAssert(_t, "Parameter should have external type.");
string typeName = _t->signatureInExternalFunction(inLibrary);
if (inLibrary && _t->dataStoredIn(DataLocation::Storage))
typeName += " storage";
return typeName;