mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Implement ABI encoding of calldata arrays and structs.
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function g(uint256[] calldata) external pure returns (bytes memory) {
|
||||
return msg.data;
|
||||
}
|
||||
function f(uint256[][1] calldata s) external view returns (bool) {
|
||||
bytes memory a = this.g(s[0]);
|
||||
uint256[] memory m = s[0];
|
||||
bytes memory b = this.g(m);
|
||||
assert(a.length == b.length);
|
||||
for (uint i = 0; i < a.length; i++)
|
||||
assert(a[i] == b[i]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// f(uint256[][1]): 32, 32, 0 -> true
|
||||
// f(uint256[][1]): 32, 32, 1, 42 -> true
|
||||
// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true
|
||||
@@ -0,0 +1,33 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f(uint256[] calldata s) external pure returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
function g(uint256[] calldata s) external view returns (bytes memory) {
|
||||
return this.f(s);
|
||||
}
|
||||
function h(uint8[] calldata s) external pure returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
function i(uint8[] calldata s) external view returns (bytes memory) {
|
||||
return this.h(s);
|
||||
}
|
||||
function j(bytes calldata s) external pure returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
function k(bytes calldata s) external view returns (bytes memory) {
|
||||
return this.j(s);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87
|
||||
// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87
|
||||
// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87
|
||||
// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87
|
||||
// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE
|
||||
// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE
|
||||
// j(bytes): 32, 3, hex"123456" -> 32, 96, 32, 3, left(0x123456)
|
||||
// k(bytes): 32, 3, hex"AB33FF" -> 32, 96, 32, 3, left(0xAB33FF)
|
||||
@@ -0,0 +1,34 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f(uint256[] calldata s) external pure returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {
|
||||
return this.f(s[which]);
|
||||
}
|
||||
function h(uint8[] calldata s) external pure returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {
|
||||
return this.h(s[which]);
|
||||
}
|
||||
function j(bytes calldata s) external pure returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {
|
||||
return this.j(s[which]);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87
|
||||
// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87
|
||||
// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27
|
||||
// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87
|
||||
// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87
|
||||
// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27
|
||||
// j(bytes): 32, 3, hex"AB11FF" -> 32, 96, 32, 3, left(0xAB11FF)
|
||||
// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex"AB11FF", 4, hex"FF791432" -> 32, 96, 32, 3, left(0xAB11FF)
|
||||
// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex"AB11FF", 4, hex"FF791432" -> 32, 96, 32, 4, left(0xFF791432)
|
||||
@@ -0,0 +1,49 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f(uint8[][1][] calldata s) external pure returns (bytes memory) {
|
||||
return msg.data;
|
||||
}
|
||||
function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {
|
||||
return msg.data;
|
||||
}
|
||||
function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {
|
||||
return this.f(s);
|
||||
}
|
||||
function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {
|
||||
return this.f2(s);
|
||||
}
|
||||
function g() external returns (bytes memory) {
|
||||
uint8[][1][] memory m = new uint8[][1][](1);
|
||||
m[0][0] = new uint8[](1);
|
||||
m[0][0][0] = 42;
|
||||
return this.f(m);
|
||||
}
|
||||
function h() external returns (bytes memory) {
|
||||
uint8[][1][] memory m = new uint8[][1][](1);
|
||||
m[0][0] = new uint8[](1);
|
||||
m[0][0][0] = 42;
|
||||
return this.reenc_f(m);
|
||||
}
|
||||
function i() external returns (bytes memory) {
|
||||
uint256[][2][] memory m = new uint256[][2][](1);
|
||||
m[0][0] = new uint256[](1);
|
||||
m[0][1] = new uint256[](1);
|
||||
m[0][0][0] = 42;
|
||||
m[0][1][0] = 42;
|
||||
return this.f2(m);
|
||||
}
|
||||
function j() external returns (bytes memory) {
|
||||
uint256[][2][] memory m = new uint256[][2][](1);
|
||||
m[0][0] = new uint256[](1);
|
||||
m[0][1] = new uint256[](1);
|
||||
m[0][0][0] = 42;
|
||||
m[0][1][0] = 42;
|
||||
return this.reenc_f2(m);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// g() -> 32, 196, hex"eccb829a", 32, 1, 32, 32, 1, 42, hex"00000000000000000000000000000000000000000000000000000000"
|
||||
// h() -> 32, 196, hex"eccb829a", 32, 1, 32, 32, 1, 42, hex"00000000000000000000000000000000000000000000000000000000"
|
||||
@@ -0,0 +1,30 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {
|
||||
assert(s.length == 3);
|
||||
return (s[0](), s[1](), s[2]());
|
||||
}
|
||||
function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {
|
||||
return this.f(s);
|
||||
}
|
||||
function getter1() external returns (uint) {
|
||||
return 23;
|
||||
}
|
||||
function getter2() external returns (uint) {
|
||||
return 37;
|
||||
}
|
||||
function getter3() external returns (uint) {
|
||||
return 71;
|
||||
}
|
||||
function g(bool reenc) external returns (uint, uint, uint) {
|
||||
function() external returns (uint)[] memory a = new function() external returns (uint)[](3);
|
||||
a[0] = this.getter1;
|
||||
a[1] = this.getter2;
|
||||
a[2] = this.getter3;
|
||||
return reenc ? this.f_reenc(a) : this.f(a);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// g(bool): false -> 23, 37, 71
|
||||
// g(bool): true -> 23, 37, 71
|
||||
@@ -0,0 +1,31 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f(uint256[][] calldata s) external pure returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
function g(uint256[][] calldata s) external view returns (bytes memory) {
|
||||
return this.f(s);
|
||||
}
|
||||
function h(uint8[][] calldata s) external pure returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
function i(uint8[][] calldata s) external view returns (bytes memory) {
|
||||
return this.h(s);
|
||||
}
|
||||
function j(bytes[] calldata s) external pure returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
function k(bytes[] calldata s) external view returns (bytes memory) {
|
||||
return this.j(s);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// f(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41
|
||||
// g(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41
|
||||
// h(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41
|
||||
// i(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41
|
||||
// j(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex"131723", 4, hex"27313741" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)
|
||||
// k(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex"131723", 4, hex"27313741" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)
|
||||
@@ -0,0 +1,25 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f(uint256[3] calldata s) external pure returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
function g(uint256[3] calldata s) external view returns (bytes memory) {
|
||||
return this.f(s);
|
||||
}
|
||||
function h(uint8[3] calldata s) external pure returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
function i(uint8[3] calldata s) external view returns (bytes memory) {
|
||||
return this.h(s);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87
|
||||
// g(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87
|
||||
// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87
|
||||
// i(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87
|
||||
// h(uint8[3]): 0xFF23, 0x1242, 0xAB87 -> FAILURE
|
||||
// i(uint8[3]): 0xAB23, 0x1242, 0xFF87 -> FAILURE
|
||||
@@ -0,0 +1,49 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {
|
||||
return msg.data;
|
||||
}
|
||||
function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {
|
||||
return msg.data;
|
||||
}
|
||||
function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {
|
||||
return this.f(s);
|
||||
}
|
||||
function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {
|
||||
return this.f2(s);
|
||||
}
|
||||
function g() external returns (bytes memory) {
|
||||
uint8[1][][1] memory m = [new uint8[1][](1)];
|
||||
m[0][0][0] = 42;
|
||||
return this.f(m);
|
||||
}
|
||||
function h() external returns (bytes memory) {
|
||||
uint8[1][][1] memory m = [new uint8[1][](1)];
|
||||
m[0][0][0] = 42;
|
||||
return this.reenc_f(m);
|
||||
}
|
||||
function i() external returns (bytes memory) {
|
||||
uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];
|
||||
m[0][0][0] = 0x00042;
|
||||
m[0][0][1] = 0x00142;
|
||||
m[1][0][0] = 0x10042;
|
||||
m[1][0][1] = 0x10142;
|
||||
return this.f2(m);
|
||||
}
|
||||
function j() external returns (bytes memory) {
|
||||
uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];
|
||||
m[0][0][0] = 0x00042;
|
||||
m[0][0][1] = 0x00142;
|
||||
m[1][0][0] = 0x10042;
|
||||
m[1][0][1] = 0x10142;
|
||||
return this.reenc_f2(m);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// g() -> 32, 132, hex"15cfcc01", 32, 32, 1, 42, hex"00000000000000000000000000000000000000000000000000000000"
|
||||
// h() -> 32, 132, hex"15cfcc01", 32, 32, 1, 42, hex"00000000000000000000000000000000000000000000000000000000"
|
||||
// i() -> 32, 292, hex"dc0ee233", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex"00000000000000000000000000000000000000000000000000000000"
|
||||
// j() -> 32, 292, hex"dc0ee233", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex"00000000000000000000000000000000000000000000000000000000"
|
||||
@@ -0,0 +1,25 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f(uint256[3] calldata s) external pure returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {
|
||||
return this.f(s[which]);
|
||||
}
|
||||
function h(uint8[3] calldata s) external pure returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {
|
||||
return this.h(s[which]);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87
|
||||
// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87
|
||||
// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187
|
||||
// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87
|
||||
// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87
|
||||
// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187
|
||||
@@ -0,0 +1,16 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct S { uint256[] a; }
|
||||
function f(S[] calldata s) external pure returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
function g(S[] calldata s) external view returns (bytes memory) {
|
||||
return this.f(s);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23
|
||||
// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23
|
||||
@@ -0,0 +1,20 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {
|
||||
if (which)
|
||||
return abi.encode(s1);
|
||||
else
|
||||
return abi.encode(s2);
|
||||
}
|
||||
function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {
|
||||
return this.f(s1, s2, which);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87
|
||||
// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72
|
||||
// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87
|
||||
// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72
|
||||
@@ -0,0 +1,20 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {
|
||||
if (which)
|
||||
return abi.encode(s1);
|
||||
else
|
||||
return abi.encode(s2);
|
||||
}
|
||||
function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {
|
||||
return this.f(s1, s2, which);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87
|
||||
// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72
|
||||
// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87
|
||||
// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72
|
||||
@@ -0,0 +1,18 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct S { uint256[] a; }
|
||||
|
||||
function f(S calldata s) external returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
|
||||
function g(S calldata s) external returns (bytes memory) {
|
||||
return this.f(s);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17
|
||||
// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17
|
||||
@@ -0,0 +1,18 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract C {
|
||||
struct S { uint256 a; }
|
||||
|
||||
function f(S calldata s) external returns (bytes memory) {
|
||||
return abi.encode(s);
|
||||
}
|
||||
|
||||
function g(S calldata s) external returns (bytes memory) {
|
||||
return this.f(s);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >homestead
|
||||
// ----
|
||||
// f((uint256)): 3 -> 32, 32, 3
|
||||
// g((uint256)): 3 -> 32, 32, 3
|
||||
Reference in New Issue
Block a user