diff --git a/Changelog.md b/Changelog.md index bc7b5b8d0..90ebf4bad 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Language Features: Compiler Features: + * ABI Output: Change sorting order of functions from selector to kind, name. * Optimizer: Add rule that replaces the BYTE opcode by 0 if the first argument is larger than 31. * Yul Optimizer: Take side-effect-freeness of user-defined functions into account. diff --git a/libsolidity/interface/ABI.cpp b/libsolidity/interface/ABI.cpp index 5001620f9..a21053d9f 100644 --- a/libsolidity/interface/ABI.cpp +++ b/libsolidity/interface/ABI.cpp @@ -40,7 +40,10 @@ bool anyDataStoredInStorage(TypePointers const& _pointers) Json::Value ABI::generate(ContractDefinition const& _contractDef) { - Json::Value abi(Json::arrayValue); + auto compare = [](Json::Value const& _a, Json::Value const& _b) -> bool { + return make_tuple(_a["type"], _a["name"]) < make_tuple(_b["type"], _b["name"]); + }; + multiset abi(compare); for (auto it: _contractDef.interfaceFunctions()) { @@ -71,7 +74,7 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef) it.second->returnParameterTypes(), _contractDef.isLibrary() ); - abi.append(std::move(method)); + abi.emplace(std::move(method)); } if (_contractDef.constructor()) { @@ -88,7 +91,7 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef) constrType.parameterTypes(), _contractDef.isLibrary() ); - abi.append(std::move(method)); + abi.emplace(std::move(method)); } if (_contractDef.fallbackFunction()) { @@ -98,7 +101,7 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef) method["type"] = "fallback"; method["payable"] = externalFunctionType->isPayable(); method["stateMutability"] = stateMutabilityToString(externalFunctionType->stateMutability()); - abi.append(std::move(method)); + abi.emplace(std::move(method)); } for (auto const& it: _contractDef.interfaceEvents()) { @@ -117,10 +120,13 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef) params.append(std::move(param)); } event["inputs"] = std::move(params); - abi.append(std::move(event)); + abi.emplace(std::move(event)); } - return abi; + Json::Value abiJson{Json::arrayValue}; + for (auto& f: abi) + abiJson.append(std::move(f)); + return abiJson; } Json::Value ABI::formatTypeList( diff --git a/test/libsolidity/ABIJson/events.sol b/test/libsolidity/ABIJson/events.sol index 287a0298f..1988e094b 100644 --- a/test/libsolidity/ABIJson/events.sol +++ b/test/libsolidity/ABIJson/events.sol @@ -9,29 +9,6 @@ contract test { // :test // [ // { -// "constant": false, -// "inputs": -// [ -// { -// "internalType": "uint256", -// "name": "a", -// "type": "uint256" -// } -// ], -// "name": "f", -// "outputs": -// [ -// { -// "internalType": "uint256", -// "name": "d", -// "type": "uint256" -// } -// ], -// "payable": false, -// "stateMutability": "nonpayable", -// "type": "function" -// }, -// { // "anonymous": false, // "inputs": // [ @@ -76,5 +53,28 @@ contract test { // "inputs": [], // "name": "e3", // "type": "event" +// }, +// { +// "constant": false, +// "inputs": +// [ +// { +// "internalType": "uint256", +// "name": "a", +// "type": "uint256" +// } +// ], +// "name": "f", +// "outputs": +// [ +// { +// "internalType": "uint256", +// "name": "d", +// "type": "uint256" +// } +// ], +// "payable": false, +// "stateMutability": "nonpayable", +// "type": "function" // } // ] diff --git a/test/libsolidity/ABIJson/inherited.sol b/test/libsolidity/ABIJson/inherited.sol index 5d61f4aef..00abd50ef 100644 --- a/test/libsolidity/ABIJson/inherited.sol +++ b/test/libsolidity/ABIJson/inherited.sol @@ -10,6 +10,20 @@ contract Derived is Base { // :Base // [ // { +// "anonymous": false, +// "inputs": +// [ +// { +// "indexed": true, +// "internalType": "bytes32", +// "name": "evtArgBase", +// "type": "bytes32" +// } +// ], +// "name": "baseEvent", +// "type": "event" +// }, +// { // "constant": false, // "inputs": // [ @@ -31,7 +45,12 @@ contract Derived is Base { // "payable": false, // "stateMutability": "nonpayable", // "type": "function" -// }, +// } +// ] +// +// +// :Derived +// [ // { // "anonymous": false, // "inputs": @@ -45,12 +64,21 @@ contract Derived is Base { // ], // "name": "baseEvent", // "type": "event" -// } -// ] -// -// -// :Derived -// [ +// }, +// { +// "anonymous": false, +// "inputs": +// [ +// { +// "indexed": true, +// "internalType": "uint256", +// "name": "evtArgDerived", +// "type": "uint256" +// } +// ], +// "name": "derivedEvent", +// "type": "event" +// }, // { // "constant": false, // "inputs": @@ -96,33 +124,5 @@ contract Derived is Base { // "payable": false, // "stateMutability": "nonpayable", // "type": "function" -// }, -// { -// "anonymous": false, -// "inputs": -// [ -// { -// "indexed": true, -// "internalType": "uint256", -// "name": "evtArgDerived", -// "type": "uint256" -// } -// ], -// "name": "derivedEvent", -// "type": "event" -// }, -// { -// "anonymous": false, -// "inputs": -// [ -// { -// "indexed": true, -// "internalType": "bytes32", -// "name": "evtArgBase", -// "type": "bytes32" -// } -// ], -// "name": "baseEvent", -// "type": "event" // } // ] diff --git a/test/libsolidity/ABIJson/pure_function.sol b/test/libsolidity/ABIJson/pure_function.sol index f1279ab3d..072b8f1f9 100644 --- a/test/libsolidity/ABIJson/pure_function.sol +++ b/test/libsolidity/ABIJson/pure_function.sol @@ -6,6 +6,29 @@ contract test { // :test // [ // { +// "constant": true, +// "inputs": +// [ +// { +// "internalType": "uint32", +// "name": "a", +// "type": "uint32" +// } +// ], +// "name": "boo", +// "outputs": +// [ +// { +// "internalType": "uint256", +// "name": "b", +// "type": "uint256" +// } +// ], +// "payable": false, +// "stateMutability": "pure", +// "type": "function" +// }, +// { // "constant": false, // "inputs": // [ @@ -32,28 +55,5 @@ contract test { // "payable": false, // "stateMutability": "nonpayable", // "type": "function" -// }, -// { -// "constant": true, -// "inputs": -// [ -// { -// "internalType": "uint32", -// "name": "a", -// "type": "uint32" -// } -// ], -// "name": "boo", -// "outputs": -// [ -// { -// "internalType": "uint256", -// "name": "b", -// "type": "uint256" -// } -// ], -// "payable": false, -// "stateMutability": "pure", -// "type": "function" // } // ] diff --git a/test/libsolidity/ABIJson/return_param_in_abi.sol b/test/libsolidity/ABIJson/return_param_in_abi.sol index 835a88a7b..2618e9ed2 100644 --- a/test/libsolidity/ABIJson/return_param_in_abi.sol +++ b/test/libsolidity/ABIJson/return_param_in_abi.sol @@ -11,6 +11,19 @@ contract test { // :test // [ // { +// "inputs": +// [ +// { +// "internalType": "enum test.ActionChoices", +// "name": "param", +// "type": "uint8" +// } +// ], +// "payable": false, +// "stateMutability": "nonpayable", +// "type": "constructor" +// }, +// { // "constant": false, // "inputs": [], // "name": "ret", @@ -25,18 +38,5 @@ contract test { // "payable": false, // "stateMutability": "nonpayable", // "type": "function" -// }, -// { -// "inputs": -// [ -// { -// "internalType": "enum test.ActionChoices", -// "name": "param", -// "type": "uint8" -// } -// ], -// "payable": false, -// "stateMutability": "nonpayable", -// "type": "constructor" // } // ] diff --git a/test/libsolidity/ABIJson/view_function.sol b/test/libsolidity/ABIJson/view_function.sol index 6112574d5..0c55b6e6e 100644 --- a/test/libsolidity/ABIJson/view_function.sol +++ b/test/libsolidity/ABIJson/view_function.sol @@ -6,6 +6,29 @@ contract test { // :test // [ // { +// "constant": true, +// "inputs": +// [ +// { +// "internalType": "uint32", +// "name": "a", +// "type": "uint32" +// } +// ], +// "name": "boo", +// "outputs": +// [ +// { +// "internalType": "uint256", +// "name": "b", +// "type": "uint256" +// } +// ], +// "payable": false, +// "stateMutability": "view", +// "type": "function" +// }, +// { // "constant": false, // "inputs": // [ @@ -32,28 +55,5 @@ contract test { // "payable": false, // "stateMutability": "nonpayable", // "type": "function" -// }, -// { -// "constant": true, -// "inputs": -// [ -// { -// "internalType": "uint32", -// "name": "a", -// "type": "uint32" -// } -// ], -// "name": "boo", -// "outputs": -// [ -// { -// "internalType": "uint256", -// "name": "b", -// "type": "uint256" -// } -// ], -// "payable": false, -// "stateMutability": "view", -// "type": "function" // } // ]