Added support for legacy ABI JSON fragments (#3932).

This commit is contained in:
Richard Moore 2023-04-06 04:25:54 -04:00
parent e4e951124f
commit 8c5973e3a9
2 changed files with 161 additions and 2 deletions

@ -136,3 +136,142 @@ describe("Test Interface", function() {
assert.equal(log.args[2], BigInt(234));
});
});
describe("Tests Legacy ABI formats", function() {
// See: #3932
const iface = new Interface([
{
name: "implicitView",
outputs: [ ],
inputs: [
{ type: "int128", name: "arg0" }
],
"constant": true,
"payable": false,
"type": "function"
},
{
name: "implicitSendNonpay",
outputs: [ ],
inputs: [
{ type: "int128", name: "arg0" }
],
"constant": false,
"payable": false,
"type": "function"
},
{
name: "implicitSendPay",
outputs: [ ],
inputs: [
{ type: "int128", name: "arg0" }
],
"constant": false,
"payable": true,
"type": "function"
},
{
name: "implicitSendImplicitPay",
outputs: [ ],
inputs: [
{ type: "int128", name: "arg0" }
],
"constant": false,
"type": "function"
},
{
name: "implicitSendExplicitPay",
outputs: [ ],
inputs: [
{ type: "int128", name: "arg0" }
],
payable: true,
type: "function"
},
{
name: "implicitSendExplicitNonpay",
outputs: [ ],
inputs: [
{ type: "int128", name: "arg0" }
],
payable: false,
type: "function"
},
{
name: "implicitAll",
outputs: [ ],
inputs: [
{ type: "int128", name: "arg0" }
],
"type": "function"
},
{
name: "explicitView",
outputs: [ ],
inputs: [
{ type: "int128", name: "arg0" }
],
"stateMutability": "view",
"constant": true,
"payable": false,
"type": "function"
},
{
name: "explicitPure",
outputs: [ ],
inputs: [
{ type: "int128", name: "arg0" }
],
"stateMutability": "pure",
"constant": true,
"payable": false,
"type": "function"
},
{
name: "explicitPay",
outputs: [ ],
inputs: [
{ type: "int128", name: "arg0" }
],
"stateMutability": "payable",
"constant": true,
"payable": true,
"type": "function"
},
{
name: "explicitNonpay",
outputs: [ ],
inputs: [
{ type: "int128", name: "arg0" }
],
"stateMutability": "nonpayable",
"constant": true,
"payable": false,
"type": "function"
},
]);
function test(name: string, isConst: boolean, payable: boolean, stateMutability: string): void {
it(`tests ABI configuration: ${ name }`, function() {
const f = iface.getFunction(name);
assert.ok(!!f, `missing ${ name }`);
assert.equal(f.constant, isConst, `${ name }.constant`);
assert.equal(f.stateMutability, stateMutability, `${ name }.stateMutability`);
assert.equal(f.payable, payable, `${ name }.payable`);
});
}
test("explicitView", true, false, "view");
test("explicitPure", true, false, "pure");
test("explicitPay", false, true, "payable");
test("explicitNonpay", false, false, "nonpayable");
test("implicitView", true, false, "view");
test("implicitSendNonpay", false, false, "nonpayable");
test("implicitSendPay", false, true, "payable");
test("implicitSendImplicitPay", false, true, "payable");
test("implicitSendExplicitPay", false, true, "payable");
test("implicitSendExplicitNonpay", false, false, "nonpayable");
test("implicitAll", false, true, "payable");
});

@ -1430,9 +1430,29 @@ export class FunctionFragment extends NamedFragment {
return new FunctionFragment(_guard, name, mutability, inputs, outputs, gas);
}
// @TODO: verifyState for stateMutability
let stateMutability = obj.stateMutability;
return new FunctionFragment(_guard, obj.name, obj.stateMutability,
// Use legacy Solidity ABI logic if stateMutability is missing
if (stateMutability == null) {
stateMutability = "payable";
if (typeof(obj.constant) === "boolean") {
stateMutability = "view";
if (!obj.constant) {
stateMutability = "payable"
if (typeof(obj.payable) === "boolean" && !obj.payable) {
stateMutability = "nonpayable";
}
}
} else if (typeof(obj.payable) === "boolean" && !obj.payable) {
stateMutability = "nonpayable";
}
}
// @TODO: verifyState for stateMutability (e.g. throw if
// payable: false but stateMutability is "nonpayable")
return new FunctionFragment(_guard, obj.name, stateMutability,
obj.inputs ? obj.inputs.map(ParamType.from): [ ],
obj.outputs ? obj.outputs.map(ParamType.from): [ ],
(obj.gas != null) ? obj.gas: null);