Merge pull request #7358 from aarlt/abstract_contracts

Abstract contracts
This commit is contained in:
chriseth 2019-11-04 13:24:30 +01:00 committed by GitHub
commit 60ec679156
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
127 changed files with 452 additions and 69 deletions

View File

@ -10,6 +10,7 @@ Breaking changes:
* General: New reserved keywords: ``virtual``. * General: New reserved keywords: ``virtual``.
* Standard JSON Interface: Add option to disable or choose hash method between IPFS and Swarm for the bytecode metadata. * Standard JSON Interface: Add option to disable or choose hash method between IPFS and Swarm for the bytecode metadata.
* Syntax: ``push(element)`` for dynamic storage arrays do not return the new length anymore. * Syntax: ``push(element)`` for dynamic storage arrays do not return the new length anymore.
* Syntax: Abstract contracts need to be marked explicitly as abstract by using the ``abstract`` keyword.
* Inline Assembly: Only strict inline assembly is allowed. * Inline Assembly: Only strict inline assembly is allowed.
* Type checker: Resulting type of exponentiation is equal to the type of the base. Also allow signed types for the base. * Type checker: Resulting type of exponentiation is equal to the type of the base. Also allow signed types for the base.
* Language Feature: When overriding a function or modifier, the new keyword ``override`` must be used. When overriding a function or modifier defined in multiple parallel bases, all bases must be listed in parentheses after the keyword like so: ``override(Base1, Base2)`` * Language Feature: When overriding a function or modifier, the new keyword ``override`` must be used. When overriding a function or modifier defined in multiple parallel bases, all bases must be listed in parentheses after the keyword like so: ``override(Base1, Base2)``

View File

@ -529,7 +529,7 @@ As an example, the code
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
contract Test { abstract contract Test {
struct S { uint a; uint[] b; T[] c; } struct S { uint a; uint[] b; T[] c; }
struct T { uint x; uint y; } struct T { uint x; uint y; }
function f(S memory s, T memory t, uint a) public; function f(S memory s, T memory t, uint a) public;

View File

@ -6,19 +6,24 @@
Abstract Contracts Abstract Contracts
****************** ******************
Contracts are marked as abstract when at least one of their functions lacks an implementation as in the following example (note that the function declaration header is terminated by ``;``):: Contracts need to be marked as abstract when at least one of their functions was not implemented.
You can also mark contracts as abstract even though all functions are implemented.
This can be done by using the ``abstract`` keyword as shown in the following example. Note, that this contract need to be
defined as abstract, because the function ``utterance()`` was defined, but no implementation was
provided (no implementation body ``{ }`` was given).::
pragma solidity >=0.4.0 <0.7.0; pragma solidity >=0.4.0 <0.7.0;
contract Feline { abstract contract Feline {
function utterance() public returns (bytes32); function utterance() public returns (bytes32);
} }
Such contracts cannot be compiled (even if they contain implemented functions alongside non-implemented functions), but they can be used as base contracts:: Such abstract contracts can not be instantiated directly. This is also true, if an abstract contract itself does implement
all defined functions. The usage of an abstract contract as a base class is shown in the following example::
pragma solidity >=0.4.0 <0.7.0; pragma solidity >=0.4.0 <0.7.0;
contract Feline { abstract contract Feline {
function utterance() public returns (bytes32); function utterance() public returns (bytes32);
} }
@ -26,7 +31,7 @@ Such contracts cannot be compiled (even if they contain implemented functions al
function utterance() public override returns (bytes32) { return "miaow"; } function utterance() public override returns (bytes32) { return "miaow"; }
} }
If a contract inherits from an abstract contract and does not implement all non-implemented functions by overriding, it will itself be abstract. If a contract inherits from an abstract contract and does not implement all non-implemented functions by overriding, it needs to be marked as abstract as well.
Note that a function without implementation is different from a :ref:`Function Type <function_types>` even though their syntax looks very similar. Note that a function without implementation is different from a :ref:`Function Type <function_types>` even though their syntax looks very similar.

View File

@ -52,12 +52,12 @@ Details are given in the following example.
// interface known to the compiler. Note the function // interface known to the compiler. Note the function
// without body. If a contract does not implement all // without body. If a contract does not implement all
// functions it can only be used as an interface. // functions it can only be used as an interface.
contract Config { abstract contract Config {
function lookup(uint id) public returns (address adr); function lookup(uint id) public returns (address adr);
} }
contract NameReg { abstract contract NameReg {
function register(bytes32 name) public; function register(bytes32 name) public;
function unregister() public; function unregister() public;
} }

View File

@ -7,7 +7,7 @@ ImportDirective = 'import' StringLiteral ('as' Identifier)? ';'
| 'import' ('*' | Identifier) ('as' Identifier)? 'from' StringLiteral ';' | 'import' ('*' | Identifier) ('as' Identifier)? 'from' StringLiteral ';'
| 'import' '{' Identifier ('as' Identifier)? ( ',' Identifier ('as' Identifier)? )* '}' 'from' StringLiteral ';' | 'import' '{' Identifier ('as' Identifier)? ( ',' Identifier ('as' Identifier)? )* '}' 'from' StringLiteral ';'
ContractDefinition = ( 'contract' | 'library' | 'interface' ) Identifier ContractDefinition = 'abstract'? ( 'contract' | 'library' | 'interface' ) Identifier
( 'is' InheritanceSpecifier (',' InheritanceSpecifier )* )? ( 'is' InheritanceSpecifier (',' InheritanceSpecifier )* )?
'{' ContractPart* '}' '{' ContractPart* '}'

View File

@ -91,7 +91,7 @@ Yes::
pragma solidity >=0.4.0 <0.7.0; pragma solidity >=0.4.0 <0.7.0;
contract A { abstract contract A {
function spam() public pure; function spam() public pure;
function ham() public pure; function ham() public pure;
} }

View File

@ -391,6 +391,19 @@ void ContractLevelChecker::checkAbstractFunctions(ContractDefinition const& _con
_contract.annotation().unimplementedFunctions.push_back(function); _contract.annotation().unimplementedFunctions.push_back(function);
break; break;
} }
if (_contract.abstract() && _contract.contractKind() != ContractDefinition::ContractKind::Contract)
m_errorReporter.typeError(_contract.location(), "Only contracts can be abstract.");
if (
_contract.contractKind() == ContractDefinition::ContractKind::Contract &&
!_contract.annotation().unimplementedFunctions.empty() &&
!_contract.abstract()
)
m_errorReporter.typeError(
_contract.location(),
"Contract \"" + _contract.annotation().canonicalName + "\" should be marked as abstract."
);
} }

View File

@ -88,7 +88,6 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
for (auto const& n: _contract.subNodes()) for (auto const& n: _contract.subNodes())
n->accept(*this); n->accept(*this);
return false; return false;
} }
@ -2152,21 +2151,10 @@ void TypeChecker::endVisit(NewExpression const& _newExpression)
m_errorReporter.fatalTypeError(_newExpression.location(), "Identifier is not a contract."); m_errorReporter.fatalTypeError(_newExpression.location(), "Identifier is not a contract.");
if (contract->isInterface()) if (contract->isInterface())
m_errorReporter.fatalTypeError(_newExpression.location(), "Cannot instantiate an interface."); m_errorReporter.fatalTypeError(_newExpression.location(), "Cannot instantiate an interface.");
if (!contract->annotation().unimplementedFunctions.empty())
{
SecondarySourceLocation ssl;
for (auto function: contract->annotation().unimplementedFunctions)
ssl.append("Missing implementation:", function->location());
string msg = "Trying to create an instance of an abstract contract.";
ssl.limitSize(msg);
m_errorReporter.typeError(
_newExpression.location(),
ssl,
msg
);
}
if (!contract->constructorIsPublic()) if (!contract->constructorIsPublic())
m_errorReporter.typeError(_newExpression.location(), "Contract with internal constructor cannot be created directly."); m_errorReporter.typeError(_newExpression.location(), "Contract with internal constructor cannot be created directly.");
if (contract->abstract() || !contract->annotation().unimplementedFunctions.empty())
m_errorReporter.typeError(_newExpression.location(), "Cannot instantiate an abstract contract.");
solAssert(!!m_scope, ""); solAssert(!!m_scope, "");
m_scope->annotation().contractDependencies.insert(contract); m_scope->annotation().contractDependencies.insert(contract);

View File

@ -151,7 +151,7 @@ bool ContractDefinition::constructorIsPublic() const
bool ContractDefinition::canBeDeployed() const bool ContractDefinition::canBeDeployed() const
{ {
return constructorIsPublic() && annotation().unimplementedFunctions.empty(); return constructorIsPublic() && annotation().unimplementedFunctions.empty() && !abstract();
} }
FunctionDefinition const* ContractDefinition::fallbackFunction() const FunctionDefinition const* ContractDefinition::fallbackFunction() const

View File

@ -388,13 +388,15 @@ public:
ASTPointer<ASTString> const& _documentation, ASTPointer<ASTString> const& _documentation,
std::vector<ASTPointer<InheritanceSpecifier>> const& _baseContracts, std::vector<ASTPointer<InheritanceSpecifier>> const& _baseContracts,
std::vector<ASTPointer<ASTNode>> const& _subNodes, std::vector<ASTPointer<ASTNode>> const& _subNodes,
ContractKind _contractKind = ContractKind::Contract ContractKind _contractKind = ContractKind::Contract,
bool _abstract = false
): ):
Declaration(_location, _name), Declaration(_location, _name),
Documented(_documentation), Documented(_documentation),
m_baseContracts(_baseContracts), m_baseContracts(_baseContracts),
m_subNodes(_subNodes), m_subNodes(_subNodes),
m_contractKind(_contractKind) m_contractKind(_contractKind),
m_abstract(_abstract)
{} {}
void accept(ASTVisitor& _visitor) override; void accept(ASTVisitor& _visitor) override;
@ -441,10 +443,13 @@ public:
ContractKind contractKind() const { return m_contractKind; } ContractKind contractKind() const { return m_contractKind; }
bool abstract() const { return m_abstract; }
private: private:
std::vector<ASTPointer<InheritanceSpecifier>> m_baseContracts; std::vector<ASTPointer<InheritanceSpecifier>> m_baseContracts;
std::vector<ASTPointer<ASTNode>> m_subNodes; std::vector<ASTPointer<ASTNode>> m_subNodes;
ContractKind m_contractKind; ContractKind m_contractKind;
bool m_abstract{false};
mutable std::unique_ptr<std::vector<std::pair<FixedHash<4>, FunctionTypePointer>>> m_interfaceFunctionList; mutable std::unique_ptr<std::vector<std::pair<FixedHash<4>, FunctionTypePointer>>> m_interfaceFunctionList;
mutable std::unique_ptr<std::vector<EventDefinition const*>> m_interfaceEvents; mutable std::unique_ptr<std::vector<EventDefinition const*>> m_interfaceEvents;

View File

@ -260,6 +260,7 @@ bool ASTJsonConverter::visit(ContractDefinition const& _node)
make_pair("name", _node.name()), make_pair("name", _node.name()),
make_pair("documentation", _node.documentation() ? Json::Value(*_node.documentation()) : Json::nullValue), make_pair("documentation", _node.documentation() ? Json::Value(*_node.documentation()) : Json::nullValue),
make_pair("contractKind", contractKind(_node.contractKind())), make_pair("contractKind", contractKind(_node.contractKind())),
make_pair("abstract", _node.abstract()),
make_pair("fullyImplemented", _node.annotation().unimplementedFunctions.empty()), make_pair("fullyImplemented", _node.annotation().unimplementedFunctions.empty()),
make_pair("linearizedBaseContracts", getContainerIds(_node.annotation().linearizedBaseContracts)), make_pair("linearizedBaseContracts", getContainerIds(_node.annotation().linearizedBaseContracts)),
make_pair("baseContracts", toJson(_node.baseContracts())), make_pair("baseContracts", toJson(_node.baseContracts())),

View File

@ -91,6 +91,7 @@ ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
case Token::Import: case Token::Import:
nodes.push_back(parseImportDirective()); nodes.push_back(parseImportDirective());
break; break;
case Token::Abstract:
case Token::Interface: case Token::Interface:
case Token::Contract: case Token::Contract:
case Token::Library: case Token::Library:
@ -244,9 +245,15 @@ ASTPointer<ImportDirective> Parser::parseImportDirective()
return nodeFactory.createNode<ImportDirective>(path, unitAlias, move(symbolAliases)); return nodeFactory.createNode<ImportDirective>(path, unitAlias, move(symbolAliases));
} }
ContractDefinition::ContractKind Parser::parseContractKind() std::pair<ContractDefinition::ContractKind, bool> Parser::parseContractKind()
{ {
ContractDefinition::ContractKind kind; ContractDefinition::ContractKind kind;
bool abstract = false;
if (m_scanner->currentToken() == Token::Abstract)
{
abstract = true;
m_scanner->next();
}
switch(m_scanner->currentToken()) switch(m_scanner->currentToken())
{ {
case Token::Interface: case Token::Interface:
@ -262,7 +269,7 @@ ContractDefinition::ContractKind Parser::parseContractKind()
solAssert(false, "Invalid contract kind."); solAssert(false, "Invalid contract kind.");
} }
m_scanner->next(); m_scanner->next();
return kind; return std::make_pair(kind, abstract);
} }
ASTPointer<ContractDefinition> Parser::parseContractDefinition() ASTPointer<ContractDefinition> Parser::parseContractDefinition()
@ -273,7 +280,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
ASTPointer<ASTString> docString; ASTPointer<ASTString> docString;
vector<ASTPointer<InheritanceSpecifier>> baseContracts; vector<ASTPointer<InheritanceSpecifier>> baseContracts;
vector<ASTPointer<ASTNode>> subNodes; vector<ASTPointer<ASTNode>> subNodes;
ContractDefinition::ContractKind contractKind = ContractDefinition::ContractKind::Contract; std::pair<ContractDefinition::ContractKind, bool> contractKind{};
try try
{ {
if (m_scanner->currentCommentLiteral() != "") if (m_scanner->currentCommentLiteral() != "")
@ -343,7 +350,8 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
docString, docString,
baseContracts, baseContracts,
subNodes, subNodes,
contractKind contractKind.first,
contractKind.second
); );
} }

View File

@ -85,7 +85,9 @@ private:
void parsePragmaVersion(langutil::SourceLocation const& _location, std::vector<Token> const& _tokens, std::vector<std::string> const& _literals); void parsePragmaVersion(langutil::SourceLocation const& _location, std::vector<Token> const& _tokens, std::vector<std::string> const& _literals);
ASTPointer<PragmaDirective> parsePragmaDirective(); ASTPointer<PragmaDirective> parsePragmaDirective();
ASTPointer<ImportDirective> parseImportDirective(); ASTPointer<ImportDirective> parseImportDirective();
ContractDefinition::ContractKind parseContractKind(); /// @returns an std::pair<ContractDefinition::ContractKind, bool>, where
/// result.second is set to true, if an abstract contract was parsed, false otherwise.
std::pair<ContractDefinition::ContractKind, bool> parseContractKind();
ASTPointer<ContractDefinition> parseContractDefinition(); ASTPointer<ContractDefinition> parseContractDefinition();
ASTPointer<InheritanceSpecifier> parseInheritanceSpecifier(); ASTPointer<InheritanceSpecifier> parseInheritanceSpecifier();
Declaration::Visibility parseVisibilitySpecifier(); Declaration::Visibility parseVisibilitySpecifier();

View File

@ -34,6 +34,7 @@ JSON AST:
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -4,4 +4,4 @@ pragma solidity >=0.0; contract Errort6 { using foo for ; /* missing type name
","message":"Expected type name","severity":"error","sourceLocation":{"end":58,"file":"A","start":57},"type":"ParserError"},{"component":"general","formattedMessage":"A:1:84: Warning: Recovered in ContractDefinition at '}'. ","message":"Expected type name","severity":"error","sourceLocation":{"end":58,"file":"A","start":57},"type":"ParserError"},{"component":"general","formattedMessage":"A:1:84: Warning: Recovered in ContractDefinition at '}'.
pragma solidity >=0.0; contract Errort6 { using foo for ; /* missing type name */ } pragma solidity >=0.0; contract Errort6 { using foo for ; /* missing type name */ }
^ ^
","message":"Recovered in ContractDefinition at '}'.","severity":"warning","sourceLocation":{"end":84,"file":"A","start":83},"type":"Warning"}],"sources":{"A":{"ast":{"absolutePath":"A","exportedSymbols":{"Errort6":[3]},"id":4,"nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity",">=","0.0"],"nodeType":"PragmaDirective","src":"0:22:0"},{"baseContracts":[],"contractDependencies":[],"contractKind":"contract","documentation":null,"fullyImplemented":true,"id":3,"linearizedBaseContracts":[3],"name":"Errort6","nodeType":"ContractDefinition","nodes":[],"scope":4,"src":"23:35:0"}],"src":"0:84:0"},"id":0}}} ","message":"Recovered in ContractDefinition at '}'.","severity":"warning","sourceLocation":{"end":84,"file":"A","start":83},"type":"Warning"}],"sources":{"A":{"ast":{"absolutePath":"A","exportedSymbols":{"Errort6":[3]},"id":4,"nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity",">=","0.0"],"nodeType":"PragmaDirective","src":"0:22:0"},{"abstract":false,"baseContracts":[],"contractDependencies":[],"contractKind":"contract","documentation":null,"fullyImplemented":true,"id":3,"linearizedBaseContracts":[3],"name":"Errort6","nodeType":"ContractDefinition","nodes":[],"scope":4,"src":"23:35:0"}],"src":"0:84:0"},"id":0}}}

View File

@ -1 +1 @@
{"sources":{"A":{"ast":{"absolutePath":"A","exportedSymbols":{"C":[6]},"id":7,"nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity",">=","0.0"],"nodeType":"PragmaDirective","src":"0:22:0"},{"baseContracts":[],"contractDependencies":[],"contractKind":"contract","documentation":null,"fullyImplemented":true,"id":6,"linearizedBaseContracts":[6],"name":"C","nodeType":"ContractDefinition","nodes":[{"body":{"id":4,"nodeType":"Block","src":"61:2:0","statements":[]},"documentation":null,"id":5,"implemented":true,"kind":"function","modifiers":[],"name":"f","nodeType":"FunctionDefinition","overrides":null,"parameters":{"id":2,"nodeType":"ParameterList","parameters":[],"src":"46:2:0"},"returnParameters":{"id":3,"nodeType":"ParameterList","parameters":[],"src":"61:0:0"},"scope":6,"src":"36:27:0","stateMutability":"pure","superFunction":null,"visibility":"public"}],"scope":7,"src":"23:42:0"}],"src":"0:65:0"},"id":0}}} {"sources":{"A":{"ast":{"absolutePath":"A","exportedSymbols":{"C":[6]},"id":7,"nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity",">=","0.0"],"nodeType":"PragmaDirective","src":"0:22:0"},{"abstract":false,"baseContracts":[],"contractDependencies":[],"contractKind":"contract","documentation":null,"fullyImplemented":true,"id":6,"linearizedBaseContracts":[6],"name":"C","nodeType":"ContractDefinition","nodes":[{"body":{"id":4,"nodeType":"Block","src":"61:2:0","statements":[]},"documentation":null,"id":5,"implemented":true,"kind":"function","modifiers":[],"name":"f","nodeType":"FunctionDefinition","overrides":null,"parameters":{"id":2,"nodeType":"ParameterList","parameters":[],"src":"46:2:0"},"returnParameters":{"id":3,"nodeType":"ParameterList","parameters":[],"src":"61:0:0"},"scope":6,"src":"36:27:0","stateMutability":"pure","superFunction":null,"visibility":"public"}],"scope":7,"src":"23:42:0"}],"src":"0:65:0"},"id":0}}}

View File

@ -6,7 +6,7 @@ import "../Oracles/Oracle.sol";
/// @title Event contract - Provide basic functionality required by different event types /// @title Event contract - Provide basic functionality required by different event types
/// @author Stefan George - <stefan@gnosis.pm> /// @author Stefan George - <stefan@gnosis.pm>
contract Event { abstract contract Event {
/* /*
* Events * Events

View File

@ -3,7 +3,7 @@ import "../Markets/Market.sol";
/// @title Abstract market maker contract - Functions to be implemented by market maker contracts /// @title Abstract market maker contract - Functions to be implemented by market maker contracts
contract MarketMaker { abstract contract MarketMaker {
/* /*
* Public functions * Public functions

View File

@ -4,7 +4,7 @@ import "../MarketMakers/MarketMaker.sol";
/// @title Abstract market contract - Functions to be implemented by market contracts /// @title Abstract market contract - Functions to be implemented by market contracts
contract Market { abstract contract Market {
/* /*
* Events * Events

View File

@ -5,7 +5,7 @@ import "../Markets/Market.sol";
/// @title Abstract market factory contract - Functions to be implemented by market factories /// @title Abstract market factory contract - Functions to be implemented by market factories
contract MarketFactory { abstract contract MarketFactory {
/* /*
* Events * Events

View File

@ -2,7 +2,7 @@ pragma solidity >=0.0;
/// @title Abstract oracle contract - Functions to be implemented by oracles /// @title Abstract oracle contract - Functions to be implemented by oracles
contract Oracle { abstract contract Oracle {
function isOutcomeSet() public view returns (bool); function isOutcomeSet() public view returns (bool);
function getOutcome() public view returns (int); function getOutcome() public view returns (int);

View File

@ -3,7 +3,7 @@ pragma solidity >=0.0;
/// @title Abstract token contract - Functions to be implemented by token contracts /// @title Abstract token contract - Functions to be implemented by token contracts
contract Token { abstract contract Token {
/* /*
* Events * Events

View File

@ -45,12 +45,12 @@ namespace
static char const* registrarCode = R"DELIMITER( static char const* registrarCode = R"DELIMITER(
pragma solidity >=0.4.0 <0.7.0; pragma solidity >=0.4.0 <0.7.0;
contract NameRegister { abstract contract NameRegister {
function addr(string memory _name) public view returns (address o_owner); function addr(string memory _name) public view returns (address o_owner);
function name(address _owner) public view returns (string memory o_name); function name(address _owner) public view returns (string memory o_name);
} }
contract Registrar is NameRegister { abstract contract Registrar is NameRegister {
event Changed(string indexed name); event Changed(string indexed name);
event PrimaryChanged(string indexed name, address indexed addr); event PrimaryChanged(string indexed name, address indexed addr);
@ -62,7 +62,7 @@ contract Registrar is NameRegister {
function name(address _owner) public override view returns (string memory o_name); function name(address _owner) public override view returns (string memory o_name);
} }
contract AuctionSystem { abstract contract AuctionSystem {
event AuctionEnded(string indexed _name, address _winner); event AuctionEnded(string indexed _name, address _winner);
event NewBid(string indexed _name, address _bidder, uint _value); event NewBid(string indexed _name, address _bidder, uint _value);

View File

@ -55,7 +55,7 @@ static char const* registrarCode = R"DELIMITER(
pragma solidity >=0.4.0 <0.7.0; pragma solidity >=0.4.0 <0.7.0;
contract Registrar { abstract contract Registrar {
event Changed(string indexed name); event Changed(string indexed name);
function owner(string memory _name) public view returns (address o_owner); function owner(string memory _name) public view returns (address o_owner);

View File

@ -276,7 +276,7 @@ contract multiowned {
// inheritable "property" contract that enables methods to be protected by placing a linear limit (specifiable) // inheritable "property" contract that enables methods to be protected by placing a linear limit (specifiable)
// on a particular resource per calendar day. is multiowned to allow the limit to be altered. resource that method // on a particular resource per calendar day. is multiowned to allow the limit to be altered. resource that method
// uses is specified in the modifier. // uses is specified in the modifier.
contract daylimit is multiowned { abstract contract daylimit is multiowned {
// MODIFIERS // MODIFIERS
@ -330,7 +330,7 @@ contract daylimit is multiowned {
} }
// interface contract for multisig proxy contracts; see below for docs. // interface contract for multisig proxy contracts; see below for docs.
contract multisig { abstract contract multisig {
// EVENTS // EVENTS

View File

@ -24,7 +24,7 @@ to automate organizational governance and decision-making.
import "./TokenCreation.sol"; import "./TokenCreation.sol";
import "./ManagedAccount.sol"; import "./ManagedAccount.sol";
contract DAOInterface { abstract contract DAOInterface {
// The amount of days for which people who try to participate in the // The amount of days for which people who try to participate in the
// creation by calling the fallback function will still get their ether back // creation by calling the fallback function will still get their ether back

View File

@ -21,7 +21,7 @@ Basic account, used by the DAO contract to separately manage both the rewards
and the extraBalance accounts. and the extraBalance accounts.
*/ */
contract ManagedAccountInterface { abstract contract ManagedAccountInterface {
// The only address with permission to withdraw from this account // The only address with permission to withdraw from this account
address public owner; address public owner;
// If true, only the owner of the account can receive ether from it // If true, only the owner of the account can receive ether from it

View File

@ -30,7 +30,7 @@ https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs
/// @title Standard Token Contract. /// @title Standard Token Contract.
contract TokenInterface { abstract contract TokenInterface {
mapping (address => uint256) balances; mapping (address => uint256) balances;
mapping (address => mapping (address => uint256)) allowed; mapping (address => mapping (address => uint256)) allowed;
@ -85,7 +85,7 @@ contract TokenInterface {
); );
} }
contract tokenRecipient { abstract contract tokenRecipient {
function receiveApproval(address _from, uint256 _value, address _token, bytes memory _extraData) public; function receiveApproval(address _from, uint256 _value, address _token, bytes memory _extraData) public;
} }

View File

@ -25,7 +25,7 @@ along with the DAO. If not, see <http://www.gnu.org/licenses/>.
import "./Token.sol"; import "./Token.sol";
import "./ManagedAccount.sol"; import "./ManagedAccount.sol";
contract TokenCreationInterface { abstract contract TokenCreationInterface {
// End of token creation, in Unix time // End of token creation, in Unix time
uint public closingTime; uint public closingTime;

View File

@ -0,0 +1,72 @@
{
"absolutePath": "a",
"exportedSymbols":
{
"C":
[
5
]
},
"id": 6,
"nodeType": "SourceUnit",
"nodes":
[
{
"abstract": true,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": true,
"id": 5,
"linearizedBaseContracts":
[
5
],
"name": "C",
"nodeType": "ContractDefinition",
"nodes":
[
{
"body":
{
"id": 3,
"nodeType": "Block",
"src": "44:4:1",
"statements": []
},
"documentation": null,
"id": 4,
"implemented": true,
"kind": "constructor",
"modifiers": [],
"name": "",
"nodeType": "FunctionDefinition",
"overrides": null,
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "34:2:1"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "44:0:1"
},
"scope": 5,
"src": "23:25:1",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 6,
"src": "0:50:1"
}
],
"src": "0:51:1"
}

View File

@ -0,0 +1,6 @@
abstract contract C {
constructor() public {
}
}
// ----

View File

@ -0,0 +1,112 @@
{
"attributes":
{
"absolutePath": "a",
"exportedSymbols":
{
"C":
[
5
]
}
},
"children":
[
{
"attributes":
{
"abstract": true,
"baseContracts":
[
null
],
"contractDependencies":
[
null
],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": true,
"linearizedBaseContracts":
[
5
],
"name": "C",
"scope": 6
},
"children":
[
{
"attributes":
{
"documentation": null,
"implemented": true,
"isConstructor": true,
"kind": "constructor",
"modifiers":
[
null
],
"name": "",
"overrides": null,
"scope": 5,
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
},
"children":
[
{
"attributes":
{
"parameters":
[
null
]
},
"children": [],
"id": 1,
"name": "ParameterList",
"src": "34:2:1"
},
{
"attributes":
{
"parameters":
[
null
]
},
"children": [],
"id": 2,
"name": "ParameterList",
"src": "44:0:1"
},
{
"attributes":
{
"statements":
[
null
]
},
"children": [],
"id": 3,
"name": "Block",
"src": "44:4:1"
}
],
"id": 4,
"name": "FunctionDefinition",
"src": "23:25:1"
}
],
"id": 5,
"name": "ContractDefinition",
"src": "0:50:1"
}
],
"id": 6,
"name": "SourceUnit",
"src": "0:51:1"
}

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -28,6 +28,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",
@ -45,6 +46,7 @@
"src": "0:14:1" "src": "0:14:1"
}, },
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
{ {
@ -88,6 +90,7 @@
"src": "15:19:1" "src": "15:19:1"
}, },
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
{ {
@ -133,6 +136,7 @@
"src": "35:19:1" "src": "35:19:1"
}, },
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
{ {
@ -180,6 +184,7 @@
"src": "55:19:1" "src": "55:19:1"
}, },
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
{ {

View File

@ -31,6 +31,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null
@ -60,6 +61,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"contractDependencies": "contractDependencies":
[ [
1 1
@ -113,6 +115,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"contractDependencies": "contractDependencies":
[ [
1, 1,
@ -168,6 +171,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"contractDependencies": "contractDependencies":
[ [
1, 1,
@ -225,6 +229,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"contractDependencies": "contractDependencies":
[ [
1, 1,

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",
@ -45,6 +46,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",
@ -78,6 +80,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -16,6 +16,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",
@ -33,6 +34,7 @@
"src": "0:14:1" "src": "0:14:1"
}, },
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
{ {

View File

@ -19,6 +19,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null
@ -48,6 +49,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"contractDependencies": "contractDependencies":
[ [
1 1

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -20,6 +20,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",
@ -75,6 +76,7 @@
"src": "0:40:1" "src": "0:40:1"
}, },
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
{ {
@ -186,6 +188,7 @@
"src": "41:78:1" "src": "41:78:1"
}, },
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
{ {

View File

@ -23,6 +23,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null
@ -115,6 +116,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"contractDependencies": "contractDependencies":
[ [
5 5
@ -283,6 +285,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"contractDependencies": "contractDependencies":
[ [
5, 5,

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -12,6 +12,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -15,6 +15,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -16,6 +16,7 @@
"nodes": "nodes":
[ [
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "library", "contractKind": "library",
@ -33,6 +34,7 @@
"src": "0:12:1" "src": "0:12:1"
}, },
{ {
"abstract": false,
"baseContracts": [], "baseContracts": [],
"contractDependencies": [], "contractDependencies": [],
"contractKind": "contract", "contractKind": "contract",

View File

@ -19,6 +19,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null
@ -48,6 +49,7 @@
{ {
"attributes": "attributes":
{ {
"abstract": false,
"baseContracts": "baseContracts":
[ [
null null

View File

@ -5446,7 +5446,7 @@ BOOST_AUTO_TEST_CASE(pass_dynamic_arguments_to_the_base_base_with_gap)
} }
uint public m_i; uint public m_i;
} }
contract Base1 is Base { abstract contract Base1 is Base {
constructor(uint k) public {} constructor(uint k) public {}
} }
contract Derived is Base, Base1 { contract Derived is Base, Base1 {
@ -10483,7 +10483,7 @@ BOOST_AUTO_TEST_CASE(mutex)
BOOST_AUTO_TEST_CASE(calling_nonexisting_contract_throws) BOOST_AUTO_TEST_CASE(calling_nonexisting_contract_throws)
{ {
char const* sourceCode = R"YY( char const* sourceCode = R"YY(
contract D { function g() public; } abstract contract D { function g() public; }
contract C { contract C {
D d = D(0x1212); D d = D(0x1212);
function f() public returns (uint) { function f() public returns (uint) {

View File

@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(function_no_implementation)
{ {
SourceUnit const* sourceUnit = nullptr; SourceUnit const* sourceUnit = nullptr;
char const* text = R"( char const* text = R"(
contract test { abstract contract test {
function functionName(bytes32 input) public returns (bytes32 out); function functionName(bytes32 input) public returns (bytes32 out);
} }
)"; )";
@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract)
{ {
SourceUnit const* sourceUnit = nullptr; SourceUnit const* sourceUnit = nullptr;
char const* text = R"( char const* text = R"(
contract base { function foo() public; } abstract contract base { function foo() public; }
contract derived is base { function foo() public override {} } contract derived is base { function foo() public override {} }
)"; )";
sourceUnit = parseAndAnalyse(text); sourceUnit = parseAndAnalyse(text);
@ -83,8 +83,8 @@ BOOST_AUTO_TEST_CASE(abstract_contract_with_overload)
{ {
SourceUnit const* sourceUnit = nullptr; SourceUnit const* sourceUnit = nullptr;
char const* text = R"( char const* text = R"(
contract base { function foo(bool) public; } abstract contract base { function foo(bool) public; }
contract derived is base { function foo(uint) public {} } abstract contract derived is base { function foo(uint) public {} }
)"; )";
sourceUnit = parseAndAnalyse(text); sourceUnit = parseAndAnalyse(text);
std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes(); std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();
@ -100,8 +100,8 @@ BOOST_AUTO_TEST_CASE(implement_abstract_via_constructor)
{ {
SourceUnit const* sourceUnit = nullptr; SourceUnit const* sourceUnit = nullptr;
char const* text = R"( char const* text = R"(
contract base { function foo() public; } abstract contract base { function foo() public; }
contract foo is base { constructor() public {} } abstract contract foo is base { constructor() public {} }
)"; )";
sourceUnit = parseAndAnalyse(text); sourceUnit = parseAndAnalyse(text);
std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes(); std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->nodes();
@ -356,7 +356,7 @@ BOOST_AUTO_TEST_CASE(string)
BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible) BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible)
{ {
char const* sourceCode = R"( char const* sourceCode = R"(
contract C { abstract contract C {
function f(uint) public returns (string memory); function f(uint) public returns (string memory);
function g() public { function g() public {
string memory x = this.f(2); string memory x = this.f(2);

View File

@ -427,7 +427,7 @@ BOOST_AUTO_TEST_CASE(basic_compilation)
BOOST_CHECK_EQUAL( BOOST_CHECK_EQUAL(
dev::jsonCompactPrint(result["sources"]["fileA"]["legacyAST"]), dev::jsonCompactPrint(result["sources"]["fileA"]["legacyAST"]),
"{\"attributes\":{\"absolutePath\":\"fileA\",\"exportedSymbols\":{\"A\":[1]}},\"children\":" "{\"attributes\":{\"absolutePath\":\"fileA\",\"exportedSymbols\":{\"A\":[1]}},\"children\":"
"[{\"attributes\":{\"baseContracts\":[null],\"contractDependencies\":[null],\"contractKind\":\"contract\"," "[{\"attributes\":{\"abstract\":false,\"baseContracts\":[null],\"contractDependencies\":[null],\"contractKind\":\"contract\","
"\"documentation\":null,\"fullyImplemented\":true,\"linearizedBaseContracts\":[1],\"name\":\"A\",\"nodes\":[null],\"scope\":2}," "\"documentation\":null,\"fullyImplemented\":true,\"linearizedBaseContracts\":[1],\"name\":\"A\",\"nodes\":[null],\"scope\":2},"
"\"id\":1,\"name\":\"ContractDefinition\",\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}" "\"id\":1,\"name\":\"ContractDefinition\",\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}"
); );

View File

@ -17,4 +17,4 @@ contract C
} }
} }
// ---- // ----
// Warning: (240-254): Assertion violation happens here // TypeError: (33-75): Contract "D" should be marked as abstract.

View File

@ -17,4 +17,4 @@ contract C
} }
} }
// ---- // ----
// Warning: (280-304): Assertion violation happens here // TypeError: (33-75): Contract "D" should be marked as abstract.

View File

@ -18,4 +18,4 @@ contract C
} }
} }
// ---- // ----
// Warning: (338-362): Assertion violation happens here // TypeError: (33-75): Contract "D" should be marked as abstract.

View File

@ -0,0 +1,7 @@
interface A {
function utterance() external returns (bytes32);
}
contract B is A {
}
// ----
// TypeError: (69-88): Contract "B" should be marked as abstract.

View File

@ -0,0 +1,12 @@
abstract contract AbstractContract {
constructor() public { }
function utterance() public returns (bytes32) { return "miaow"; }
}
contract Test {
function create() public {
AbstractContract ac = new AbstractContract();
}
}
// ----
// TypeError: (215-235): Cannot instantiate an abstract contract.

View File

@ -0,0 +1 @@
abstract contract A { constructor() public {} }

View File

@ -0,0 +1,3 @@
abstract interface A { }
// ----
// TypeError: (0-24): Only contracts can be abstract.

View File

@ -0,0 +1,3 @@
abstract library A { }
// ----
// TypeError: (0-22): Only contracts can be abstract.

View File

@ -0,0 +1,5 @@
contract A {
function a() public;
}
// ----
// TypeError: (0-39): Contract "A" should be marked as abstract.

View File

@ -0,0 +1,7 @@
abstract contract A {
function a() public;
}
contract B is A {
}
// ----
// TypeError: (49-68): Contract "B" should be marked as abstract.

View File

@ -12,4 +12,4 @@ contract Parent {
contract Child is Parent { contract Child is Parent {
} }
// ---- // ----
// TypeError: (146-155): Trying to create an instance of an abstract contract. // TypeError: (146-155): Cannot instantiate an abstract contract.

View File

@ -2,3 +2,5 @@ contract C {
function f() internal returns(uint[] storage); function f() internal returns(uint[] storage);
function g() internal returns(uint[] storage s); function g() internal returns(uint[] storage s);
} }
// ----
// TypeError: (0-118): Contract "C" should be marked as abstract.

View File

@ -2,3 +2,4 @@ contract test {
function f(bytes calldata) external; function f(bytes calldata) external;
} }
// ---- // ----
// TypeError: (0-58): Contract "test" should be marked as abstract.

View File

@ -2,3 +2,4 @@ contract test {
function f(bytes memory) internal; function f(bytes memory) internal;
} }
// ---- // ----
// TypeError: (0-56): Contract "test" should be marked as abstract.

View File

@ -2,3 +2,4 @@ contract test {
function f(bytes storage) internal; function f(bytes storage) internal;
} }
// ---- // ----
// TypeError: (0-57): Contract "test" should be marked as abstract.

View File

@ -2,3 +2,4 @@ contract test {
function f(bytes memory) public; function f(bytes memory) public;
} }
// ---- // ----
// TypeError: (0-54): Contract "test" should be marked as abstract.

View File

@ -7,3 +7,4 @@ contract T {
} }
// ---- // ----
// DeclarationError: (81-105): Identifier already declared. // DeclarationError: (81-105): Identifier already declared.
// TypeError: (0-58): Contract "X" should be marked as abstract.

View File

@ -5,3 +5,5 @@ contract Y is X {
contract T { contract T {
constructor() public { new Y(); } constructor() public { new Y(); }
} }
// ----
// TypeError: (0-57): Contract "X" should be marked as abstract.

View File

@ -7,3 +7,4 @@ contract T {
} }
// ---- // ----
// DeclarationError: (79-103): Identifier already declared. // DeclarationError: (79-103): Identifier already declared.
// TypeError: (0-56): Contract "X" should be marked as abstract.

Some files were not shown because too many files have changed in this diff Show More