mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix external ABI type name for contracts
This commit is contained in:
parent
9861145ca8
commit
5251099b14
@ -2,6 +2,7 @@
|
||||
|
||||
Important Bugfixes:
|
||||
* Code Generator: Fix initialization routine of uninitialized internal function pointers in constructor context.
|
||||
* Type System: Use correct type name for contracts in event parameters when used in libraries. This affected code generation.
|
||||
|
||||
Bugfixes:
|
||||
* General: Split rule list such that JavaScript environments with small stacks can use the compiler.
|
||||
|
||||
@ -121,6 +121,21 @@ bool fitsPrecisionBase2(bigint const& _mantissa, uint32_t _expBase2)
|
||||
return fitsPrecisionBaseX(_mantissa, 1.0, _expBase2);
|
||||
}
|
||||
|
||||
boost::optional<TypePointers> transformParametersToExternal(TypePointers const& _parameters, bool _inLibrary)
|
||||
{
|
||||
TypePointers transformed;
|
||||
|
||||
for (auto const& type: _parameters)
|
||||
{
|
||||
if (TypePointer ext = type->interfaceType(_inLibrary))
|
||||
transformed.push_back(ext);
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
return transformed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void StorageOffsets::computeOffsets(TypePointers const& _types)
|
||||
@ -2669,32 +2684,27 @@ 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;
|
||||
boost::optional<TypePointers> paramTypes =
|
||||
transformParametersToExternal(m_parameterTypes, isLibraryFunction);
|
||||
|
||||
if (!paramTypes)
|
||||
return FunctionTypePointer();
|
||||
|
||||
boost::optional<TypePointers> retParamTypes =
|
||||
transformParametersToExternal(m_returnParameterTypes, isLibraryFunction);
|
||||
|
||||
if (!retParamTypes)
|
||||
return FunctionTypePointer();
|
||||
|
||||
for (auto type: m_parameterTypes)
|
||||
{
|
||||
if (auto ext = type->interfaceType(isLibraryFunction))
|
||||
paramTypes.push_back(ext);
|
||||
else
|
||||
return FunctionTypePointer();
|
||||
}
|
||||
for (auto type: m_returnParameterTypes)
|
||||
{
|
||||
if (auto ext = type->interfaceType(isLibraryFunction))
|
||||
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 make_shared<FunctionType>(
|
||||
paramTypes,
|
||||
retParamTypes,
|
||||
*paramTypes,
|
||||
*retParamTypes,
|
||||
m_parameterNames,
|
||||
m_returnParameterNames,
|
||||
m_kind,
|
||||
@ -2834,14 +2844,16 @@ string FunctionType::externalSignature() const
|
||||
solAssert(m_declaration != nullptr, "External signature of function needs declaration");
|
||||
solAssert(!m_declaration->name().empty(), "Fallback function has no signature.");
|
||||
|
||||
bool const inLibrary = 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
|
||||
bool const inLibrary = kind() != Kind::Event && dynamic_cast<ContractDefinition const&>(*m_declaration->scope()).isLibrary();
|
||||
|
||||
boost::optional<TypePointers> extParams = transformParametersToExternal(m_parameterTypes, inLibrary);
|
||||
|
||||
solAssert(extParams, "");
|
||||
|
||||
auto typeStrings = *extParams | 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;
|
||||
|
||||
@ -12413,6 +12413,34 @@ BOOST_AUTO_TEST_CASE(senders_balance)
|
||||
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(27)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_wrong_abi_name)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
library ClientReceipt {
|
||||
event Deposit(Test indexed _from, bytes32 indexed _id, uint _value);
|
||||
function deposit(bytes32 _id) public {
|
||||
Test a;
|
||||
emit Deposit(a, _id, msg.value);
|
||||
}
|
||||
}
|
||||
contract Test {
|
||||
function f() public {
|
||||
ClientReceipt.deposit("123");
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "ClientReceipt", bytes());
|
||||
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{"ClientReceipt", m_contractAddress}});
|
||||
u256 value(18);
|
||||
u256 id(0x1234);
|
||||
|
||||
callContractFunction("f()");
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 3);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address,bytes32,uint256)")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user