Fixed ABIv2 signatures for calling methods.

This commit is contained in:
Richard Moore 2018-01-09 20:45:38 -05:00
parent d6cf970ae9
commit df930103e7
No known key found for this signature in database
GPG Key ID: 525F70A6FCABC295
5 changed files with 84 additions and 2 deletions

View File

@ -614,7 +614,10 @@ function Interface(abi) {
var outputNames = outputParams.names;
}
var signature = method.name + '(' + inputParams.types.join(',') + ')';
var signature = '(' + inputParams.types.join(',') + ')';
signature = signature.replace(/tuple/g, '');
signature = method.name + signature;
var sighash = utils.keccak256(utils.toUtf8Bytes(signature)).substring(0, 10);
var func = function() {
var result = {
@ -649,6 +652,7 @@ function Interface(abi) {
// @TODO: Move the paraseParams
defineFrozen(func, 'inputs', getKeys(method.inputs, 'name'));
defineFrozen(func, 'outputs', getKeys(method.outputs, 'name'));
utils.defineProperty(func, 'signature', signature);
utils.defineProperty(func, 'sighash', sighash);
@ -667,9 +671,11 @@ function Interface(abi) {
var func = (function() {
// @TODO: Move to parseParams
var inputTypes = getKeys(method.inputs, 'type');
var func = function() {
// @TODO: Move to parseParams
var signature = method.name + '(' + getKeys(method.inputs, 'type').join(',') + ')';
var result = {
inputs: method.inputs,
name: method.name,
@ -747,15 +753,30 @@ function Interface(abi) {
return result;
};
return populateDescription(new EventDescription(), result);
}
// Next Major Version: All the event parameters are known and should
// not require a function to be called to get them. We expose them
// here now, and in the future will remove the callable version and
// replace it with the EventDescription object
var info = func();
// @TODO: Move to parseParams
defineFrozen(func, 'inputs', getKeys(method.inputs, 'name'));
utils.defineProperty(func, 'name', info.name);
utils.defineProperty(func, 'parse', info.parse);
utils.defineProperty(func, 'signature', info.signature);
utils.defineProperty(func, 'topic', info.topics[0]);
return func;
})();
if (method.name && events[method.name] == null) {
utils.defineProperty(events, method.name, func);
}

View File

@ -1,6 +1,6 @@
{
"name": "ethers-contracts",
"version": "2.1.9",
"version": "2.1.10",
"description": "Contract and Interface (ABI) library for Ethereum.",
"bugs": {
"url": "http://github.com/ethers-io/ethers.js/issues",

View File

@ -0,0 +1,46 @@
'use strict';
var utils = require('../utils');
var compile = (function() {
var soljson = require('../soljson-4.19.js');
var _compile = soljson.cwrap("compileJSONCallback", "string", ["string", "number", "number"]);
function compile(source) {
return JSON.parse(_compile(JSON.stringify({sources: { "demo.sol": source }}), 0));
}
compile.version = JSON.parse(compile('contract Foo { }').contracts['demo.sol:Foo'].metadata).compiler.version
return compile;
})();
var tests = utils.loadTests('contract-interface-abi2');
var output = [];
tests.forEach(function(test) {
var source = test.source;
var ret = source.match(/returns([^{]*){/);
var testSig = 'function testSig' + ret[1] + ' { }';
source = source.substring(0, source.length - 2) + ' ' + testSig + '\n}\n';
var code = compile(source);
if (!code.contracts['demo.sol:Test']) {
console.log(test.name, testSig, code.errors);
return;
}
var funcHashes = code.contracts['demo.sol:Test'].functionHashes;
var funcHash = null;
for (var key in funcHashes) {
if (key === 'test()') { continue; }
if (funcHash) { throw new Error('should not happen'); }
funcHash = key;
}
console.log(test.name, funcHash, funcHashes[funcHash]);
output.push({
name: test.name,
signature: funcHash,
sigHash: '0x' + funcHashes[funcHash],
abi: code.contracts['demo.sol:Test'].interface
});
});
utils.saveTests('contract-signatures', output);

View File

@ -321,3 +321,18 @@ describe('Test Contract Events', function() {
});
});
describe('Test Interface Signatures', function() {
var Interface = require('../contracts').Interface;
var tests = utils.loadTests('contract-signatures');
tests.forEach(function(test) {
var contract = new Interface(test.abi);
it('derives the correct signature - ' + test.name, function() {
assert.equal(contract.functions.testSig.signature, test.signature,
'derived the correct signature');
assert.equal(contract.functions.testSig.sighash, test.sigHash,
'derived the correct signature hash');
})
});
});

Binary file not shown.