Skip to content

Commit df93010

Browse files
committed
Fixed ABIv2 signatures for calling methods.
1 parent d6cf970 commit df93010

File tree

5 files changed

+84
-2
lines changed

5 files changed

+84
-2
lines changed

contracts/interface.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,10 @@ function Interface(abi) {
614614
var outputNames = outputParams.names;
615615
}
616616

617-
var signature = method.name + '(' + inputParams.types.join(',') + ')';
617+
var signature = '(' + inputParams.types.join(',') + ')';
618+
signature = signature.replace(/tuple/g, '');
619+
signature = method.name + signature;
620+
618621
var sighash = utils.keccak256(utils.toUtf8Bytes(signature)).substring(0, 10);
619622
var func = function() {
620623
var result = {
@@ -649,6 +652,7 @@ function Interface(abi) {
649652
// @TODO: Move the paraseParams
650653
defineFrozen(func, 'inputs', getKeys(method.inputs, 'name'));
651654
defineFrozen(func, 'outputs', getKeys(method.outputs, 'name'));
655+
652656
utils.defineProperty(func, 'signature', signature);
653657
utils.defineProperty(func, 'sighash', sighash);
654658

@@ -667,9 +671,11 @@ function Interface(abi) {
667671
var func = (function() {
668672
// @TODO: Move to parseParams
669673
var inputTypes = getKeys(method.inputs, 'type');
674+
670675
var func = function() {
671676
// @TODO: Move to parseParams
672677
var signature = method.name + '(' + getKeys(method.inputs, 'type').join(',') + ')';
678+
673679
var result = {
674680
inputs: method.inputs,
675681
name: method.name,
@@ -747,15 +753,30 @@ function Interface(abi) {
747753

748754
return result;
749755
};
756+
750757
return populateDescription(new EventDescription(), result);
751758
}
752759

760+
// Next Major Version: All the event parameters are known and should
761+
// not require a function to be called to get them. We expose them
762+
// here now, and in the future will remove the callable version and
763+
// replace it with the EventDescription object
764+
765+
var info = func();
766+
753767
// @TODO: Move to parseParams
754768
defineFrozen(func, 'inputs', getKeys(method.inputs, 'name'));
755769

770+
utils.defineProperty(func, 'name', info.name);
771+
utils.defineProperty(func, 'parse', info.parse);
772+
utils.defineProperty(func, 'signature', info.signature);
773+
utils.defineProperty(func, 'topic', info.topics[0]);
774+
756775
return func;
757776
})();
758777

778+
779+
759780
if (method.name && events[method.name] == null) {
760781
utils.defineProperty(events, method.name, func);
761782
}

contracts/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ethers-contracts",
3-
"version": "2.1.9",
3+
"version": "2.1.10",
44
"description": "Contract and Interface (ABI) library for Ethereum.",
55
"bugs": {
66
"url": "http://github.com/ethers-io/ethers.js/issues",
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
3+
var utils = require('../utils');
4+
5+
var compile = (function() {
6+
var soljson = require('../soljson-4.19.js');
7+
var _compile = soljson.cwrap("compileJSONCallback", "string", ["string", "number", "number"]);
8+
9+
function compile(source) {
10+
return JSON.parse(_compile(JSON.stringify({sources: { "demo.sol": source }}), 0));
11+
}
12+
compile.version = JSON.parse(compile('contract Foo { }').contracts['demo.sol:Foo'].metadata).compiler.version
13+
return compile;
14+
})();
15+
16+
var tests = utils.loadTests('contract-interface-abi2');
17+
18+
var output = [];
19+
20+
tests.forEach(function(test) {
21+
var source = test.source;
22+
var ret = source.match(/returns([^{]*){/);
23+
var testSig = 'function testSig' + ret[1] + ' { }';
24+
source = source.substring(0, source.length - 2) + ' ' + testSig + '\n}\n';
25+
var code = compile(source);
26+
if (!code.contracts['demo.sol:Test']) {
27+
console.log(test.name, testSig, code.errors);
28+
return;
29+
}
30+
var funcHashes = code.contracts['demo.sol:Test'].functionHashes;
31+
var funcHash = null;
32+
for (var key in funcHashes) {
33+
if (key === 'test()') { continue; }
34+
if (funcHash) { throw new Error('should not happen'); }
35+
funcHash = key;
36+
}
37+
console.log(test.name, funcHash, funcHashes[funcHash]);
38+
output.push({
39+
name: test.name,
40+
signature: funcHash,
41+
sigHash: '0x' + funcHashes[funcHash],
42+
abi: code.contracts['demo.sol:Test'].interface
43+
});
44+
});
45+
46+
utils.saveTests('contract-signatures', output);

tests/test-contract-interface.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,3 +321,18 @@ describe('Test Contract Events', function() {
321321
});
322322

323323
});
324+
325+
describe('Test Interface Signatures', function() {
326+
var Interface = require('../contracts').Interface;
327+
328+
var tests = utils.loadTests('contract-signatures');
329+
tests.forEach(function(test) {
330+
var contract = new Interface(test.abi);
331+
it('derives the correct signature - ' + test.name, function() {
332+
assert.equal(contract.functions.testSig.signature, test.signature,
333+
'derived the correct signature');
334+
assert.equal(contract.functions.testSig.sighash, test.sigHash,
335+
'derived the correct signature hash');
336+
})
337+
});
338+
});
63.3 KB
Binary file not shown.

0 commit comments

Comments
 (0)