var chai = require('chai'); var assert = chai.assert; var Eth = require('../packages/web3-eth'); var sha3 = require('../packages/web3-utils').sha3; var FakeHttpProvider = require('./helpers/FakeHttpProvider'); var abi = [{ "type": "constructor", "inputs": [{ "name": "who", "type": "address" },{ "name": "myValue", "type": "uint256" }] },{ "name": "balance", "type": "function", "inputs": [{ "name": "who", "type": "address" }], "constant": true, "outputs": [{ "name": "value", "type": "uint256" }] }, { "name": "mySend", "type": "function", "inputs": [{ "name": "to", "type": "address" }, { "name": "value", "type": "uint256" }], "outputs": [], "payable": true },{ "name": "myDisallowedSend", "type": "function", "inputs": [{ "name": "to", "type": "address" }, { "name": "value", "type": "uint256" }], "outputs": [], "payable": false }, { "name": "testArr", "type": "function", "inputs": [{ "name": "value", "type": "int[]" }], "constant": true, "outputs": [{ "name": "d", "type": "int" }] }, { "name":"Changed", "type":"event", "inputs": [ {"name":"from","type":"address","indexed":true}, {"name":"amount","type":"uint256","indexed":true}, {"name":"t1","type":"uint256","indexed":false}, {"name":"t2","type":"uint256","indexed":false} ] }, { "name":"Unchanged", "type":"event", "inputs": [ {"name":"value","type":"uint256","indexed":true}, {"name":"addressFrom","type":"address","indexed":true}, {"name":"t1","type":"uint256","indexed":false} ] }]; var address = '0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe'; var addressLowercase = '0x11f4d0a3c12e86b4b5f39b213f7e19d048276dae'; var address2 = '0x5555567890123456789012345678901234567891'; describe('contract', function () { describe('instantiation', function () { it('should transform address from checksum addressess', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var contract = new eth.contract(abi, address); assert.equal(contract.options.address, address); }); it('should transform address to checksum address', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var contract = new eth.contract(abi, addressLowercase); assert.equal(contract.options.address, address); }); it('should fail on invalid address', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var test = function () { new eth.contract(abi, '0x11F4D0A3c12e86B4b5F39B213F7E19D048276DAe'); }; assert.throws(test); }); }); describe('internal method', function () { it('_encodeEventABI should return the encoded event object without topics', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var contract = new eth.contract(abi, address); var result = contract._encodeEventABI({ signature: '0x1234', "name":"Changed", "type":"event", "inputs": [ {"name":"from","type":"address","indexed":true}, {"name":"amount","type":"uint256","indexed":true}, {"name":"t1","type":"uint256","indexed":false}, {"name":"t2","type":"uint256","indexed":false} ] }); assert.deepEqual(result, { address: addressLowercase, topics: [ '0x1234', null, null ] }); }); it('_encodeEventABI should return the encoded event object with topics', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var contract = new eth.contract(abi, address); var result = contract._encodeEventABI({ signature: '0x1234', "name":"Changed", "type":"event", "inputs": [ {"name":"from","type":"address","indexed":true}, {"name":"amount","type":"uint256","indexed":true}, {"name":"t1","type":"uint256","indexed":false}, {"name":"t2","type":"uint256","indexed":false} ] }, {filter: {amount: 12}, fromBlock: 2}); assert.deepEqual(result, { address: addressLowercase, fromBlock: '0x2', topics: [ '0x1234', null, '0x000000000000000000000000000000000000000000000000000000000000000c' ] }); }); it('_encodeEventABI should return the encoded event object with topics and multiple choices', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var contract = new eth.contract(abi, address); var result = contract._encodeEventABI({ signature: '0x1234', "name":"Changed", "type":"event", "inputs": [ {"name":"test","type":"uint256","indexed":true}, {"name":"from","type":"address","indexed":true}, {"name":"amount","type":"uint256","indexed":true}, {"name":"t1","type":"uint256","indexed":false}, {"name":"t2","type":"uint256","indexed":false} ] }, {filter: {amount: [12,10], from: address}, fromBlock: 2}); assert.deepEqual(result, { address: addressLowercase, fromBlock: '0x2', topics: [ '0x1234', null, '0x000000000000000000000000'+ addressLowercase.replace('0x',''), ['0x000000000000000000000000000000000000000000000000000000000000000c', '0x000000000000000000000000000000000000000000000000000000000000000a'] ] }); }); it('_decodeEventABI should return the decoded event object with topics', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'Changed(address,uint256,uint256,uint256)'; var contract = new eth.contract(abi, address); var result = contract._decodeEventABI.call({ signature: sha3(signature), "name":"Changed", "type":"event", "inputs": [ {"name":"from","type":"address","indexed":true}, {"name":"amount","type":"uint256","indexed":true}, {"name":"t1","type":"uint256","indexed":false}, {"name":"t2","type":"uint256","indexed":false} ] }, { address: address, topics: [ sha3(signature), '0x000000000000000000000000'+ address.replace('0x',''), '0x0000000000000000000000000000000000000000000000000000000000000001' ], blockNumber: '0x3', transactionHash: '0x1234', blockHash: '0x1345', logIndex: '0x4', data: '0x0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000008' }); assert.equal(result.blockNumber, 3); assert.equal(result.blockHash, '0x1345'); assert.equal(result.logIndex, 4); assert.equal(result.id, 'log_9ff24cb4'); assert.equal(result.transactionIndex, 0); assert.equal(result.returnValues.from, address); assert.equal(result.returnValues.amount, 1); assert.equal(result.returnValues.t1, 1); assert.equal(result.returnValues.t2, 8); }); it('_decodeMethodReturn should return the decoded values', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'Changed(address,uint256,uint256,uint256)'; var contract = new eth.contract(abi, address); var result = contract._decodeMethodReturn([{ "name": "myAddress", "type": "address" },{ "name": "value", "type": "uint256" }], '0x000000000000000000000000'+ address.replace('0x','')+ '000000000000000000000000000000000000000000000000000000000000000a'); assert.equal(result[0], address); assert.equal(result[1], 10); }); it('_executeMethod should sendTransaction and check for receipts', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = sha3('mySend(address,uint256)').slice(0, 10); provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_sendTransaction'); assert.deepEqual(payload.params, [{ data: signature +'000000000000000000000000'+ addressLowercase.replace('0x','') +'000000000000000000000000000000000000000000000000000000000000000a', from: address2, to: addressLowercase }]); }); provider.injectResult('0x1234000000000000000000000000000000000000000000000000000000056789'); provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_subscribe'); assert.deepEqual(payload.params, ['newHeads']); }); provider.injectResult('0x1234567'); // fake newBlock provider.injectNotification({ method: 'eth_subscription', params: { subscription: '0x1234567', result: { blockNumber: '0x10' } } }); provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_getTransactionReceipt'); assert.deepEqual(payload.params, ['0x1234000000000000000000000000000000000000000000000000000000056789']); }); provider.injectResult({ contractAddress: addressLowercase, cumulativeGasUsed: '0xa', transactionIndex: '0x3', blockNumber: '0xa' }); provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_unsubscribe'); assert.deepEqual(payload.params, ['0x1234567']); }); provider.injectResult('0x321'); var contract = new eth.contract(abi, address); var txObject = {}; txObject._method = { signature: signature, "name": "send", "type": "function", "inputs": [{ "name": "to", "type": "address" }, { "name": "value", "type": "uint256" }], "outputs": [] }; txObject._parent = contract; txObject.encodeABI = contract._encodeMethodABI.bind(txObject); txObject.arguments = [address, 10]; var deploy = contract._executeMethod.call(txObject, 'send', {from: address2}, function (err, result) { // tx hash assert.equal(result, '0x1234000000000000000000000000000000000000000000000000000000056789'); }) .on('receipt', function(result){ assert.deepEqual(result, { contractAddress: address, cumulativeGasUsed: 10, transactionIndex: 3, blockNumber: 10, gasUsed: 0 }); done(); }); }); it('_executeMethod should call and return values', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = sha3('balance(address)').slice(0, 10); provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_call'); assert.deepEqual(payload.params, [{ data: signature + '000000000000000000000000'+ addressLowercase.replace('0x',''), from: address2, to: addressLowercase }, 'latest']); }); provider.injectResult('0x000000000000000000000000000000000000000000000000000000000000000a'); var contract = new eth.contract(abi, address); var txObject = {}; txObject._method = { signature: signature, "name": "balance", "type": "function", "inputs": [{ "name": "who", "type": "address" }], "constant": true, "outputs": [{ "name": "value", "type": "uint256" }] }; txObject._parent = contract; txObject.encodeABI = contract._encodeMethodABI.bind(txObject); txObject.arguments = [address]; var deploy = contract._executeMethod.call(txObject, 'call', {from: address2}, function (err, result) { assert.equal(result, '10'); }) .then(function(result){ assert.equal(result, '10'); done(); }); }); }); describe('event', function () { it('should create event subscription', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'Changed(address,uint256,uint256,uint256)'; provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_subscribe'); assert.deepEqual(payload.params[1], { topics: [ sha3(signature), ('0x000000000000000000000000' + addressLowercase.replace('0x', '')), null ], address: addressLowercase }); }); provider.injectResult('0x123'); provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_unsubscribe'); done(); }); provider.injectNotification({ method: 'eth_subscription', params: { subscription: '0x123', result: { address: addressLowercase, topics: [ sha3(signature), ('0x000000000000000000000000' + addressLowercase.replace('0x', '')), '0x0000000000000000000000000000000000000000000000000000000000000001' ], blockNumber: '0x3', transactionHash: '0x1234', blockHash: '0x1345', logIndex: '0x4', data: '0x0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000008' } } }); var contract = new eth.contract(abi, address); var event = contract.events.Changed({filter: {from: address}}, function (err, result, sub) { assert.equal(result.returnValues.from, address); assert.equal(result.returnValues.amount, 1); assert.equal(result.returnValues.t1, 1); assert.equal(result.returnValues.t2, 8); sub.unsubscribe(); }); }); it('should create event from the events object and use the fromBlock option', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'Changed(address,uint256,uint256,uint256)'; provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_getLogs'); }); provider.injectResult([{ address: addressLowercase, topics: [ sha3(signature), '0x000000000000000000000000'+ addressLowercase.replace('0x',''), '0x0000000000000000000000000000000000000000000000000000000000000002' ], blockNumber: '0x3', transactionHash: '0x1234', blockHash: '0x1345', logIndex: '0x4', data: '0x0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000009' }, { address: addressLowercase, topics: [ sha3(signature), '0x000000000000000000000000'+ addressLowercase.replace('0x',''), '0x0000000000000000000000000000000000000000000000000000000000000003' ], blockNumber: '0x4', transactionHash: '0x1235', blockHash: '0x1346', logIndex: '0x1', data: '0x0000000000000000000000000000000000000000000000000000000000000004' + '0000000000000000000000000000000000000000000000000000000000000005' }]); provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_subscribe'); assert.deepEqual(payload.params[1], { topics: [ sha3(signature), '0x000000000000000000000000'+ addressLowercase.replace('0x',''), null ], address: addressLowercase }); }); provider.injectResult('0x321'); provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_unsubscribe'); done(); }); provider.injectResult(true); provider.injectNotification({ method: 'eth_subscription', params: { subscription: '0x321', result: { address: addressLowercase, topics: [ sha3(signature), '0x000000000000000000000000'+ addressLowercase.replace('0x',''), '0x0000000000000000000000000000000000000000000000000000000000000001' ], blockNumber: '0x3', transactionHash: '0x1234', blockHash: '0x1345', logIndex: '0x4', data: '0x0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000008' } } }); var contract = new eth.contract(abi, address); var count = 0; var event = contract.events.Changed({fromBlock: 0,filter: {from: address}}) .on('data', function (result) { count++; if(count === 1) { assert.equal(result.returnValues.from, address); assert.equal(result.returnValues.amount, 2); assert.equal(result.returnValues.t1, 2); assert.equal(result.returnValues.t2, 9); } if(count === 2) { assert.equal(result.returnValues.from, address); assert.equal(result.returnValues.amount, 3); assert.equal(result.returnValues.t1, 4); assert.equal(result.returnValues.t2, 5); } if(count === 3) { assert.equal(result.returnValues.from, address); assert.equal(result.returnValues.amount, 1); assert.equal(result.returnValues.t1, 1); assert.equal(result.returnValues.t2, 8); event.unsubscribe(); } }); }); it('should create event from the events object using a signature and callback', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'Changed(address,uint256,uint256,uint256)'; provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_subscribe'); assert.deepEqual(payload.params[1], { topics: [ sha3(signature), '0x000000000000000000000000'+ addressLowercase.replace('0x',''), null ], address: addressLowercase }); }); provider.injectResult('0x321'); provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_unsubscribe'); done(); }); provider.injectResult(true); provider.injectNotification({ method: 'eth_subscription', params: { subscription: '0x321', result: { address: addressLowercase, topics: [ sha3(signature), '0x000000000000000000000000'+ addressLowercase.replace('0x',''), '0x0000000000000000000000000000000000000000000000000000000000000001' ], blockNumber: '0x3', transactionHash: '0x1234', blockHash: '0x1345', logIndex: '0x4', data: '0x0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000008' } } }); var contract = new eth.contract(abi, address); var event = contract.events['0x792991ed5ba9322deaef76cff5051ce4bedaaa4d097585970f9ad8f09f54e651']({filter: {from: address}}, function (err, result) { assert.equal(result.returnValues.from, address); assert.equal(result.returnValues.amount, 1); assert.equal(result.returnValues.t1, 1); assert.equal(result.returnValues.t2, 8); event.unsubscribe(); }); }); it('should create event from the events object using event name and parameters', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'Changed(address,uint256,uint256,uint256)'; provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_subscribe'); assert.deepEqual(payload.params[1], { topics: [ sha3(signature), '0x000000000000000000000000'+ addressLowercase.replace('0x',''), null ], address: addressLowercase }); }); provider.injectResult('0x321'); provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_unsubscribe'); done(); }); provider.injectResult(true); provider.injectNotification({ method: 'eth_subscription', params: { subscription: '0x321', result: { address: addressLowercase, topics: [ sha3(signature), '0x000000000000000000000000'+ addressLowercase.replace('0x',''), '0x0000000000000000000000000000000000000000000000000000000000000001' ], blockNumber: '0x3', transactionHash: '0x1234', blockHash: '0x1345', logIndex: '0x4', data: '0x0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000008' } } }); var contract = new eth.contract(abi, address); var event = contract.events[signature]({filter: {from: address}}, function (err, result) { assert.equal(result.returnValues.from, address); assert.equal(result.returnValues.amount, 1); assert.equal(result.returnValues.t1, 1); assert.equal(result.returnValues.t2, 8); event.unsubscribe(); }); }); it('should create event using the function and unsubscribe after one log received', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'Changed(address,uint256,uint256,uint256)'; provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_subscribe'); assert.deepEqual(payload.params[1], { topics: [ sha3(signature), '0x000000000000000000000000'+ addressLowercase.replace('0x',''), null ], address: addressLowercase }); }); provider.injectResult('0x321'); provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_unsubscribe'); }); provider.injectResult(true); provider.injectNotification({ method: 'eth_subscription', params: { subscription: '0x321', result: { address: addressLowercase, topics: [ sha3(signature), '0x000000000000000000000000'+ addressLowercase.replace('0x',''), '0x0000000000000000000000000000000000000000000000000000000000000001' ], blockNumber: '0x3', transactionHash: '0x1234', blockHash: '0x1345', logIndex: '0x4', data: '0x0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000008' } } }); provider.injectNotification({ method: 'eth_subscription', params: { subscription: '0x321', result: { address: addressLowercase, topics: [ sha3(signature), '0x000000000000000000000000'+ addressLowercase.replace('0x',''), '0x0000000000000000000000000000000000000000000000000000000000000001' ], blockNumber: '0x3', transactionHash: '0x1234', blockHash: '0x1345', logIndex: '0x4', data: '0x0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000008' } } }); var count = 1; var contract = new eth.contract(abi, address); contract.once('Changed', {filter: {from: address}}, function (err, result, sub) { assert.equal(result.returnValues.from, address); assert.equal(result.returnValues.amount, 1); assert.equal(result.returnValues.t1, 1); assert.equal(result.returnValues.t2, 8); assert.deepEqual(sub.options.requestManager.subscriptions, {}); assert.equal(count, 1); count++; setTimeout(done, 10); }); }); it('should create event using the function and unsubscribe after one log received when no options are provided', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'Changed(address,uint256,uint256,uint256)'; provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_subscribe'); assert.deepEqual(payload.params[1], { topics: [ sha3(signature), null, null ], address: addressLowercase }); }); provider.injectResult('0x321'); provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_unsubscribe'); }); provider.injectResult(true); provider.injectNotification({ method: 'eth_subscription', params: { subscription: '0x321', result: { address: addressLowercase, topics: [ sha3(signature), '0x000000000000000000000000'+ addressLowercase.replace('0x',''), '0x0000000000000000000000000000000000000000000000000000000000000001' ], blockNumber: '0x3', transactionHash: '0x1234', blockHash: '0x1345', logIndex: '0x4', data: '0x0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000008' } } }); provider.injectNotification({ method: 'eth_subscription', params: { subscription: '0x321', result: { address: addressLowercase, topics: [ sha3(signature), '0x000000000000000000000000'+ addressLowercase.replace('0x',''), '0x0000000000000000000000000000000000000000000000000000000000000001' ], blockNumber: '0x3', transactionHash: '0x1234', blockHash: '0x1345', logIndex: '0x4', data: '0x0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000008' } } }); var count = 1; var contract = new eth.contract(abi, address); contract.once('Changed', function (err, result, sub) { assert.equal(result.returnValues.from, address); assert.equal(result.returnValues.amount, 1); assert.equal(result.returnValues.t1, 1); assert.equal(result.returnValues.t2, 8); assert.deepEqual(sub.options.requestManager.subscriptions, {}); assert.equal(count, 1); count++; setTimeout(done, 10); }); }); it('should throw an error when using the once() function and no callback is provided', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var contract = new eth.contract(abi, address); assert.throws(contract.once.bind(contract, 'Changed', {filter: {from: address}})); }); it('should create all event filter and receive two logs', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'Changed(address,uint256,uint256,uint256)'; provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_subscribe'); assert.deepEqual(payload.params[1], { topics: [], address: addressLowercase }); }); provider.injectResult('0x333'); provider.injectValidation(function (payload) { assert.equal(payload.jsonrpc, '2.0'); assert.equal(payload.method, 'eth_unsubscribe'); done(); }); provider.injectResult(true); var contract = new eth.contract(abi, address); var count = 0; var event = contract.events.allEvents(function (err, result) { count++; if(count === 1) { assert.equal(result.returnValues.from, address); assert.equal(result.returnValues.amount, 1); assert.equal(result.returnValues.t1, 1); assert.equal(result.returnValues.t2, 8); } if(count === 2) { assert.equal(result.returnValues.addressFrom, address); assert.equal(result.returnValues.value, 2); assert.equal(result.returnValues.t1, 5); event.unsubscribe(); } }); provider.injectNotification({ method: 'eth_subscription', params: { subscription: '0x333', result: { address: address, topics: [ sha3('Changed(address,uint256,uint256,uint256)'), '0x000000000000000000000000'+ address.replace('0x',''), '0x0000000000000000000000000000000000000000000000000000000000000001' ], blockNumber: '0x3', transactionHash: '0x1234', blockHash: '0x1345', logIndex: '0x4', data: '0x0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000008' } } }); provider.injectNotification({ method: 'eth_subscription', params: { subscription: '0x333', result: { address: address, topics: [ sha3('Unchanged(uint256,address,uint256)'), '0x0000000000000000000000000000000000000000000000000000000000000002', '0x000000000000000000000000'+ address.replace('0x','') ], blockNumber: '0x3', transactionHash: '0x1234', blockHash: '0x1345', logIndex: '0x4', data: '0x0000000000000000000000000000000000000000000000000000000000000005' } } }); }); }); describe('with methods', function () { it('should change the address', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'balance(address)'; var contract = new eth.contract(abi, address); provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_call'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '000000000000000000000000'+ addressLowercase.replace('0x',''), to: addressLowercase, from: address2 }, 'latest']); }); contract.methods.balance(address).call({from: address2}); // change address contract.options.address = address2; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_call'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '000000000000000000000000'+ addressLowercase.replace('0x',''), to: address2, from: addressLowercase }, 'latest']); }); contract.methods.balance(address).call({from: address}); }); it('should reset functions when resetting json interface', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var contract = new eth.contract(abi); assert.isFunction(contract.methods.mySend); assert.isFunction(contract.events.Changed); contract.options.jsonInterface = [{ "name": "otherSend", "type": "function", "inputs": [{ "name": "to", "type": "address" }, { "name": "value", "type": "uint256" }], "outputs": [] }, { "name":"Unchanged", "type":"event", "inputs": [ {"name":"value","type":"uint256","indexed":true}, {"name":"addressFrom","type":"address","indexed":true}, {"name":"t1","type":"uint256","indexed":false} ] }]; assert.isFunction(contract.methods.otherSend); assert.isFunction(contract.events.Unchanged); assert.isUndefined(contract.methods.mySend); assert.isUndefined(contract.events.Changed); }); it('should encode a function call', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'balance(address)'; var contract = new eth.contract(abi); var result = contract.methods.balance(address).encodeABI(); assert.equal(result, sha3(signature).slice(0, 10) + '000000000000000000000000'+ addressLowercase.replace('0x','')); }); it('should encode a constructor call with pre set data', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'balance(address)'; var contract = new eth.contract(abi, {data: '0x1234'}); var result = contract.deploy({ arguments: [address, 10] }).encodeABI(); assert.equal(result, '0x1234' + '000000000000000000000000'+ addressLowercase.replace('0x','')+ '000000000000000000000000000000000000000000000000000000000000000a'); }); it('should encode a constructor call with passed data', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'balance(address)'; var contract = new eth.contract(abi); var result = contract.deploy({ arguments: [address, 10], data: '0x1234' }).encodeABI(); assert.equal(result, '0x1234' + '000000000000000000000000'+ addressLowercase.replace('0x','')+ '000000000000000000000000000000000000000000000000000000000000000a'); }); it('should estimate a function', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'balance(address)'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_estimateGas'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '000000000000000000000000'+ addressLowercase.replace('0x',''), to: addressLowercase }]); }); provider.injectResult('0x0000000000000000000000000000000000000000000000000000000000000032'); var contract = new eth.contract(abi, address); contract.methods.balance(address).estimateGas(function (err, res) { assert.deepEqual(res, 50); done(); }); }); it('should estimate the constructor', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'balance(address)'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_estimateGas'); assert.deepEqual(payload.params, [{ data: '0x1234000000000000000000000000'+ addressLowercase.replace('0x','') +'0000000000000000000000000000000000000000000000000000000000000032' }]); }); provider.injectResult('0x000000000000000000000000000000000000000000000000000000000000000a'); var contract = new eth.contract(abi, address, {data: '0x1234'}); contract.deploy({ arguments: [address, 50] }).estimateGas(function (err, res) { assert.deepEqual(res, 10); done(); }); }); it('should call constant function', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'balance(address)'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_call'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '000000000000000000000000'+ addressLowercase.replace('0x',''), to: addressLowercase }, 'latest']); }); provider.injectResult('0x0000000000000000000000000000000000000000000000000000000000000032'); var contract = new eth.contract(abi, address); contract.methods.balance(address).call(function (err, res) { assert.deepEqual(res, '50'); done(); }); }); it('should call constant function with default block', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'balance(address)'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_call'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '000000000000000000000000'+ addressLowercase.replace('0x',''), to: addressLowercase }, '0xb']); }); provider.injectResult('0x0000000000000000000000000000000000000000000000000000000000000032'); var contract = new eth.contract(abi, address); contract.methods.balance(address).call(11) .then(function (r) { assert.deepEqual(r, '50'); done(); }); }); it('should sendTransaction to contract function', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'mySend(address,uint256)'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_sendTransaction'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '000000000000000000000000'+ addressLowercase.replace('0x','') + '0000000000000000000000000000000000000000000000000000000000000011' , from: addressLowercase, to: addressLowercase }]); }); var contract = new eth.contract(abi, address); contract.methods.mySend(address, 17).send({from: address}); }); it('should throw error when trying to send ether to a non payable contract function', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var contract = new eth.contract(abi, address); try{ contract.methods.myDisallowedSend(address, 17).send({from: address, value: 123}) .on('error', function (e) { assert.isTrue(e instanceof Error, 'Should throw error'); }) .catch(function (e) { assert.isTrue(e instanceof Error, 'Should throw error'); }); } catch(e){ assert.isTrue(e instanceof Error, 'Should throw error'); } }); it('should not throw error when trying to not send ether to a non payable contract function', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'myDisallowedSend(address,uint256)'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_sendTransaction'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '000000000000000000000000'+ addressLowercase.replace('0x','') + '0000000000000000000000000000000000000000000000000000000000000011' , from: addressLowercase, to: addressLowercase }]); done(); }); var contract = new eth.contract(abi, address); try{ contract.methods.myDisallowedSend(address, 17).send({from: address}) .on('error', function (e) { assert.isFalse(e instanceof Error, 'Should not throw error'); }) .catch(function (e) { assert.isFalse(e instanceof Error, 'Should not throw error'); }); } catch(e){ assert.isFalse(e instanceof Error, 'Should not throw error'); } }); it('should sendTransaction to contract function using the function namen incl. parameters', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = sha3('mySend(address,uint256)').slice(0, 10); provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_sendTransaction'); assert.deepEqual(payload.params, [{ data: signature + '000000000000000000000000'+ addressLowercase.replace('0x','') + '0000000000000000000000000000000000000000000000000000000000000011' , from: addressLowercase, to: addressLowercase }]); }); var contract = new eth.contract(abi, address); contract.methods['mySend(address,uint256)'](address, 17).send({from: address}); }); it('should sendTransaction to contract function using the signature', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = sha3('mySend(address,uint256)').slice(0, 10); provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_sendTransaction'); assert.deepEqual(payload.params, [{ data: signature + '000000000000000000000000'+ addressLowercase.replace('0x','') + '0000000000000000000000000000000000000000000000000000000000000011' , from: addressLowercase, to: addressLowercase }]); }); var contract = new eth.contract(abi, address); contract.methods[signature](address, 17).send({from: address}); }); it('should make a call with optional params', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'balance(address)'; var count = 0; provider.injectValidation(function (payload) { count++; if(count > 1) return; assert.equal(payload.method, 'eth_call'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '000000000000000000000000'+ addressLowercase.replace('0x',''), to: addressLowercase, from: addressLowercase, gas: '0xc350' }, 'latest']); }); provider.injectResult('0x0000000000000000000000000000000000000000000000000000000000000032'); var contract = new eth.contract(abi, address); contract.methods.balance(address).call({from: address, gas: 50000}) .then(function (r) { assert.deepEqual(r, '50'); done(); }); }); it('should explicitly make a call with optional params', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'balance(address)'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_call'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '000000000000000000000000'+ addressLowercase.replace('0x',''), to: addressLowercase, from: addressLowercase, gas: '0xc350' }, 'latest']); }); provider.injectResult('0x0000000000000000000000000000000000000000000000000000000000000032'); var contract = new eth.contract(abi, address); contract.methods.balance(address).call({from: address, gas: 50000}) .then(function (r) { assert.deepEqual(r, '50'); done(); }); }); it('should explicitly make a call with optional params and defaultBlock', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'balance(address)'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_call'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '000000000000000000000000'+ addressLowercase.replace('0x',''), to: addressLowercase, from: addressLowercase, gas: '0xc350' }, '0xb']); }); provider.injectResult('0x0000000000000000000000000000000000000000000000000000000000000032'); var contract = new eth.contract(abi, address); contract.methods.balance(address).call({from: address, gas: 50000}, 11) .then(function (r) { assert.deepEqual(r, '50'); done(); }); }); it('should sendTransaction with optional params', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'mySend(address,uint256)'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_sendTransaction'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '000000000000000000000000'+ addressLowercase.replace('0x','') + '0000000000000000000000000000000000000000000000000000000000000011' , to: addressLowercase, from: addressLowercase, gas: '0xc350', gasPrice: '0xbb8', value: '0x2710' }]); }); var contract = new eth.contract(abi, address); contract.methods.mySend(address, 17).send({from: address, gas: 50000, gasPrice: 3000, value: 10000}); }); it('should explicitly sendTransaction with optional params', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'mySend(address,uint256)'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_sendTransaction'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '000000000000000000000000'+ addressLowercase.replace('0x','') + '0000000000000000000000000000000000000000000000000000000000000011' , to: addressLowercase, from: addressLowercase, gas: '0xc350', gasPrice: '0xbb8', value: '0x2710' }]); }); var contract = new eth.contract(abi, address); contract.methods.mySend(address, 17).send({from: address, gas: 50000, gasPrice: 3000, value: 10000}); }); it('should explicitly call sendTransaction with optional params and call callback without error', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'mySend(address,uint256)'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_sendTransaction'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '000000000000000000000000'+ addressLowercase.replace('0x','') + '0000000000000000000000000000000000000000000000000000000000000011' , to: addressLowercase, from: addressLowercase, gas: '0xc350', gasPrice: '0xbb8', value: '0x2710' }]); }); var contract = new eth.contract(abi, address); contract.methods.mySend(address, 17).send({from: address, gas: 50000, gasPrice: 3000, value: 10000}, function (err) { assert.equal(err, null); done(); }); }) it('should explicitly estimateGas with optional params', function () { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'mySend(address,uint256)'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_estimateGas'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '000000000000000000000000' + addressLowercase.replace('0x','') + '0000000000000000000000000000000000000000000000000000000000000011' , to: addressLowercase, from: addressLowercase, gas: '0xc350', gasPrice: '0xbb8', value: '0x2710' }]); }); var contract = new eth.contract(abi, address); contract.methods.mySend(address, 17).estimateGas({from: address, gas: 50000, gasPrice: 3000, value: 10000}); }); it('getPastEvents should get past events and format them correctly', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'testArr(int[])'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_getLogs'); assert.deepEqual(payload.params, [{ address: addressLowercase, topics: [ "0x792991ed5ba9322deaef76cff5051ce4bedaaa4d097585970f9ad8f09f54e651", "0x000000000000000000000000" + address2.replace('0x',''), null ] }]); }); var topic1 = [ sha3(signature), '0x000000000000000000000000'+ address.replace('0x',''), '0x000000000000000000000000000000000000000000000000000000000000000a' ]; var topic2 = [ sha3(signature), '0x000000000000000000000000'+ address.replace('0x',''), '0x0000000000000000000000000000000000000000000000000000000000000003' ]; provider.injectResult([{ address: address, topics: topic1, blockNumber: '0x3', transactionHash: '0x1234', blockHash: '0x1345', logIndex: '0x4', data: '0x0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000009' }, { address: address, topics: topic2, blockNumber: '0x4', transactionHash: '0x1235', blockHash: '0x1346', logIndex: '0x1', data: '0x0000000000000000000000000000000000000000000000000000000000000004' + '0000000000000000000000000000000000000000000000000000000000000005' }]); var contract = new eth.contract(abi, address); contract.getPastEvents('Changed', {filter: {from: address2}}) .then(function (result) { assert.deepEqual(result, [{ event: "Changed", id: "log_9ff24cb4", address: address, topics: topic1, blockNumber: 3, transactionHash: '0x1234', blockHash: '0x1345', logIndex: 4, transactionIndex: 0, data: '0x0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000009', returnValues: { from: address, amount: '10', t1: '2', t2: '9' } }, { event: "Changed", id: "log_29c93e15", address: address, topics: topic2, blockNumber: 4, transactionHash: '0x1235', blockHash: '0x1346', logIndex: 1, transactionIndex: 0, data: '0x0000000000000000000000000000000000000000000000000000000000000004' + '0000000000000000000000000000000000000000000000000000000000000005', returnValues: { from: address, amount: '3', t1: '4', t2: '5' } }]); done(); }).catch(done); }); it('should call testArr method and properly parse result', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'testArr(int[])'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_call'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '0000000000000000000000000000000000000000000000000000000000000020' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003', to: addressLowercase }, 'latest' ]); }); provider.injectResult('0x0000000000000000000000000000000000000000000000000000000000000005'); var contract = new eth.contract(abi, address); contract.methods.testArr([3]).call() .then(function (result) { assert.deepEqual(result, '5'); done(); }); }); it('should call testArr method, properly parse result and return the result in a callback', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); var signature = 'testArr(int[])'; provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_call'); assert.deepEqual(payload.params, [{ data: sha3(signature).slice(0, 10) + '0000000000000000000000000000000000000000000000000000000000000020' + '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000003', to: addressLowercase }, 'latest' ]); }); provider.injectResult('0x0000000000000000000000000000000000000000000000000000000000000005'); var contract = new eth.contract(abi, address); contract.methods.testArr([3]).call(function (err, result) { assert.deepEqual(result, '5'); done(); }); }); }); describe('with data', function () { it('should deploy a contract and use callback', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); provider.injectResult('0x1234567'); provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_sendTransaction'); assert.deepEqual(payload.params, [{ data: '0x1234567000000000000000000000000555456789012345678901234567890123456789100000000000000000000000000000000000000000000000000000000000000c8' , from: addressLowercase, gas: '0xc350', gasPrice: '0xbb8' }]); }); var contract = new eth.contract(abi); contract.deploy({ data: '0x1234567', arguments: ['0x5554567890123456789012345678901234567891', 200] }).send({ from: address, gas: 50000, gasPrice: 3000 }, function (err, result) { assert.equal(err, null); assert.equal(result, '0x1234567'); done(); }); }); it('should deploy a contract and use all promise steps', function (done) { var provider = new FakeHttpProvider(); var eth = new Eth(provider); provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_sendTransaction'); assert.deepEqual(payload.params, [{ data: '0x1234567000000000000000000000000'+ addressLowercase.replace('0x','') +'00000000000000000000000000000000000000000000000000000000000000c8' , from: addressLowercase, gas: '0xc350', gasPrice: '0xbb8' }]); }); provider.injectResult('0x5550000000000000000000000000000000000000000000000000000000000032'); provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_subscribe'); assert.deepEqual(payload.params, ['newHeads']); }); provider.injectResult('0x1234567'); // fake newBlock provider.injectNotification({ method: 'eth_subscription', params: { subscription: '0x1234567', result: { blockNumber: '0x10' } } }); provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_getTransactionReceipt'); assert.deepEqual(payload.params, ['0x5550000000000000000000000000000000000000000000000000000000000032']); }); provider.injectResult({ contractAddress: addressLowercase }); provider.injectValidation(function (payload) { assert.equal(payload.method, 'eth_getCode'); assert.deepEqual(payload.params, [addressLowercase, 'latest']); }); provider.injectResult('0x321'); var contract = new eth.contract(abi); contract.deploy({ data: '0x1234567', arguments: [address, 200] }).send({ from: address, gas: 50000, gasPrice: 3000 }) .on('transactionHash', function (value) { assert.equal('0x5550000000000000000000000000000000000000000000000000000000000032', value); }) .on('receipt', function (receipt) { assert.equal(address, receipt.contractAddress); }) .then(function(receipt) { assert.equal(address, receipt.contractAddress); done(); }); // .on('error', function (value) { // console.log('error', value); // done(); // }); }); // TODO add error check }); });