mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
fix: corrects _ prefixes
This commit is contained in:
parent
7f360e61fc
commit
beb51068bb
@ -45,10 +45,10 @@ Solidity language without a compiler change.
|
||||
pragma solidity >=0.4.16 <0.9.0;
|
||||
|
||||
library GetCode {
|
||||
function at(address _addr) public view returns (bytes memory code) {
|
||||
function at(address addr) public view returns (bytes memory code) {
|
||||
assembly {
|
||||
// retrieve the size of the code, this needs assembly
|
||||
let size := extcodesize(_addr)
|
||||
let size := extcodesize(addr)
|
||||
// allocate output byte array - this could also be done without assembly
|
||||
// by using code = new bytes(size)
|
||||
code := mload(0x40)
|
||||
@ -57,7 +57,7 @@ Solidity language without a compiler change.
|
||||
// store length in memory
|
||||
mstore(code, size)
|
||||
// actually retrieve the code, this needs assembly
|
||||
extcodecopy(_addr, add(code, 0x20), 0, size)
|
||||
extcodecopy(addr, add(code, 0x20), 0, size)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -74,43 +74,43 @@ efficient code, for example:
|
||||
library VectorSum {
|
||||
// This function is less efficient because the optimizer currently fails to
|
||||
// remove the bounds checks in array access.
|
||||
function sumSolidity(uint[] memory _data) public pure returns (uint sum) {
|
||||
for (uint i = 0; i < _data.length; ++i)
|
||||
sum += _data[i];
|
||||
function sumSolidity(uint[] memory data) public pure returns (uint sum) {
|
||||
for (uint i = 0; i < data.length; ++i)
|
||||
sum += data[i];
|
||||
}
|
||||
|
||||
// We know that we only access the array in bounds, so we can avoid the check.
|
||||
// 0x20 needs to be added to an array because the first slot contains the
|
||||
// array length.
|
||||
function sumAsm(uint[] memory _data) public pure returns (uint sum) {
|
||||
for (uint i = 0; i < _data.length; ++i) {
|
||||
function sumAsm(uint[] memory data) public pure returns (uint sum) {
|
||||
for (uint i = 0; i < data.length; ++i) {
|
||||
assembly {
|
||||
sum := add(sum, mload(add(add(_data, 0x20), mul(i, 0x20))))
|
||||
sum := add(sum, mload(add(add(data, 0x20), mul(i, 0x20))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Same as above, but accomplish the entire code within inline assembly.
|
||||
function sumPureAsm(uint[] memory _data) public pure returns (uint sum) {
|
||||
function sumPureAsm(uint[] memory data) public pure returns (uint sum) {
|
||||
assembly {
|
||||
// Load the length (first 32 bytes)
|
||||
let len := mload(_data)
|
||||
let len := mload(data)
|
||||
|
||||
// Skip over the length field.
|
||||
//
|
||||
// Keep temporary variable so it can be incremented in place.
|
||||
//
|
||||
// NOTE: incrementing _data would result in an unusable
|
||||
// _data variable after this assembly block
|
||||
let data := add(_data, 0x20)
|
||||
// NOTE: incrementing data would result in an unusable
|
||||
// data variable after this assembly block
|
||||
let dataElementLocation := add(data, 0x20)
|
||||
|
||||
// Iterate until the bound is not met.
|
||||
for
|
||||
{ let end := add(data, mul(len, 0x20)) }
|
||||
lt(data, end)
|
||||
{ data := add(data, 0x20) }
|
||||
{ let end := add(dataElementLocation, mul(len, 0x20)) }
|
||||
lt(dataElementLocation, end)
|
||||
{ data := add(dataElementLocation, 0x20) }
|
||||
{
|
||||
sum := add(sum, mload(data))
|
||||
sum := add(sum, mload(dataElementLocation))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -163,9 +163,9 @@ restrictions highly readable.
|
||||
// prepend a check that only passes
|
||||
// if the function is called from
|
||||
// a certain address.
|
||||
modifier onlyBy(address _account)
|
||||
modifier onlyBy(address account)
|
||||
{
|
||||
if (msg.sender != _account)
|
||||
if (msg.sender != account)
|
||||
revert Unauthorized();
|
||||
// Do not forget the "_;"! It will
|
||||
// be replaced by the actual function
|
||||
@ -173,17 +173,17 @@ restrictions highly readable.
|
||||
_;
|
||||
}
|
||||
|
||||
/// Make `_newOwner` the new owner of this
|
||||
/// Make `newOwner` the new owner of this
|
||||
/// contract.
|
||||
function changeOwner(address _newOwner)
|
||||
function changeOwner(address newOwner)
|
||||
public
|
||||
onlyBy(owner)
|
||||
{
|
||||
owner = _newOwner;
|
||||
owner = newOwner;
|
||||
}
|
||||
|
||||
modifier onlyAfter(uint _time) {
|
||||
if (block.timestamp < _time)
|
||||
modifier onlyAfter(uint time) {
|
||||
if (block.timestamp < time)
|
||||
revert TooEarly();
|
||||
_;
|
||||
}
|
||||
@ -205,21 +205,21 @@ restrictions highly readable.
|
||||
// refunded, but only after the function body.
|
||||
// This was dangerous before Solidity version 0.4.0,
|
||||
// where it was possible to skip the part after `_;`.
|
||||
modifier costs(uint _amount) {
|
||||
if (msg.value < _amount)
|
||||
modifier costs(uint amount) {
|
||||
if (msg.value < amount)
|
||||
revert NotEnoughEther();
|
||||
|
||||
_;
|
||||
if (msg.value > _amount)
|
||||
payable(msg.sender).transfer(msg.value - _amount);
|
||||
if (msg.value > amount)
|
||||
payable(msg.sender).transfer(msg.value - amount);
|
||||
}
|
||||
|
||||
function forceOwnerChange(address _newOwner)
|
||||
function forceOwnerChange(address newOwner)
|
||||
public
|
||||
payable
|
||||
costs(200 ether)
|
||||
{
|
||||
owner = _newOwner;
|
||||
owner = newOwner;
|
||||
// just some example condition
|
||||
if (uint160(owner) & 0 == 1)
|
||||
// This did not refund for Solidity
|
||||
@ -315,8 +315,8 @@ function finishes.
|
||||
|
||||
uint public creationTime = block.timestamp;
|
||||
|
||||
modifier atStage(Stages _stage) {
|
||||
if (stage != _stage)
|
||||
modifier atStage(Stages stage_) {
|
||||
if (stage != stage_)
|
||||
revert FunctionInvalidAtThisStage();
|
||||
_;
|
||||
}
|
||||
|
@ -41,14 +41,14 @@ Not all types for constants and immutables are implemented at this time. The onl
|
||||
uint immutable maxBalance;
|
||||
address immutable owner = msg.sender;
|
||||
|
||||
constructor(uint _decimals, address _reference) {
|
||||
decimals = _decimals;
|
||||
constructor(uint decimals_, address ref) {
|
||||
decimals = decimals_;
|
||||
// Assignments to immutables can even access the environment.
|
||||
maxBalance = _reference.balance;
|
||||
maxBalance = ref.balance;
|
||||
}
|
||||
|
||||
function isBalanceTooHigh(address _other) public view returns (bool) {
|
||||
return _other.balance > maxBalance;
|
||||
function isBalanceTooHigh(address other) public view returns (bool) {
|
||||
return other.balance > maxBalance;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ This means that cyclic creation dependencies are impossible.
|
||||
|
||||
// This is the constructor which registers the
|
||||
// creator and the assigned name.
|
||||
constructor(bytes32 _name) {
|
||||
constructor(bytes32 name_) {
|
||||
// State variables are accessed via their name
|
||||
// and not via e.g. `this.owner`. Functions can
|
||||
// be accessed directly or through `this.f`,
|
||||
@ -65,7 +65,7 @@ This means that cyclic creation dependencies are impossible.
|
||||
// no real way to verify that.
|
||||
// This does not create a new contract.
|
||||
creator = TokenCreator(msg.sender);
|
||||
name = _name;
|
||||
name = name_;
|
||||
}
|
||||
|
||||
function changeName(bytes32 newName) public {
|
||||
|
@ -80,18 +80,18 @@ four indexed arguments rather than three.
|
||||
|
||||
contract ClientReceipt {
|
||||
event Deposit(
|
||||
address indexed _from,
|
||||
bytes32 indexed _id,
|
||||
uint _value
|
||||
address indexed from,
|
||||
bytes32 indexed id,
|
||||
uint value
|
||||
);
|
||||
|
||||
function deposit(bytes32 _id) public payable {
|
||||
function deposit(bytes32 id) public payable {
|
||||
// Events are emitted using `emit`, followed by
|
||||
// the name of the event and the arguments
|
||||
// (if any) in parentheses. Any such invocation
|
||||
// (even deeply nested) can be detected from
|
||||
// the JavaScript API by filtering for `Deposit`.
|
||||
emit Deposit(msg.sender, _id, msg.value);
|
||||
emit Deposit(msg.sender, id, msg.value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,9 +126,9 @@ The output of the above looks like the following (trimmed):
|
||||
|
||||
{
|
||||
"returnValues": {
|
||||
"_from": "0x1111…FFFFCCCC",
|
||||
"_id": "0x50…sd5adb20",
|
||||
"_value": "0x420042"
|
||||
"from": "0x1111…FFFFCCCC",
|
||||
"id": "0x50…sd5adb20",
|
||||
"value": "0x420042"
|
||||
},
|
||||
"raw": {
|
||||
"data": "0x7f…91385",
|
||||
|
@ -72,8 +72,8 @@ if they are marked ``virtual``. For details, please see
|
||||
registeredAddresses[msg.sender] = true;
|
||||
}
|
||||
|
||||
function changePrice(uint _price) public onlyOwner {
|
||||
price = _price;
|
||||
function changePrice(uint price_) public onlyOwner {
|
||||
price = price_;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,17 +17,17 @@ that call them, similar to internal library functions.
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.7.1 <0.9.0;
|
||||
|
||||
function sum(uint[] memory _arr) pure returns (uint s) {
|
||||
for (uint i = 0; i < _arr.length; i++)
|
||||
s += _arr[i];
|
||||
function sum(uint[] memory arr) pure returns (uint s) {
|
||||
for (uint i = 0; i < arr.length; i++)
|
||||
s += arr[i];
|
||||
}
|
||||
|
||||
contract ArrayExample {
|
||||
bool found;
|
||||
function f(uint[] memory _arr) public {
|
||||
function f(uint[] memory arr) public {
|
||||
// This calls the free function internally.
|
||||
// The compiler will add its code to the contract.
|
||||
uint s = sum(_arr);
|
||||
uint s = sum(arr);
|
||||
require(s >= 10);
|
||||
found = true;
|
||||
}
|
||||
@ -65,8 +65,8 @@ with two integers, you would use something like the following:
|
||||
|
||||
contract Simple {
|
||||
uint sum;
|
||||
function taker(uint _a, uint _b) public {
|
||||
sum = _a + _b;
|
||||
function taker(uint a, uint b) public {
|
||||
sum = a + b;
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,13 +99,13 @@ two integers passed as function parameters, then you use something like:
|
||||
pragma solidity >=0.4.16 <0.9.0;
|
||||
|
||||
contract Simple {
|
||||
function arithmetic(uint _a, uint _b)
|
||||
function arithmetic(uint a, uint b)
|
||||
public
|
||||
pure
|
||||
returns (uint sum, uint product)
|
||||
{
|
||||
sum = _a + _b;
|
||||
product = _a * _b;
|
||||
sum = a + b;
|
||||
product = a * b;
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,12 +126,12 @@ statement:
|
||||
pragma solidity >=0.4.16 <0.9.0;
|
||||
|
||||
contract Simple {
|
||||
function arithmetic(uint _a, uint _b)
|
||||
function arithmetic(uint a, uint b)
|
||||
public
|
||||
pure
|
||||
returns (uint sum, uint product)
|
||||
{
|
||||
return (_a + _b, _a * _b);
|
||||
return (a + b, a * b);
|
||||
}
|
||||
}
|
||||
|
||||
@ -362,7 +362,7 @@ Fallback Function
|
||||
-----------------
|
||||
|
||||
A contract can have at most one ``fallback`` function, declared using either ``fallback () external [payable]``
|
||||
or ``fallback (bytes calldata _input) external [payable] returns (bytes memory _output)``
|
||||
or ``fallback (bytes calldata input) external [payable] returns (bytes memory output)``
|
||||
(both without the ``function`` keyword).
|
||||
This function must have ``external`` visibility. A fallback function can be virtual, can override
|
||||
and can have modifiers.
|
||||
@ -373,8 +373,8 @@ all and there is no :ref:`receive Ether function <receive-ether-function>`.
|
||||
The fallback function always receives data, but in order to also receive Ether
|
||||
it must be marked ``payable``.
|
||||
|
||||
If the version with parameters is used, ``_input`` will contain the full data sent to the contract
|
||||
(equal to ``msg.data``) and can return data in ``_output``. The returned data will not be
|
||||
If the version with parameters is used, ``input`` will contain the full data sent to the contract
|
||||
(equal to ``msg.data``) and can return data in ``output``. The returned data will not be
|
||||
ABI-encoded. Instead it will be returned without modifications (not even padding).
|
||||
|
||||
In the worst case, if a payable fallback function is also used in
|
||||
@ -397,7 +397,7 @@ operations as long as there is enough gas passed on to it.
|
||||
for the function selector and then
|
||||
you can use ``abi.decode`` together with the array slice syntax to
|
||||
decode ABI-encoded data:
|
||||
``(c, d) = abi.decode(_input[4:], (uint256, uint256));``
|
||||
``(c, d) = abi.decode(input[4:], (uint256, uint256));``
|
||||
Note that this should only be used as a last resort and
|
||||
proper functions should be used instead.
|
||||
|
||||
@ -486,13 +486,13 @@ The following example shows overloading of the function
|
||||
pragma solidity >=0.4.16 <0.9.0;
|
||||
|
||||
contract A {
|
||||
function f(uint _in) public pure returns (uint out) {
|
||||
out = _in;
|
||||
function f(uint value) public pure returns (uint out) {
|
||||
out = value;
|
||||
}
|
||||
|
||||
function f(uint _in, bool _really) public pure returns (uint out) {
|
||||
if (_really)
|
||||
out = _in;
|
||||
function f(uint value, bool really) public pure returns (uint out) {
|
||||
if (really)
|
||||
out = value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -506,12 +506,12 @@ externally visible functions differ by their Solidity types but not by their ext
|
||||
|
||||
// This will not compile
|
||||
contract A {
|
||||
function f(B _in) public pure returns (B out) {
|
||||
out = _in;
|
||||
function f(B value) public pure returns (B out) {
|
||||
out = value;
|
||||
}
|
||||
|
||||
function f(address _in) public pure returns (address out) {
|
||||
out = _in;
|
||||
function f(address value) public pure returns (address out) {
|
||||
out = value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -539,12 +539,12 @@ candidate, resolution fails.
|
||||
pragma solidity >=0.4.16 <0.9.0;
|
||||
|
||||
contract A {
|
||||
function f(uint8 _in) public pure returns (uint8 out) {
|
||||
out = _in;
|
||||
function f(uint8 val) public pure returns (uint8 out) {
|
||||
out = val;
|
||||
}
|
||||
|
||||
function f(uint256 _in) public pure returns (uint256 out) {
|
||||
out = _in;
|
||||
function f(uint256 val) public pure returns (uint256 out) {
|
||||
out = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,8 +421,8 @@ equivalent to ``constructor() {}``. For example:
|
||||
abstract contract A {
|
||||
uint public a;
|
||||
|
||||
constructor(uint _a) {
|
||||
a = _a;
|
||||
constructor(uint a_) {
|
||||
a = a_;
|
||||
}
|
||||
}
|
||||
|
||||
@ -459,7 +459,7 @@ derived contracts need to specify all of them. This can be done in two ways:
|
||||
|
||||
contract Base {
|
||||
uint x;
|
||||
constructor(uint _x) { x = _x; }
|
||||
constructor(uint x_) { x = x_; }
|
||||
}
|
||||
|
||||
// Either directly specify in the inheritance list...
|
||||
@ -469,12 +469,12 @@ derived contracts need to specify all of them. This can be done in two ways:
|
||||
|
||||
// or through a "modifier" of the derived constructor.
|
||||
contract Derived2 is Base {
|
||||
constructor(uint _y) Base(_y * _y) {}
|
||||
constructor(uint y) Base(y * y) {}
|
||||
}
|
||||
|
||||
One way is directly in the inheritance list (``is Base(7)``). The other is in
|
||||
the way a modifier is invoked as part of
|
||||
the derived constructor (``Base(_y * _y)``). The first way to
|
||||
the derived constructor (``Base(y * y)``). The first way to
|
||||
do it is more convenient if the constructor argument is a
|
||||
constant and defines the behaviour of the contract or
|
||||
describes it. The second way has to be used if the
|
||||
|
@ -146,16 +146,16 @@ custom types without the overhead of external function calls:
|
||||
r.limbs[0] = x;
|
||||
}
|
||||
|
||||
function add(bigint memory _a, bigint memory _b) internal pure returns (bigint memory r) {
|
||||
r.limbs = new uint[](max(_a.limbs.length, _b.limbs.length));
|
||||
function add(bigint memory a, bigint memory b) internal pure returns (bigint memory r) {
|
||||
r.limbs = new uint[](max(a.limbs.length, b.limbs.length));
|
||||
uint carry = 0;
|
||||
for (uint i = 0; i < r.limbs.length; ++i) {
|
||||
uint a = limb(_a, i);
|
||||
uint b = limb(_b, i);
|
||||
uint limbA = limb(a, i);
|
||||
uint limbB = limb(b, i);
|
||||
unchecked {
|
||||
r.limbs[i] = a + b + carry;
|
||||
r.limbs[i] = limbA + limbB + carry;
|
||||
|
||||
if (a + b < a || (a + b == type(uint).max && carry > 0))
|
||||
if (limbA + limbB < limbA || (limbA + limbB == type(uint).max && carry > 0))
|
||||
carry = 1;
|
||||
else
|
||||
carry = 0;
|
||||
@ -172,8 +172,8 @@ custom types without the overhead of external function calls:
|
||||
}
|
||||
}
|
||||
|
||||
function limb(bigint memory _a, uint _limb) internal pure returns (uint) {
|
||||
return _limb < _a.limbs.length ? _a.limbs[_limb] : 0;
|
||||
function limb(bigint memory a, uint index) internal pure returns (uint) {
|
||||
return index < a.limbs.length ? a.limbs[index] : 0;
|
||||
}
|
||||
|
||||
function max(uint a, uint b) private pure returns (uint) {
|
||||
|
@ -128,13 +128,13 @@ In this example, we will use a library.
|
||||
data.push(value);
|
||||
}
|
||||
|
||||
function replace(uint _old, uint _new) public {
|
||||
function replace(uint from, uint to) public {
|
||||
// This performs the library function call
|
||||
uint index = data.indexOf(_old);
|
||||
uint index = data.indexOf(from);
|
||||
if (index == type(uint).max)
|
||||
data.push(_new);
|
||||
data.push(to);
|
||||
else
|
||||
data[index] = _new;
|
||||
data[index] = to;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,8 +168,8 @@ following:
|
||||
|
||||
.. code-block:: solidity
|
||||
|
||||
function balances(address _account) external view returns (uint) {
|
||||
return balances[_account];
|
||||
function balances(address account) external view returns (uint) {
|
||||
return balances[account];
|
||||
}
|
||||
|
||||
You can use this function to query the balance of a single account.
|
||||
|
@ -74,8 +74,8 @@ hiding new and different behavior in existing code.
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.7.0;
|
||||
contract C {
|
||||
function f(uint _a) public pure mod() returns (uint _r) {
|
||||
_r = _a++;
|
||||
function f(uint a) public pure mod() returns (uint r) {
|
||||
r = a++;
|
||||
}
|
||||
modifier mod() { _; _; }
|
||||
}
|
||||
@ -166,7 +166,7 @@ This causes differences in some contracts, for example:
|
||||
|
||||
contract C {
|
||||
bytes x;
|
||||
function f() public returns (uint _r) {
|
||||
function f() public returns (uint r) {
|
||||
bytes memory m = "tmp";
|
||||
assembly {
|
||||
mstore(m, 8)
|
||||
@ -174,7 +174,7 @@ This causes differences in some contracts, for example:
|
||||
}
|
||||
x = m;
|
||||
assembly {
|
||||
_r := sload(x.slot)
|
||||
r := sload(x.slot)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -197,8 +197,8 @@ This causes differences in some contracts, for example:
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.8.1;
|
||||
contract C {
|
||||
function preincr_u8(uint8 _a) public pure returns (uint8) {
|
||||
return ++_a + _a;
|
||||
function preincr_u8(uint8 a) public pure returns (uint8) {
|
||||
return ++a + a;
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,11 +218,11 @@ This causes differences in some contracts, for example:
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.8.1;
|
||||
contract C {
|
||||
function add(uint8 _a, uint8 _b) public pure returns (uint8) {
|
||||
return _a + _b;
|
||||
function add(uint8 a, uint8 b) public pure returns (uint8) {
|
||||
return a + b;
|
||||
}
|
||||
function g(uint8 _a, uint8 _b) public pure returns (uint8) {
|
||||
return add(++_a + ++_b, _a + _b);
|
||||
function g(uint8 a, uint8 b) public pure returns (uint8) {
|
||||
return add(++a + ++b, a + b);
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,13 +321,13 @@ For example:
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
pragma solidity >=0.8.1;
|
||||
contract C {
|
||||
function f(uint8 _a) public pure returns (uint _r1, uint _r2)
|
||||
function f(uint8 a) public pure returns (uint r1, uint r2)
|
||||
{
|
||||
_a = ~_a;
|
||||
a = ~a;
|
||||
assembly {
|
||||
_r1 := _a
|
||||
r1 := a
|
||||
}
|
||||
_r2 = _a;
|
||||
r2 = a;
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,6 +336,6 @@ The function ``f(1)`` returns the following values:
|
||||
- Old code generator: (``fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe``, ``00000000000000000000000000000000000000000000000000000000000000fe``)
|
||||
- New code generator: (``00000000000000000000000000000000000000000000000000000000000000fe``, ``00000000000000000000000000000000000000000000000000000000000000fe``)
|
||||
|
||||
Note that, unlike the new code generator, the old code generator does not perform a cleanup after the bit-not assignment (``_a = ~_a``).
|
||||
This results in different values being assigned (within the inline assembly block) to return value ``_r1`` between the old and new code generators.
|
||||
However, both code generators perform a cleanup before the new value of ``_a`` is assigned to ``_r2``.
|
||||
Note that, unlike the new code generator, the old code generator does not perform a cleanup after the bit-not assignment (``a = ~a``).
|
||||
This results in different values being assigned (within the inline assembly block) to return value ``r1`` between the old and new code generators.
|
||||
However, both code generators perform a cleanup before the new value of ``a`` is assigned to ``r2``.
|
||||
|
@ -210,9 +210,9 @@ using a second proxy:
|
||||
contract ProxyWithMoreFunctionality {
|
||||
PermissionlessProxy proxy;
|
||||
|
||||
function callOther(address _addr, bytes memory _payload) public
|
||||
function callOther(address addr, bytes memory payload) public
|
||||
returns (bool, bytes memory) {
|
||||
return proxy.callOther(_addr, _payload);
|
||||
return proxy.callOther(addr, payload);
|
||||
}
|
||||
// Other functions and other functionality
|
||||
}
|
||||
@ -220,9 +220,9 @@ using a second proxy:
|
||||
// This is the full contract, it has no other functionality and
|
||||
// requires no privileges to work.
|
||||
contract PermissionlessProxy {
|
||||
function callOther(address _addr, bytes memory _payload) public
|
||||
function callOther(address addr, bytes memory payload) public
|
||||
returns (bool, bytes memory) {
|
||||
return _addr.call(_payload);
|
||||
return addr.call(payload);
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,17 +331,17 @@ field of a ``struct`` that is the base type of a dynamic storage array. The
|
||||
contract Map {
|
||||
mapping (uint => uint)[] array;
|
||||
|
||||
function allocate(uint _newMaps) public {
|
||||
for (uint i = 0; i < _newMaps; i++)
|
||||
function allocate(uint newMaps) public {
|
||||
for (uint i = 0; i < newMaps; i++)
|
||||
array.push();
|
||||
}
|
||||
|
||||
function writeMap(uint _map, uint _key, uint _value) public {
|
||||
array[_map][_key] = _value;
|
||||
function writeMap(uint map, uint key, uint value) public {
|
||||
array[map][key] = value;
|
||||
}
|
||||
|
||||
function readMap(uint _map, uint _key) public view returns (uint) {
|
||||
return array[_map][_key];
|
||||
function readMap(uint map, uint key) public view returns (uint) {
|
||||
return array[map][key];
|
||||
}
|
||||
|
||||
function eraseMaps() public {
|
||||
|
@ -82,12 +82,12 @@ Overflow
|
||||
uint immutable x;
|
||||
uint immutable y;
|
||||
|
||||
function add(uint _x, uint _y) internal pure returns (uint) {
|
||||
return _x + _y;
|
||||
function add(uint x_, uint y_) internal pure returns (uint) {
|
||||
return x_ + y_;
|
||||
}
|
||||
|
||||
constructor(uint _x, uint _y) {
|
||||
(x, y) = (_x, _y);
|
||||
constructor(uint x_, uint y_) {
|
||||
(x, y) = (x_, y_);
|
||||
}
|
||||
|
||||
function stateAdd() public view returns (uint) {
|
||||
@ -116,7 +116,7 @@ Here, it reports the following:
|
||||
Overflow.add(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935) -- internal call
|
||||
--> o.sol:9:20:
|
||||
|
|
||||
9 | return _x + _y;
|
||||
9 | return x_ + y_;
|
||||
| ^^^^^^^
|
||||
|
||||
If we add ``require`` statements that filter out overflow cases,
|
||||
@ -131,12 +131,12 @@ the SMTChecker proves that no overflow is reachable (by not reporting warnings):
|
||||
uint immutable x;
|
||||
uint immutable y;
|
||||
|
||||
function add(uint _x, uint _y) internal pure returns (uint) {
|
||||
return _x + _y;
|
||||
function add(uint x_, uint y_) internal pure returns (uint) {
|
||||
return x_ + y_;
|
||||
}
|
||||
|
||||
constructor(uint _x, uint _y) {
|
||||
(x, y) = (_x, _y);
|
||||
constructor(uint x_, uint y_) {
|
||||
(x, y) = (x_, y_);
|
||||
}
|
||||
|
||||
function stateAdd() public view returns (uint) {
|
||||
@ -155,7 +155,7 @@ An assertion represents an invariant in your code: a property that must be true
|
||||
|
||||
The code below defines a function ``f`` that guarantees no overflow.
|
||||
Function ``inv`` defines the specification that ``f`` is monotonically increasing:
|
||||
for every possible pair ``(_a, _b)``, if ``_b > _a`` then ``f(_b) > f(_a)``.
|
||||
for every possible pair ``(a, b)``, if ``b > a`` then ``f(b) > f(a)``.
|
||||
Since ``f`` is indeed monotonically increasing, the SMTChecker proves that our
|
||||
property is correct. You are encouraged to play with the property and the function
|
||||
definition to see what results come out!
|
||||
@ -166,14 +166,14 @@ definition to see what results come out!
|
||||
pragma solidity >=0.8.0;
|
||||
|
||||
contract Monotonic {
|
||||
function f(uint _x) internal pure returns (uint) {
|
||||
require(_x < type(uint128).max);
|
||||
return _x * 42;
|
||||
function f(uint x) internal pure returns (uint) {
|
||||
require(x < type(uint128).max);
|
||||
return x * 42;
|
||||
}
|
||||
|
||||
function inv(uint _a, uint _b) public pure {
|
||||
require(_b > _a);
|
||||
assert(f(_b) > f(_a));
|
||||
function inv(uint a, uint b) public pure {
|
||||
require(b > a);
|
||||
assert(f(b) > f(a));
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,14 +188,14 @@ equal every element in the array.
|
||||
pragma solidity >=0.8.0;
|
||||
|
||||
contract Max {
|
||||
function max(uint[] memory _a) public pure returns (uint) {
|
||||
function max(uint[] memory a) public pure returns (uint) {
|
||||
uint m = 0;
|
||||
for (uint i = 0; i < _a.length; ++i)
|
||||
if (_a[i] > m)
|
||||
m = _a[i];
|
||||
for (uint i = 0; i < a.length; ++i)
|
||||
if (a[i] > m)
|
||||
m = a[i];
|
||||
|
||||
for (uint i = 0; i < _a.length; ++i)
|
||||
assert(m >= _a[i]);
|
||||
for (uint i = 0; i < a.length; ++i)
|
||||
assert(m >= a[i]);
|
||||
|
||||
return m;
|
||||
}
|
||||
@ -222,15 +222,15 @@ For example, changing the code to
|
||||
pragma solidity >=0.8.0;
|
||||
|
||||
contract Max {
|
||||
function max(uint[] memory _a) public pure returns (uint) {
|
||||
require(_a.length >= 5);
|
||||
function max(uint[] memory a) public pure returns (uint) {
|
||||
require(a.length >= 5);
|
||||
uint m = 0;
|
||||
for (uint i = 0; i < _a.length; ++i)
|
||||
if (_a[i] > m)
|
||||
m = _a[i];
|
||||
for (uint i = 0; i < a.length; ++i)
|
||||
if (a[i] > m)
|
||||
m = a[i];
|
||||
|
||||
for (uint i = 0; i < _a.length; ++i)
|
||||
assert(m > _a[i]);
|
||||
for (uint i = 0; i < a.length; ++i)
|
||||
assert(m > a[i]);
|
||||
|
||||
return m;
|
||||
}
|
||||
@ -243,7 +243,7 @@ gives us:
|
||||
Warning: CHC: Assertion violation happens here.
|
||||
Counterexample:
|
||||
|
||||
_a = [0, 0, 0, 0, 0]
|
||||
a = [0, 0, 0, 0, 0]
|
||||
= 0
|
||||
|
||||
Transaction trace:
|
||||
@ -251,7 +251,7 @@ gives us:
|
||||
Test.max([0, 0, 0, 0, 0])
|
||||
--> max.sol:14:4:
|
||||
|
|
||||
14 | assert(m > _a[i]);
|
||||
14 | assert(m > a[i]);
|
||||
|
||||
|
||||
State Properties
|
||||
@ -383,9 +383,9 @@ anything, including reenter the caller contract.
|
||||
|
||||
Unknown immutable unknown;
|
||||
|
||||
constructor(Unknown _u) {
|
||||
require(address(_u) != address(0));
|
||||
unknown = _u;
|
||||
constructor(Unknown u) {
|
||||
require(address(u) != address(0));
|
||||
unknown = u;
|
||||
}
|
||||
|
||||
modifier mutex {
|
||||
@ -395,8 +395,8 @@ anything, including reenter the caller contract.
|
||||
lock = false;
|
||||
}
|
||||
|
||||
function set(uint _x) mutex public {
|
||||
x = _x;
|
||||
function set(uint x_) mutex public {
|
||||
x = x_;
|
||||
}
|
||||
|
||||
function run() mutex public {
|
||||
@ -754,15 +754,15 @@ not mean loss of proving power.
|
||||
{
|
||||
function f(
|
||||
bytes32 hash,
|
||||
uint8 _v1, uint8 _v2,
|
||||
bytes32 _r1, bytes32 _r2,
|
||||
bytes32 _s1, bytes32 _s2
|
||||
uint8 v1, uint8 v2,
|
||||
bytes32 r1, bytes32 r2,
|
||||
bytes32 s1, bytes32 s2
|
||||
) public pure returns (address) {
|
||||
address a1 = ecrecover(hash, _v1, _r1, _s1);
|
||||
require(_v1 == _v2);
|
||||
require(_r1 == _r2);
|
||||
require(_s1 == _s2);
|
||||
address a2 = ecrecover(hash, _v2, _r2, _s2);
|
||||
address a1 = ecrecover(hash, v1, r1, s1);
|
||||
require(v1 == v2);
|
||||
require(r1 == r2);
|
||||
require(s1 == s2);
|
||||
address a2 = ecrecover(hash, v2, r2, s2);
|
||||
assert(a1 == a2);
|
||||
return a1;
|
||||
}
|
||||
|
@ -4,12 +4,12 @@
|
||||
Mapping Types
|
||||
=============
|
||||
|
||||
Mapping types use the syntax ``mapping(_KeyType => _ValueType)`` and variables
|
||||
of mapping type are declared using the syntax ``mapping(_KeyType => _ValueType) _VariableName``.
|
||||
The ``_KeyType`` can be any
|
||||
Mapping types use the syntax ``mapping(KeyType => ValueType)`` and variables
|
||||
of mapping type are declared using the syntax ``mapping(KeyType => ValueType) VariableName``.
|
||||
The ``KeyType`` can be any
|
||||
built-in value type, ``bytes``, ``string``, or any contract or enum type. Other user-defined
|
||||
or complex types, such as mappings, structs or array types are not allowed.
|
||||
``_ValueType`` can be any type, including mappings, arrays and structs.
|
||||
``ValueType`` can be any type, including mappings, arrays and structs.
|
||||
|
||||
You can think of mappings as `hash tables <https://en.wikipedia.org/wiki/Hash_table>`_, which are virtually initialised
|
||||
such that every possible key exists and is mapped to a value whose
|
||||
@ -29,10 +29,10 @@ of contract functions that are publicly visible.
|
||||
These restrictions are also true for arrays and structs that contain mappings.
|
||||
|
||||
You can mark state variables of mapping type as ``public`` and Solidity creates a
|
||||
:ref:`getter <visibility-and-getters>` for you. The ``_KeyType`` becomes a parameter for the getter.
|
||||
If ``_ValueType`` is a value type or a struct, the getter returns ``_ValueType``.
|
||||
If ``_ValueType`` is an array or a mapping, the getter has one parameter for
|
||||
each ``_KeyType``, recursively.
|
||||
:ref:`getter <visibility-and-getters>` for you. The ``KeyType`` becomes a parameter for the getter.
|
||||
If ``ValueType`` is a value type or a struct, the getter returns ``ValueType``.
|
||||
If ``ValueType`` is an array or a mapping, the getter has one parameter for
|
||||
each ``KeyType``, recursively.
|
||||
|
||||
In the example below, the ``MappingExample`` contract defines a public ``balances``
|
||||
mapping, with the key type an ``address``, and a value type a ``uint``, mapping
|
||||
|
@ -511,21 +511,21 @@ Array slices are useful to ABI-decode secondary data passed in function paramete
|
||||
/// @dev Address of the client contract managed by proxy i.e., this contract
|
||||
address client;
|
||||
|
||||
constructor(address _client) {
|
||||
client = _client;
|
||||
constructor(address client_) {
|
||||
client = client_;
|
||||
}
|
||||
|
||||
/// Forward call to "setOwner(address)" that is implemented by client
|
||||
/// after doing basic validation on the address argument.
|
||||
function forward(bytes calldata _payload) external {
|
||||
bytes4 sig = bytes4(_payload[:4]);
|
||||
// Due to truncating behaviour, bytes4(_payload) performs identically.
|
||||
// bytes4 sig = bytes4(_payload);
|
||||
function forward(bytes calldata payload) external {
|
||||
bytes4 sig = bytes4(payload[:4]);
|
||||
// Due to truncating behaviour, bytes4(payload) performs identically.
|
||||
// bytes4 sig = bytes4(payload);
|
||||
if (sig == bytes4(keccak256("setOwner(address)"))) {
|
||||
address owner = abi.decode(_payload[4:], (address));
|
||||
address owner = abi.decode(payload[4:], (address));
|
||||
require(owner != address(0), "Address of owner cannot be zero.");
|
||||
}
|
||||
(bool status,) = client.delegatecall(_payload);
|
||||
(bool status,) = client.delegatecall(payload);
|
||||
require(status, "Forwarded call failed.");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user