Skip to content

Commit

Permalink
[Lity] Support freegas modifier, which allows developers to use c…
Browse files Browse the repository at this point in the history
…ontract balance to pay the transaction fee.

- Add a new opcode ``freegas`` at 0xf8.
  • Loading branch information
hydai committed Feb 27, 2019
1 parent c03f43b commit 5e14982
Show file tree
Hide file tree
Showing 22 changed files with 157 additions and 59 deletions.
8 changes: 8 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
### Lity 1.2.7 (2019-02-27)

Features:
* Add support for `contract-standard` option in JSON compiler.

Language Features:
* General: Add a new modifier ``freegas``, which allows developers to use contract balance to pay the transaction fee for the users.

### Lity 1.2.6 (2018-12-07)

Language Features:
Expand Down
4 changes: 2 additions & 2 deletions libevmasm/Assembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ Json::Value Assembly::assemblyJSON(StringMap const& _sourceCodes) const
createJsonValue("PUSH [ErrorTag]", i.location().start, i.location().end, ""));
else
collection.append(
createJsonValue("PUSH [tag]", i.location().start, i.location().end, string(i.data())));
createJsonValue("PUSH [tag]", i.location().start, i.location().end, dev::toString(i.data())));
break;
case PushSub:
collection.append(
Expand All @@ -290,7 +290,7 @@ Json::Value Assembly::assemblyJSON(StringMap const& _sourceCodes) const
break;
case Tag:
collection.append(
createJsonValue("tag", i.location().start, i.location().end, string(i.data())));
createJsonValue("tag", i.location().start, i.location().end, dev::toString(i.data())));
collection.append(
createJsonValue("JUMPDEST", i.location().start, i.location().end));
break;
Expand Down
3 changes: 3 additions & 0 deletions libevmasm/GasMeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _
case Instruction::ISVALIDATOR:
gas = GasCosts::isValidatorGas;
break;
case Instruction::FREEGAS:
gas = GasCosts::freeGasGas;
break;
case Instruction::CALLDATACOPY:
case Instruction::CODECOPY:
case Instruction::RETURNDATACOPY:
Expand Down
1 change: 1 addition & 0 deletions libevmasm/GasMeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ namespace GasCosts
static unsigned const txDataNonZeroGas = 68;
static unsigned const copyGas = 3;
static unsigned const isValidatorGas = 3;
static unsigned const freeGasGas = 3;
}

/**
Expand Down
2 changes: 2 additions & 0 deletions libevmasm/Instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ const std::map<std::string, Instruction> dev::solidity::c_instructions =
{ "SFDIV", Instruction::SFDIV },
{ "ENI", Instruction::ENI },
{ "ISVALIDATOR", Instruction::ISVALIDATOR },
{ "FREEGAS", Instruction::FREEGAS },
{ "ADDRESS", Instruction::ADDRESS },
{ "BALANCE", Instruction::BALANCE },
{ "ORIGIN", Instruction::ORIGIN },
Expand Down Expand Up @@ -218,6 +219,7 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::SFDIV, { "SFDIV", 0, 3, 1, false, Tier::Mid } },
{ Instruction::ENI, { "ENI", 0, 3, 1, true, Tier::Special } },
{ Instruction::ISVALIDATOR, { "ISVALIDATOR", 0, 1, 1, false, Tier::VeryLow } },
{ Instruction::FREEGAS, { "FREEGAS", 0, 0, 0, false, Tier::VeryLow } },
{ Instruction::ADDRESS, { "ADDRESS", 0, 0, 1, false, Tier::Base } },
{ Instruction::BALANCE, { "BALANCE", 0, 1, 1, false, Tier::Balance } },
{ Instruction::ORIGIN, { "ORIGIN", 0, 0, 1, false, Tier::Base } },
Expand Down
3 changes: 2 additions & 1 deletion libevmasm/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ enum class Instruction: uint8_t
RETURN, ///< halt execution returning output data
DELEGATECALL, ///< like CALLCODE but keeps caller's value and sender
ENI,
ISVALIDATOR,
ISVALIDATOR = 0xf6,
FREEGAS = 0xf8,
STATICCALL = 0xfa, ///< like CALL but disallow state modifications
CREATE2 = 0xfb, ///< create new account with associated code at address `sha3(sender + salt + sha3(init code)) % 2**160`

Expand Down
48 changes: 24 additions & 24 deletions libsolidity/analysis/ContractStandardChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,12 @@ FunctionSpecifications const& ERC20ContractStandard::requiredFunctions() const
{
static FunctionSpecifications ret =
{ // Note that ERC20 standard says name() / symbol() / decimals() are OPTIONAL
{"totalSupply", make_shared<FunctionType>(strings(), strings{"uint256"}, FunctionType::Kind::External, false, StateMutability::View)},
{"balanceOf", make_shared<FunctionType>(strings{"address"}, strings{"uint256"}, FunctionType::Kind::External, false, StateMutability::View)},
{"totalSupply", make_shared<FunctionType>(strings(), strings{"uint256"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"balanceOf", make_shared<FunctionType>(strings{"address"}, strings{"uint256"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"transfer", make_shared<FunctionType>(strings{"address", "uint256"}, strings{"bool"}, FunctionType::Kind::External)},
{"transferFrom", make_shared<FunctionType>(strings{"address", "address", "uint256"}, strings{"bool"}, FunctionType::Kind::External)},
{"approve", make_shared<FunctionType>(strings{"address", "uint256"}, strings{"bool"}, FunctionType::Kind::External)},
{"allowance", make_shared<FunctionType>(strings{"address", "address"}, strings{"uint256"}, FunctionType::Kind::External, false, StateMutability::View)},
{"allowance", make_shared<FunctionType>(strings{"address", "address"}, strings{"uint256"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"Transfer", make_shared<FunctionType>(strings{"address", "address", "uint256"}, strings(), FunctionType::Kind::Event)},
{"Approval", make_shared<FunctionType>(strings{"address", "address", "uint256"}, strings(), FunctionType::Kind::Event)}
};
Expand All @@ -211,8 +211,8 @@ FunctionSpecifications const& ERC223ContractStandard::requiredFunctions() const
static FunctionSpecifications ret =
{ // we explicitly use "bytes memory" because Type::fromElementaryTypeName(string) defaults to storage,
// but the default for function parameters in solidity is memory
{"totalSupply", make_shared<FunctionType>(strings(), strings{"uint256"}, FunctionType::Kind::External, false, StateMutability::View)},
{"balanceOf", make_shared<FunctionType>(strings{"address"}, strings{"uint256"}, FunctionType::Kind::External, false, StateMutability::View)},
{"totalSupply", make_shared<FunctionType>(strings(), strings{"uint256"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"balanceOf", make_shared<FunctionType>(strings{"address"}, strings{"uint256"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"transfer", make_shared<FunctionType>(strings{"address", "uint256"}, strings{"bool"}, FunctionType::Kind::External)},
{"transfer", make_shared<FunctionType>(strings{"address", "uint256", "bytes memory"}, strings{"bool"}, FunctionType::Kind::External)},
{"Transfer", make_shared<FunctionType>(strings{"address", "address", "uint256", "bytes memory"}, strings(), FunctionType::Kind::Event)},
Expand Down Expand Up @@ -244,16 +244,16 @@ FunctionSpecifications const& ERC721ContractStandard::requiredFunctions() const
{"Transfer", make_shared<FunctionType>(strings{"address", "address", "uint256"}, strings(), FunctionType::Kind::Event)},
{"Approval", make_shared<FunctionType>(strings{"address", "address", "uint256"}, strings(), FunctionType::Kind::Event)},
{"ApprovalForAll", make_shared<FunctionType>(strings{"address", "address", "bool"}, strings(), FunctionType::Kind::Event)},
{"balanceOf", make_shared<FunctionType>(strings{"address"}, strings{"uint256"}, FunctionType::Kind::External, false, StateMutability::View)},
{"ownerOf", make_shared<FunctionType>(strings{"uint256"}, strings{"address"}, FunctionType::Kind::External, false, StateMutability::View)},
{"safeTransferFrom", make_shared<FunctionType>(strings{"address", "address", "uint256", "bytes calldata"}, strings(), FunctionType::Kind::External, false, StateMutability::Payable)},
{"safeTransferFrom", make_shared<FunctionType>(strings{"address", "address", "uint256"}, strings(), FunctionType::Kind::External, false, StateMutability::Payable)},
{"transferFrom", make_shared<FunctionType>(strings{"address", "address", "uint256"}, strings(), FunctionType::Kind::External, false, StateMutability::Payable)},
{"approve", make_shared<FunctionType>(strings{"address", "uint256"}, strings(), FunctionType::Kind::External, false, StateMutability::Payable)},
{"balanceOf", make_shared<FunctionType>(strings{"address"}, strings{"uint256"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"ownerOf", make_shared<FunctionType>(strings{"uint256"}, strings{"address"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"safeTransferFrom", make_shared<FunctionType>(strings{"address", "address", "uint256", "bytes calldata"}, strings(), FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::Payable)},
{"safeTransferFrom", make_shared<FunctionType>(strings{"address", "address", "uint256"}, strings(), FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::Payable)},
{"transferFrom", make_shared<FunctionType>(strings{"address", "address", "uint256"}, strings(), FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::Payable)},
{"approve", make_shared<FunctionType>(strings{"address", "uint256"}, strings(), FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::Payable)},
{"setApprovalForAll", make_shared<FunctionType>(strings{"address", "bool"}, strings(), FunctionType::Kind::External)},
{"getApproved", make_shared<FunctionType>(strings{"uint256"}, strings{"address"}, FunctionType::Kind::External, false, StateMutability::View)},
{"isApprovedForAll", make_shared<FunctionType>(strings{"address", "address"}, strings{"bool"}, FunctionType::Kind::External, false, StateMutability::View)},
{"supportsInterface", make_shared<FunctionType>(strings{"bytes4"}, strings{"bool"}, FunctionType::Kind::External, false, StateMutability::View)},
{"getApproved", make_shared<FunctionType>(strings{"uint256"}, strings{"address"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"isApprovedForAll", make_shared<FunctionType>(strings{"address", "address"}, strings{"bool"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"supportsInterface", make_shared<FunctionType>(strings{"bytes4"}, strings{"bool"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
};
return ret;
}
Expand All @@ -269,9 +269,9 @@ FunctionSpecifications const& ERC827ContractStandard::requiredFunctions() const
{
FunctionSpecifications erc827 =
{
{"transferAndCall", make_shared<FunctionType>(strings{"address", "uint256", "bytes memory"}, strings{"bool"}, FunctionType::Kind::External, false, StateMutability::Payable)},
{"transferFromAndCall", make_shared<FunctionType>(strings{"address", "address", "uint256", "bytes memory"}, strings{"bool"}, FunctionType::Kind::External, false, StateMutability::Payable)},
{"approveAndCall", make_shared<FunctionType>(strings{"address", "uint256", "bytes memory"}, strings{"bool"}, FunctionType::Kind::External, false, StateMutability::Payable)},
{"transferAndCall", make_shared<FunctionType>(strings{"address", "uint256", "bytes memory"}, strings{"bool"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::Payable)},
{"transferFromAndCall", make_shared<FunctionType>(strings{"address", "address", "uint256", "bytes memory"}, strings{"bool"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::Payable)},
{"approveAndCall", make_shared<FunctionType>(strings{"address", "uint256", "bytes memory"}, strings{"bool"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::Payable)},
};
// also need erc20 standard functions
erc827.insert(erc827.end(), ERC20ContractStandard::requiredFunctions().begin(), ERC20ContractStandard::requiredFunctions().end());
Expand Down Expand Up @@ -301,13 +301,13 @@ FunctionSpecifications const& ERC884ContractStandard::requiredFunctions() const
{"removeVerified", make_shared<FunctionType>(strings{"address"}, strings(), FunctionType::Kind::External)},
{"updateVerified", make_shared<FunctionType>(strings{"address", "bytes32"}, strings(), FunctionType::Kind::External)},
{"cancelAndReissue", make_shared<FunctionType>(strings{"address", "address"}, strings(), FunctionType::Kind::External)},
{"isVerified", make_shared<FunctionType>(strings{"address"}, strings{"bool"}, FunctionType::Kind::External, false, StateMutability::View)},
{"isHolder", make_shared<FunctionType>(strings{"address"}, strings{"bool"}, FunctionType::Kind::External, false, StateMutability::View)},
{"hasHash", make_shared<FunctionType>(strings{"address", "bytes32"}, strings{"bool"}, FunctionType::Kind::External, false, StateMutability::View)},
{"holderCount", make_shared<FunctionType>(strings(), strings{"uint"}, FunctionType::Kind::External, false, StateMutability::View)},
{"holderAt", make_shared<FunctionType>(strings{"uint256"}, strings{"address"}, FunctionType::Kind::External, false, StateMutability::View)},
{"isSuperseded", make_shared<FunctionType>(strings{"address"}, strings{"bool"}, FunctionType::Kind::External, false, StateMutability::View)},
{"getCurrentFor", make_shared<FunctionType>(strings{"address"}, strings{"address"}, FunctionType::Kind::External, false, StateMutability::View)},
{"isVerified", make_shared<FunctionType>(strings{"address"}, strings{"bool"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"isHolder", make_shared<FunctionType>(strings{"address"}, strings{"bool"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"hasHash", make_shared<FunctionType>(strings{"address", "bytes32"}, strings{"bool"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"holderCount", make_shared<FunctionType>(strings(), strings{"uint"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"holderAt", make_shared<FunctionType>(strings{"uint256"}, strings{"address"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"isSuperseded", make_shared<FunctionType>(strings{"address"}, strings{"bool"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
{"getCurrentFor", make_shared<FunctionType>(strings{"address"}, strings{"address"}, FunctionType::Kind::External, FunctionType::SpecialModifier::Default, false, StateMutability::View)},
};
// also need erc20 standard functions
erc884.insert(erc884.end(), ERC20ContractStandard::requiredFunctions().begin(), ERC20ContractStandard::requiredFunctions().end());
Expand Down

0 comments on commit 5e14982

Please sign in to comment.