Fix bug in handling 2-dimensional arrays of user defined data types in generated Python code.
282 lines
7.4 KiB
Solidity
282 lines
7.4 KiB
Solidity
/*
|
|
|
|
Copyright 2019 ZeroEx Intl.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
pragma experimental ABIEncoderV2;
|
|
|
|
pragma solidity ^0.5.5;
|
|
|
|
|
|
contract AbiGenDummy
|
|
{
|
|
|
|
uint256 constant internal SOME_CONSTANT = 1234;
|
|
string constant internal REVERT_REASON = "REVERT_WITH_CONSTANT";
|
|
string constant internal REQUIRE_REASON = "REQUIRE_WITH_CONSTANT";
|
|
|
|
function simplePureFunction ()
|
|
public
|
|
pure
|
|
returns (uint256 result)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
function simplePureFunctionWithInput (uint256 x)
|
|
public
|
|
pure
|
|
returns (uint256 sum)
|
|
{
|
|
return 1 + x;
|
|
}
|
|
|
|
function pureFunctionWithConstant ()
|
|
public
|
|
pure
|
|
returns (uint256 someConstant)
|
|
{
|
|
return SOME_CONSTANT;
|
|
}
|
|
|
|
function simpleRevert ()
|
|
public
|
|
pure
|
|
{
|
|
revert("SIMPLE_REVERT");
|
|
}
|
|
|
|
function revertWithConstant ()
|
|
public
|
|
pure
|
|
{
|
|
revert(REVERT_REASON);
|
|
}
|
|
|
|
function simpleRequire ()
|
|
public
|
|
pure
|
|
{
|
|
require(0 > 1, "SIMPLE_REQUIRE");
|
|
}
|
|
|
|
function requireWithConstant ()
|
|
public
|
|
pure
|
|
{
|
|
require(0 > 1, REQUIRE_REASON);
|
|
}
|
|
|
|
/// @dev test that devdocs will be generated and
|
|
/// that multiline devdocs will look okay
|
|
/// @param hash description of some hash. Let's make this line super long to demonstrate hanging indents for method params. It has to be more than one hundred twenty columns.
|
|
/// @param v some v, recovery id
|
|
/// @param r ECDSA r output
|
|
/// @param s ECDSA s output
|
|
/// @return the signerAddress that created this signature. this line too is super long in order to demonstrate the proper hanging indentation in generated code.
|
|
function ecrecoverFn(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
|
|
public
|
|
pure
|
|
returns (address signerAddress)
|
|
{
|
|
bytes memory prefix = "\x19Ethereum Signed Message:\n32";
|
|
bytes32 prefixedHash = keccak256(abi.encodePacked(prefix, hash));
|
|
return ecrecover(prefixedHash, v, r, s);
|
|
}
|
|
|
|
// test: generated code should normalize address inputs to lowercase
|
|
// add extra inputs to make sure it works with address in any position
|
|
function withAddressInput(address x, uint256 a, uint256 b, address y, uint256 c)
|
|
public
|
|
pure
|
|
returns (address z)
|
|
{
|
|
return x;
|
|
}
|
|
|
|
function acceptsBytes(bytes memory a) public pure {}
|
|
|
|
/// @dev a method that accepts an array of bytes
|
|
/// @param a the array of bytes being accepted
|
|
function acceptsAnArrayOfBytes(bytes[] memory a) public pure {}
|
|
|
|
struct Struct {
|
|
bytes someBytes;
|
|
uint32 anInteger;
|
|
bytes[] aDynamicArrayOfBytes;
|
|
string aString;
|
|
}
|
|
|
|
function structInput(Struct memory s) public pure {}
|
|
|
|
/// @dev a method that returns a struct
|
|
/// @return a Struct struct
|
|
function structOutput() public pure returns(Struct memory s) {
|
|
bytes[] memory byteArray = new bytes[](2);
|
|
byteArray[0] = "0x123";
|
|
byteArray[1] = "0x321";
|
|
|
|
return Struct({
|
|
someBytes: "0x123",
|
|
anInteger: 5,
|
|
aDynamicArrayOfBytes: byteArray,
|
|
aString: "abc"
|
|
});
|
|
}
|
|
|
|
function methodReturningArrayOfStructs() public pure returns(Struct[] memory) {}
|
|
function methodAcceptingArrayOfStructs(Struct[] memory) public pure {}
|
|
function methodAcceptingArrayOfArrayOfStructs(Struct[][] memory) public pure {}
|
|
|
|
struct NestedStruct {
|
|
Struct innerStruct;
|
|
string description;
|
|
}
|
|
|
|
function nestedStructInput(NestedStruct memory n) public pure {}
|
|
function nestedStructOutput() public pure returns(NestedStruct memory) {}
|
|
|
|
struct StructNotDirectlyUsedAnywhere {
|
|
uint256 aField;
|
|
}
|
|
|
|
struct NestedStructWithInnerStructNotUsedElsewhere {
|
|
StructNotDirectlyUsedAnywhere innerStruct;
|
|
}
|
|
|
|
function methodUsingNestedStructWithInnerStructNotUsedElsewhere()
|
|
public pure returns(NestedStructWithInnerStructNotUsedElsewhere memory)
|
|
{}
|
|
|
|
uint someState;
|
|
function nonPureMethod() public returns(uint) { return someState += 1; }
|
|
function nonPureMethodThatReturnsNothing() public { someState += 1; }
|
|
|
|
function methodReturningMultipleValues()
|
|
public pure returns (uint256, string memory)
|
|
{
|
|
return (1, "hello");
|
|
}
|
|
|
|
function overloadedMethod(int a) public pure {}
|
|
function overloadedMethod(string memory a) public pure {}
|
|
|
|
|
|
event Withdrawal(address indexed _owner, uint _value);
|
|
|
|
function withdraw(uint wad) public {
|
|
emit Withdrawal(msg.sender, wad);
|
|
}
|
|
|
|
event SimpleEvent(bytes someBytes, string someString);
|
|
|
|
function emitSimpleEvent() public {
|
|
emit SimpleEvent(
|
|
hex'12345678',
|
|
"lorem"
|
|
);
|
|
}
|
|
|
|
// begin tests for `decodeTransactionData`, `decodeReturnData`
|
|
/// @dev complex input is dynamic and more difficult to decode than simple input.
|
|
struct ComplexInput {
|
|
uint256 foo;
|
|
bytes bar;
|
|
string car;
|
|
}
|
|
|
|
/// @dev complex input is dynamic and more difficult to decode than simple input.
|
|
struct ComplexOutput {
|
|
ComplexInput input;
|
|
bytes lorem;
|
|
bytes ipsum;
|
|
string dolor;
|
|
}
|
|
|
|
/// @dev Tests decoding when both input and output are empty.
|
|
function noInputNoOutput()
|
|
public
|
|
pure
|
|
{
|
|
// NOP
|
|
require(true == true);
|
|
}
|
|
|
|
/// @dev Tests decoding when input is empty and output is non-empty.
|
|
function noInputSimpleOutput()
|
|
public
|
|
pure
|
|
returns (uint256)
|
|
{
|
|
return 1991;
|
|
}
|
|
|
|
/// @dev Tests decoding when input is not empty but output is empty.
|
|
function simpleInputNoOutput(uint256)
|
|
public
|
|
pure
|
|
{
|
|
// NOP
|
|
require(true == true);
|
|
}
|
|
|
|
/// @dev Tests decoding when both input and output are non-empty.
|
|
function simpleInputSimpleOutput(uint256)
|
|
public
|
|
pure
|
|
returns (uint256)
|
|
{
|
|
return 1991;
|
|
}
|
|
|
|
/// @dev Tests decoding when the input and output are complex.
|
|
function complexInputComplexOutput(ComplexInput memory complexInput)
|
|
public
|
|
pure
|
|
returns (ComplexOutput memory)
|
|
{
|
|
return ComplexOutput({
|
|
input: complexInput,
|
|
lorem: hex'12345678',
|
|
ipsum: hex'87654321',
|
|
dolor: "amet"
|
|
});
|
|
}
|
|
|
|
/// @dev Tests decoding when the input and output are complex and have more than one argument.
|
|
function multiInputMultiOutput(
|
|
uint256,
|
|
bytes memory,
|
|
string memory
|
|
)
|
|
public
|
|
pure
|
|
returns (
|
|
bytes memory,
|
|
bytes memory,
|
|
string memory
|
|
)
|
|
{
|
|
return (
|
|
hex'12345678',
|
|
hex'87654321',
|
|
"amet"
|
|
);
|
|
}
|
|
|
|
// end tests for `decodeTransactionData`, `decodeReturnData`
|
|
}
|