mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Split ABI out of InterfaceHandler
This commit is contained in:
parent
4bf3cbb09a
commit
12328b7848
116
libsolidity/interface/ABI.cpp
Normal file
116
libsolidity/interface/ABI.cpp
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
This file is part of solidity.
|
||||||
|
|
||||||
|
solidity is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
solidity is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Utilities to handle the Contract ABI (https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libsolidity/interface/ABI.h>
|
||||||
|
#include <boost/range/irange.hpp>
|
||||||
|
#include <libsolidity/ast/AST.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace dev;
|
||||||
|
using namespace dev::solidity;
|
||||||
|
|
||||||
|
Json::Value ABI::generate(ContractDefinition const& _contractDef)
|
||||||
|
{
|
||||||
|
Json::Value abi(Json::arrayValue);
|
||||||
|
|
||||||
|
for (auto it: _contractDef.interfaceFunctions())
|
||||||
|
{
|
||||||
|
auto externalFunctionType = it.second->interfaceFunctionType();
|
||||||
|
Json::Value method;
|
||||||
|
method["type"] = "function";
|
||||||
|
method["name"] = it.second->declaration().name();
|
||||||
|
method["constant"] = it.second->isConstant();
|
||||||
|
method["payable"] = it.second->isPayable();
|
||||||
|
method["inputs"] = formatTypeList(
|
||||||
|
externalFunctionType->parameterNames(),
|
||||||
|
externalFunctionType->parameterTypes(),
|
||||||
|
_contractDef.isLibrary()
|
||||||
|
);
|
||||||
|
method["outputs"] = formatTypeList(
|
||||||
|
externalFunctionType->returnParameterNames(),
|
||||||
|
externalFunctionType->returnParameterTypes(),
|
||||||
|
_contractDef.isLibrary()
|
||||||
|
);
|
||||||
|
abi.append(method);
|
||||||
|
}
|
||||||
|
if (_contractDef.constructor())
|
||||||
|
{
|
||||||
|
Json::Value method;
|
||||||
|
method["type"] = "constructor";
|
||||||
|
auto externalFunction = FunctionType(*_contractDef.constructor(), false).interfaceFunctionType();
|
||||||
|
solAssert(!!externalFunction, "");
|
||||||
|
method["payable"] = externalFunction->isPayable();
|
||||||
|
method["inputs"] = formatTypeList(
|
||||||
|
externalFunction->parameterNames(),
|
||||||
|
externalFunction->parameterTypes(),
|
||||||
|
_contractDef.isLibrary()
|
||||||
|
);
|
||||||
|
abi.append(method);
|
||||||
|
}
|
||||||
|
if (_contractDef.fallbackFunction())
|
||||||
|
{
|
||||||
|
auto externalFunctionType = FunctionType(*_contractDef.fallbackFunction(), false).interfaceFunctionType();
|
||||||
|
solAssert(!!externalFunctionType, "");
|
||||||
|
Json::Value method;
|
||||||
|
method["type"] = "fallback";
|
||||||
|
method["payable"] = externalFunctionType->isPayable();
|
||||||
|
abi.append(method);
|
||||||
|
}
|
||||||
|
for (auto const& it: _contractDef.interfaceEvents())
|
||||||
|
{
|
||||||
|
Json::Value event;
|
||||||
|
event["type"] = "event";
|
||||||
|
event["name"] = it->name();
|
||||||
|
event["anonymous"] = it->isAnonymous();
|
||||||
|
Json::Value params(Json::arrayValue);
|
||||||
|
for (auto const& p: it->parameters())
|
||||||
|
{
|
||||||
|
solAssert(!!p->annotation().type->interfaceType(false), "");
|
||||||
|
Json::Value input;
|
||||||
|
input["name"] = p->name();
|
||||||
|
input["type"] = p->annotation().type->interfaceType(false)->canonicalName(false);
|
||||||
|
input["indexed"] = p->isIndexed();
|
||||||
|
params.append(input);
|
||||||
|
}
|
||||||
|
event["inputs"] = params;
|
||||||
|
abi.append(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return abi;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value ABI::formatTypeList(
|
||||||
|
vector<string> const& _names,
|
||||||
|
vector<TypePointer> const& _types,
|
||||||
|
bool _forLibrary
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Json::Value params(Json::arrayValue);
|
||||||
|
solAssert(_names.size() == _types.size(), "Names and types vector size does not match");
|
||||||
|
for (unsigned i = 0; i < _names.size(); ++i)
|
||||||
|
{
|
||||||
|
solAssert(_types[i], "");
|
||||||
|
Json::Value param;
|
||||||
|
param["name"] = _names[i];
|
||||||
|
param["type"] = _types[i]->canonicalName(_forLibrary);
|
||||||
|
params.append(param);
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
56
libsolidity/interface/ABI.h
Normal file
56
libsolidity/interface/ABI.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
This file is part of solidity.
|
||||||
|
|
||||||
|
solidity is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
solidity is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Utilities to handle the Contract ABI (https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <json/json.h>
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
namespace solidity
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
class ContractDefinition;
|
||||||
|
class Type;
|
||||||
|
using TypePointer = std::shared_ptr<Type const>;
|
||||||
|
|
||||||
|
class ABI
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Get the ABI Interface of the contract
|
||||||
|
/// @param _contractDef The contract definition
|
||||||
|
/// @return A JSONrepresentation of the contract's ABI Interface
|
||||||
|
static Json::Value generate(ContractDefinition const& _contractDef);
|
||||||
|
private:
|
||||||
|
/// @returns a json value suitable for a list of types in function input or output
|
||||||
|
/// parameters or other places. If @a _forLibrary is true, complex types are referenced
|
||||||
|
/// by name, otherwise they are anonymously expanded.
|
||||||
|
static Json::Value formatTypeList(
|
||||||
|
std::vector<std::string> const& _names,
|
||||||
|
std::vector<TypePointer> const& _types,
|
||||||
|
bool _forLibrary
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -37,6 +37,7 @@
|
|||||||
#include <libsolidity/analysis/PostTypeChecker.h>
|
#include <libsolidity/analysis/PostTypeChecker.h>
|
||||||
#include <libsolidity/analysis/SyntaxChecker.h>
|
#include <libsolidity/analysis/SyntaxChecker.h>
|
||||||
#include <libsolidity/codegen/Compiler.h>
|
#include <libsolidity/codegen/Compiler.h>
|
||||||
|
#include <libsolidity/interface/ABI.h>
|
||||||
#include <libsolidity/interface/InterfaceHandler.h>
|
#include <libsolidity/interface/InterfaceHandler.h>
|
||||||
#include <libsolidity/interface/GasEstimator.h>
|
#include <libsolidity/interface/GasEstimator.h>
|
||||||
#include <libsolidity/formal/Why3Translator.h>
|
#include <libsolidity/formal/Why3Translator.h>
|
||||||
@ -446,12 +447,21 @@ map<string, unsigned> CompilerStack::sourceIndices() const
|
|||||||
|
|
||||||
Json::Value const& CompilerStack::contractABI(string const& _contractName) const
|
Json::Value const& CompilerStack::contractABI(string const& _contractName) const
|
||||||
{
|
{
|
||||||
return metadata(_contractName, DocumentationType::ABIInterface);
|
return contractABI(contract(_contractName));
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::Value const& CompilerStack::contractABI(Contract const& _contract) const
|
Json::Value const& CompilerStack::contractABI(Contract const& _contract) const
|
||||||
{
|
{
|
||||||
return metadata(_contract, DocumentationType::ABIInterface);
|
if (m_stackState < AnalysisSuccessful)
|
||||||
|
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
|
||||||
|
|
||||||
|
solAssert(_contract.contract, "");
|
||||||
|
|
||||||
|
// caches the result
|
||||||
|
if (!_contract.abi)
|
||||||
|
_contract.abi.reset(new Json::Value(ABI::generate(*_contract.contract)));
|
||||||
|
|
||||||
|
return *_contract.abi;
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::Value const& CompilerStack::metadata(string const& _contractName, DocumentationType _type) const
|
Json::Value const& CompilerStack::metadata(string const& _contractName, DocumentationType _type) const
|
||||||
@ -476,9 +486,6 @@ Json::Value const& CompilerStack::metadata(Contract const& _contract, Documentat
|
|||||||
case DocumentationType::NatspecDev:
|
case DocumentationType::NatspecDev:
|
||||||
doc = &_contract.devDocumentation;
|
doc = &_contract.devDocumentation;
|
||||||
break;
|
break;
|
||||||
case DocumentationType::ABIInterface:
|
|
||||||
doc = &_contract.interface;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Illegal documentation type."));
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Illegal documentation type."));
|
||||||
}
|
}
|
||||||
|
@ -66,8 +66,7 @@ class DeclarationContainer;
|
|||||||
enum class DocumentationType: uint8_t
|
enum class DocumentationType: uint8_t
|
||||||
{
|
{
|
||||||
NatspecUser = 1,
|
NatspecUser = 1,
|
||||||
NatspecDev,
|
NatspecDev
|
||||||
ABIInterface
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -230,7 +229,7 @@ private:
|
|||||||
eth::LinkerObject runtimeObject;
|
eth::LinkerObject runtimeObject;
|
||||||
eth::LinkerObject cloneObject;
|
eth::LinkerObject cloneObject;
|
||||||
std::string onChainMetadata; ///< The metadata json that will be hashed into the chain.
|
std::string onChainMetadata; ///< The metadata json that will be hashed into the chain.
|
||||||
mutable std::unique_ptr<Json::Value const> interface;
|
mutable std::unique_ptr<Json::Value const> abi;
|
||||||
mutable std::unique_ptr<Json::Value const> userDocumentation;
|
mutable std::unique_ptr<Json::Value const> userDocumentation;
|
||||||
mutable std::unique_ptr<Json::Value const> devDocumentation;
|
mutable std::unique_ptr<Json::Value const> devDocumentation;
|
||||||
mutable std::unique_ptr<std::string const> sourceMapping;
|
mutable std::unique_ptr<std::string const> sourceMapping;
|
||||||
@ -267,6 +266,7 @@ private:
|
|||||||
|
|
||||||
std::string createOnChainMetadata(Contract const& _contract) const;
|
std::string createOnChainMetadata(Contract const& _contract) const;
|
||||||
std::string computeSourceMapping(eth::AssemblyItems const& _items) const;
|
std::string computeSourceMapping(eth::AssemblyItems const& _items) const;
|
||||||
|
Json::Value const& contractABI(Contract const&) const;
|
||||||
Json::Value const& metadata(Contract const&, DocumentationType _type) const;
|
Json::Value const& metadata(Contract const&, DocumentationType _type) const;
|
||||||
|
|
||||||
struct Remapping
|
struct Remapping
|
||||||
|
@ -1,3 +1,27 @@
|
|||||||
|
/*
|
||||||
|
This file is part of solidity.
|
||||||
|
|
||||||
|
solidity is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
solidity is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @author Lefteris <lefteris@ethdev.com>
|
||||||
|
* @date 2014
|
||||||
|
* Takes the parsed AST and produces the Natspec documentation:
|
||||||
|
* https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format
|
||||||
|
*
|
||||||
|
* Can generally deal with JSON files
|
||||||
|
*/
|
||||||
|
|
||||||
#include <libsolidity/interface/InterfaceHandler.h>
|
#include <libsolidity/interface/InterfaceHandler.h>
|
||||||
#include <boost/range/irange.hpp>
|
#include <boost/range/irange.hpp>
|
||||||
@ -19,83 +43,11 @@ Json::Value InterfaceHandler::documentation(
|
|||||||
return userDocumentation(_contractDef);
|
return userDocumentation(_contractDef);
|
||||||
case DocumentationType::NatspecDev:
|
case DocumentationType::NatspecDev:
|
||||||
return devDocumentation(_contractDef);
|
return devDocumentation(_contractDef);
|
||||||
case DocumentationType::ABIInterface:
|
|
||||||
return abiInterface(_contractDef);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown documentation type"));
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown documentation type"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::Value InterfaceHandler::abiInterface(ContractDefinition const& _contractDef)
|
|
||||||
{
|
|
||||||
Json::Value abi(Json::arrayValue);
|
|
||||||
|
|
||||||
for (auto it: _contractDef.interfaceFunctions())
|
|
||||||
{
|
|
||||||
auto externalFunctionType = it.second->interfaceFunctionType();
|
|
||||||
Json::Value method;
|
|
||||||
method["type"] = "function";
|
|
||||||
method["name"] = it.second->declaration().name();
|
|
||||||
method["constant"] = it.second->isConstant();
|
|
||||||
method["payable"] = it.second->isPayable();
|
|
||||||
method["inputs"] = formatTypeList(
|
|
||||||
externalFunctionType->parameterNames(),
|
|
||||||
externalFunctionType->parameterTypes(),
|
|
||||||
_contractDef.isLibrary()
|
|
||||||
);
|
|
||||||
method["outputs"] = formatTypeList(
|
|
||||||
externalFunctionType->returnParameterNames(),
|
|
||||||
externalFunctionType->returnParameterTypes(),
|
|
||||||
_contractDef.isLibrary()
|
|
||||||
);
|
|
||||||
abi.append(method);
|
|
||||||
}
|
|
||||||
if (_contractDef.constructor())
|
|
||||||
{
|
|
||||||
Json::Value method;
|
|
||||||
method["type"] = "constructor";
|
|
||||||
auto externalFunction = FunctionType(*_contractDef.constructor(), false).interfaceFunctionType();
|
|
||||||
solAssert(!!externalFunction, "");
|
|
||||||
method["payable"] = externalFunction->isPayable();
|
|
||||||
method["inputs"] = formatTypeList(
|
|
||||||
externalFunction->parameterNames(),
|
|
||||||
externalFunction->parameterTypes(),
|
|
||||||
_contractDef.isLibrary()
|
|
||||||
);
|
|
||||||
abi.append(method);
|
|
||||||
}
|
|
||||||
if (_contractDef.fallbackFunction())
|
|
||||||
{
|
|
||||||
auto externalFunctionType = FunctionType(*_contractDef.fallbackFunction(), false).interfaceFunctionType();
|
|
||||||
solAssert(!!externalFunctionType, "");
|
|
||||||
Json::Value method;
|
|
||||||
method["type"] = "fallback";
|
|
||||||
method["payable"] = externalFunctionType->isPayable();
|
|
||||||
abi.append(method);
|
|
||||||
}
|
|
||||||
for (auto const& it: _contractDef.interfaceEvents())
|
|
||||||
{
|
|
||||||
Json::Value event;
|
|
||||||
event["type"] = "event";
|
|
||||||
event["name"] = it->name();
|
|
||||||
event["anonymous"] = it->isAnonymous();
|
|
||||||
Json::Value params(Json::arrayValue);
|
|
||||||
for (auto const& p: it->parameters())
|
|
||||||
{
|
|
||||||
solAssert(!!p->annotation().type->interfaceType(false), "");
|
|
||||||
Json::Value input;
|
|
||||||
input["name"] = p->name();
|
|
||||||
input["type"] = p->annotation().type->interfaceType(false)->canonicalName(false);
|
|
||||||
input["indexed"] = p->isIndexed();
|
|
||||||
params.append(input);
|
|
||||||
}
|
|
||||||
event["inputs"] = params;
|
|
||||||
abi.append(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
return abi;
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value InterfaceHandler::userDocumentation(ContractDefinition const& _contractDef)
|
Json::Value InterfaceHandler::userDocumentation(ContractDefinition const& _contractDef)
|
||||||
{
|
{
|
||||||
Json::Value doc;
|
Json::Value doc;
|
||||||
@ -168,25 +120,6 @@ Json::Value InterfaceHandler::devDocumentation(ContractDefinition const& _contra
|
|||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::Value InterfaceHandler::formatTypeList(
|
|
||||||
vector<string> const& _names,
|
|
||||||
vector<TypePointer> const& _types,
|
|
||||||
bool _forLibrary
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Json::Value params(Json::arrayValue);
|
|
||||||
solAssert(_names.size() == _types.size(), "Names and types vector size does not match");
|
|
||||||
for (unsigned i = 0; i < _names.size(); ++i)
|
|
||||||
{
|
|
||||||
solAssert(_types[i], "");
|
|
||||||
Json::Value param;
|
|
||||||
param["name"] = _names[i];
|
|
||||||
param["type"] = _types[i]->canonicalName(_forLibrary);
|
|
||||||
params.append(param);
|
|
||||||
}
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
string InterfaceHandler::extractDoc(multimap<string, DocTag> const& _tags, string const& _name)
|
string InterfaceHandler::extractDoc(multimap<string, DocTag> const& _tags, string const& _name)
|
||||||
{
|
{
|
||||||
string value;
|
string value;
|
||||||
|
@ -17,8 +17,7 @@
|
|||||||
/**
|
/**
|
||||||
* @author Lefteris <lefteris@ethdev.com>
|
* @author Lefteris <lefteris@ethdev.com>
|
||||||
* @date 2014
|
* @date 2014
|
||||||
* Takes the parsed AST and produces the Natspec
|
* Takes the parsed AST and produces the Natspec documentation:
|
||||||
* documentation and the ABI interface
|
|
||||||
* https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format
|
* https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format
|
||||||
*
|
*
|
||||||
* Can generally deal with JSON files
|
* Can generally deal with JSON files
|
||||||
@ -71,10 +70,6 @@ public:
|
|||||||
ContractDefinition const& _contractDef,
|
ContractDefinition const& _contractDef,
|
||||||
DocumentationType _type
|
DocumentationType _type
|
||||||
);
|
);
|
||||||
/// Get the ABI Interface of the contract
|
|
||||||
/// @param _contractDef The contract definition
|
|
||||||
/// @return A JSONrepresentation of the contract's ABI Interface
|
|
||||||
static Json::Value abiInterface(ContractDefinition const& _contractDef);
|
|
||||||
/// Get the User documentation of the contract
|
/// Get the User documentation of the contract
|
||||||
/// @param _contractDef The contract definition
|
/// @param _contractDef The contract definition
|
||||||
/// @return A JSON representation of the contract's user documentation
|
/// @return A JSON representation of the contract's user documentation
|
||||||
|
Loading…
Reference in New Issue
Block a user