Paweł Bylica
10 years ago
93 changed files with 3858 additions and 1010 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,8 +1,11 @@ |
|||
var web3 = require('./lib/web3'); |
|||
var ProviderManager = require('./lib/providermanager'); |
|||
web3.provider = new ProviderManager(); |
|||
web3.filter = require('./lib/filter'); |
|||
web3.providers.WebSocketProvider = require('./lib/websocket'); |
|||
web3.providers.HttpRpcProvider = require('./lib/httprpc'); |
|||
web3.providers.QtProvider = require('./lib/qt'); |
|||
web3.providers.AutoProvider = require('./lib/autoprovider'); |
|||
web3.contract = require('./lib/contract'); |
|||
web3.eth.contract = require('./lib/contract'); |
|||
|
|||
module.exports = web3; |
|||
|
@ -0,0 +1,86 @@ |
|||
/* |
|||
This file is part of ethereum.js. |
|||
|
|||
ethereum.js is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU Lesser General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ethereum.js is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU Lesser General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU Lesser General Public License |
|||
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file filter.js |
|||
* @authors: |
|||
* Jeffrey Wilcke <jeff@ethdev.com> |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* Marian Oancea <marian@ethdev.com> |
|||
* Gav Wood <g@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
var web3 = require('./web3'); // jshint ignore:line
|
|||
|
|||
/// should be used when we want to watch something
|
|||
/// it's using inner polling mechanism and is notified about changes
|
|||
var Filter = function(options, impl) { |
|||
this.impl = impl; |
|||
this.callbacks = []; |
|||
|
|||
var self = this; |
|||
this.promise = impl.newFilter(options); |
|||
this.promise.then(function (id) { |
|||
self.id = id; |
|||
web3.on(impl.changed, id, self.trigger.bind(self)); |
|||
web3.provider.startPolling({call: impl.changed, args: [id]}, id); |
|||
}); |
|||
}; |
|||
|
|||
/// alias for changed*
|
|||
Filter.prototype.arrived = function(callback) { |
|||
this.changed(callback); |
|||
}; |
|||
|
|||
/// gets called when there is new eth/shh message
|
|||
Filter.prototype.changed = function(callback) { |
|||
var self = this; |
|||
this.promise.then(function(id) { |
|||
self.callbacks.push(callback); |
|||
}); |
|||
}; |
|||
|
|||
/// trigger calling new message from people
|
|||
Filter.prototype.trigger = function(messages) { |
|||
for(var i = 0; i < this.callbacks.length; i++) { |
|||
this.callbacks[i].call(this, messages); |
|||
} |
|||
}; |
|||
|
|||
/// should be called to uninstall current filter
|
|||
Filter.prototype.uninstall = function() { |
|||
var self = this; |
|||
this.promise.then(function (id) { |
|||
self.impl.uninstallFilter(id); |
|||
web3.provider.stopPolling(id); |
|||
web3.off(impl.changed, id); |
|||
}); |
|||
}; |
|||
|
|||
/// should be called to manually trigger getting latest messages from the client
|
|||
Filter.prototype.messages = function() { |
|||
var self = this; |
|||
return this.promise.then(function (id) { |
|||
return self.impl.getMessages(id); |
|||
}); |
|||
}; |
|||
|
|||
/// alias for messages
|
|||
Filter.prototype.logs = function () { |
|||
return this.messages(); |
|||
}; |
|||
|
|||
module.exports = Filter; |
@ -0,0 +1,119 @@ |
|||
/* |
|||
This file is part of ethereum.js. |
|||
|
|||
ethereum.js is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU Lesser General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ethereum.js is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU Lesser General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU Lesser General Public License |
|||
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file providermanager.js |
|||
* @authors: |
|||
* Jeffrey Wilcke <jeff@ethdev.com> |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* Marian Oancea <marian@ethdev.com> |
|||
* Gav Wood <g@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
var web3 = require('./web3'); // jshint ignore:line
|
|||
|
|||
/** |
|||
* Provider manager object prototype |
|||
* It's responsible for passing messages to providers |
|||
* If no provider is set it's responsible for queuing requests |
|||
* It's also responsible for polling the ethereum node for incoming messages |
|||
* Default poll timeout is 12 seconds |
|||
* If we are running ethereum.js inside ethereum browser, there are backend based tools responsible for polling, |
|||
* and provider manager polling mechanism is not used |
|||
*/ |
|||
var ProviderManager = function() { |
|||
this.queued = []; |
|||
this.polls = []; |
|||
this.ready = false; |
|||
this.provider = undefined; |
|||
this.id = 1; |
|||
|
|||
var self = this; |
|||
var poll = function () { |
|||
if (self.provider && self.provider.poll) { |
|||
self.polls.forEach(function (data) { |
|||
data.data._id = self.id; |
|||
self.id++; |
|||
self.provider.poll(data.data, data.id); |
|||
}); |
|||
} |
|||
setTimeout(poll, 12000); |
|||
}; |
|||
poll(); |
|||
}; |
|||
|
|||
/// sends outgoing requests, if provider is not available, enqueue the request
|
|||
ProviderManager.prototype.send = function(data, cb) { |
|||
data._id = this.id; |
|||
if (cb) { |
|||
web3._callbacks[data._id] = cb; |
|||
} |
|||
|
|||
data.args = data.args || []; |
|||
this.id++; |
|||
|
|||
if(this.provider !== undefined) { |
|||
this.provider.send(data); |
|||
} else { |
|||
console.warn("provider is not set"); |
|||
this.queued.push(data); |
|||
} |
|||
}; |
|||
|
|||
/// setups provider, which will be used for sending messages
|
|||
ProviderManager.prototype.set = function(provider) { |
|||
if(this.provider !== undefined && this.provider.unload !== undefined) { |
|||
this.provider.unload(); |
|||
} |
|||
|
|||
this.provider = provider; |
|||
this.ready = true; |
|||
}; |
|||
|
|||
/// resends queued messages
|
|||
ProviderManager.prototype.sendQueued = function() { |
|||
for(var i = 0; this.queued.length; i++) { |
|||
// Resend
|
|||
this.send(this.queued[i]); |
|||
} |
|||
}; |
|||
|
|||
/// @returns true if the provider i properly set
|
|||
ProviderManager.prototype.installed = function() { |
|||
return this.provider !== undefined; |
|||
}; |
|||
|
|||
/// this method is only used, when we do not have native qt bindings and have to do polling on our own
|
|||
/// should be callled, on start watching for eth/shh changes
|
|||
ProviderManager.prototype.startPolling = function (data, pollId) { |
|||
if (!this.provider || !this.provider.poll) { |
|||
return; |
|||
} |
|||
this.polls.push({data: data, id: pollId}); |
|||
}; |
|||
|
|||
/// should be called to stop polling for certain watch changes
|
|||
ProviderManager.prototype.stopPolling = function (pollId) { |
|||
for (var i = this.polls.length; i--;) { |
|||
var poll = this.polls[i]; |
|||
if (poll.id === pollId) { |
|||
this.polls.splice(i, 1); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
module.exports = ProviderManager; |
|||
|
@ -1,37 +1,827 @@ |
|||
var assert = require('assert'); |
|||
var BigNumber = require('bignumber.js'); |
|||
var abi = require('../lib/abi.js'); |
|||
var clone = function (object) { return JSON.parse(JSON.stringify(object)); }; |
|||
|
|||
var description = [{ |
|||
"name": "test", |
|||
"inputs": [{ |
|||
"name": "a", |
|||
"type": "uint256" |
|||
} |
|||
], |
|||
"outputs": [ |
|||
{ |
|||
"name": "d", |
|||
"type": "uint256" |
|||
} |
|||
] |
|||
}]; |
|||
|
|||
describe('abi', function() { |
|||
describe('inputParser', function() { |
|||
it('should parse ...', function() { |
|||
|
|||
var desc = [{ |
|||
"name": "multiply", |
|||
"inputs": [ |
|||
{ |
|||
"name": "a", |
|||
"type": "uint256" |
|||
} |
|||
], |
|||
"outputs": [ |
|||
{ |
|||
"name": "d", |
|||
"type": "uint256" |
|||
} |
|||
] |
|||
it('should parse input uint', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: "uint" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001"); |
|||
assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a"); |
|||
assert.equal( |
|||
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), |
|||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
|||
); |
|||
assert.equal( |
|||
parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)), |
|||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
|||
); |
|||
assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000"); |
|||
assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003"); |
|||
assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000"); |
|||
assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003"); |
|||
|
|||
|
|||
}); |
|||
|
|||
it('should parse input uint128', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: "uint128" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001"); |
|||
assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a"); |
|||
assert.equal( |
|||
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), |
|||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
|||
); |
|||
assert.equal( |
|||
parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)), |
|||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
|||
); |
|||
assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000"); |
|||
assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003"); |
|||
assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000"); |
|||
assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003"); |
|||
|
|||
}); |
|||
|
|||
it('should parse input uint256', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: "uint256" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001"); |
|||
assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a"); |
|||
assert.equal( |
|||
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), |
|||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
|||
); |
|||
assert.equal( |
|||
parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)), |
|||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
|||
); |
|||
assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000"); |
|||
assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003"); |
|||
assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000"); |
|||
assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003"); |
|||
|
|||
}); |
|||
|
|||
it('should parse input int', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: "int" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001"); |
|||
assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a"); |
|||
assert.equal(parser.test(-1), "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); |
|||
assert.equal(parser.test(-2), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"); |
|||
assert.equal(parser.test(-16), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0"); |
|||
assert.equal( |
|||
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), |
|||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
|||
); |
|||
assert.equal( |
|||
parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)), |
|||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
|||
); |
|||
assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000"); |
|||
assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003"); |
|||
assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000"); |
|||
assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003"); |
|||
}); |
|||
|
|||
it('should parse input int128', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: "int128" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001"); |
|||
assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a"); |
|||
assert.equal(parser.test(-1), "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); |
|||
assert.equal(parser.test(-2), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"); |
|||
assert.equal(parser.test(-16), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0"); |
|||
assert.equal( |
|||
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), |
|||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
|||
); |
|||
assert.equal( |
|||
parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)), |
|||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
|||
); |
|||
assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000"); |
|||
assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003"); |
|||
assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000"); |
|||
assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003"); |
|||
|
|||
}); |
|||
|
|||
it('should parse input int256', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: "int256" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001"); |
|||
assert.equal(parser.test(10), "000000000000000000000000000000000000000000000000000000000000000a"); |
|||
assert.equal(parser.test(-1), "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); |
|||
assert.equal(parser.test(-2), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"); |
|||
assert.equal(parser.test(-16), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0"); |
|||
assert.equal( |
|||
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), |
|||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
|||
); |
|||
assert.equal( |
|||
parser.test(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)), |
|||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" |
|||
); |
|||
assert.equal(parser.test(0.1), "0000000000000000000000000000000000000000000000000000000000000000"); |
|||
assert.equal(parser.test(3.9), "0000000000000000000000000000000000000000000000000000000000000003"); |
|||
assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000"); |
|||
assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003"); |
|||
|
|||
}); |
|||
|
|||
it('should parse input bool', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: 'bool' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test(true), "0000000000000000000000000000000000000000000000000000000000000001"); |
|||
assert.equal(parser.test(false), "0000000000000000000000000000000000000000000000000000000000000000"); |
|||
|
|||
}); |
|||
|
|||
it('should parse input hash', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: "hash" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test("0x407d73d8a49eeb85d32cf465507dd71d507100c1"), "000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1"); |
|||
|
|||
}); |
|||
|
|||
it('should parse input hash256', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: "hash256" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test("0x407d73d8a49eeb85d32cf465507dd71d507100c1"), "000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1"); |
|||
|
|||
}); |
|||
|
|||
|
|||
it('should parse input hash160', function() { |
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: "hash160" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test("0x407d73d8a49eeb85d32cf465507dd71d507100c1"), "000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1"); |
|||
}); |
|||
|
|||
it('should parse input address', function () { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: "address" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d) |
|||
|
|||
// then
|
|||
assert.equal(parser.test("0x407d73d8a49eeb85d32cf465507dd71d507100c1"), "000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1"); |
|||
|
|||
}); |
|||
|
|||
it('should parse input string', function () { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: "string" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal( |
|||
parser.test('hello'), |
|||
"000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000" |
|||
); |
|||
assert.equal( |
|||
parser.test('world'), |
|||
"0000000000000000000000000000000000000000000000000000000000000005776f726c64000000000000000000000000000000000000000000000000000000" |
|||
); |
|||
}); |
|||
|
|||
it('should use proper method name', function () { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
d[0].name = 'helloworld'; |
|||
d[0].inputs = [ |
|||
{ type: "int" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.helloworld(1), "0000000000000000000000000000000000000000000000000000000000000001"); |
|||
|
|||
}); |
|||
|
|||
it('should parse multiple methods', function () { |
|||
|
|||
// given
|
|||
var d = [{ |
|||
name: "test", |
|||
inputs: [{ type: "int" }], |
|||
outputs: [{ type: "int" }] |
|||
},{ |
|||
name: "test2", |
|||
inputs: [{ type: "string" }], |
|||
outputs: [{ type: "string" }] |
|||
}]; |
|||
|
|||
var iParser = abi.inputParser(desc); |
|||
assert.equal(iParser.multiply(1), "0x000000000000000000000000000000000000000000000000000000000000000001"); |
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
//then
|
|||
assert.equal(parser.test(1), "0000000000000000000000000000000000000000000000000000000000000001"); |
|||
assert.equal( |
|||
parser.test2('hello'), |
|||
"000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000" |
|||
); |
|||
|
|||
}); |
|||
}); |
|||
|
|||
it('should parse input array of ints', function () { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: "int[]" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal( |
|||
parser.test([5, 6]), |
|||
"0000000000000000000000000000000000000000000000000000000000000002" + |
|||
"0000000000000000000000000000000000000000000000000000000000000005" + |
|||
"0000000000000000000000000000000000000000000000000000000000000006" |
|||
); |
|||
}); |
|||
|
|||
it('should parse input real', function () { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: 'real' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test([1]), "0000000000000000000000000000000100000000000000000000000000000000"); |
|||
assert.equal(parser.test([2.125]), "0000000000000000000000000000000220000000000000000000000000000000"); |
|||
assert.equal(parser.test([8.5]), "0000000000000000000000000000000880000000000000000000000000000000"); |
|||
assert.equal(parser.test([-1]), "ffffffffffffffffffffffffffffffff00000000000000000000000000000000"); |
|||
|
|||
}); |
|||
|
|||
it('should parse input ureal', function () { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].inputs = [ |
|||
{ type: 'ureal' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.inputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test([1]), "0000000000000000000000000000000100000000000000000000000000000000"); |
|||
assert.equal(parser.test([2.125]), "0000000000000000000000000000000220000000000000000000000000000000"); |
|||
assert.equal(parser.test([8.5]), "0000000000000000000000000000000880000000000000000000000000000000"); |
|||
|
|||
}); |
|||
|
|||
}); |
|||
|
|||
describe('outputParser', function() { |
|||
it('parse ...', function() { |
|||
it('should parse output string', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: "string" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal( |
|||
parser.test("0x" + |
|||
"0000000000000000000000000000000000000000000000000000000000000005" + |
|||
"68656c6c6f000000000000000000000000000000000000000000000000000000")[0], |
|||
'hello' |
|||
); |
|||
assert.equal( |
|||
parser.test("0x" + |
|||
"0000000000000000000000000000000000000000000000000000000000000005" + |
|||
"776f726c64000000000000000000000000000000000000000000000000000000")[0], |
|||
'world' |
|||
); |
|||
|
|||
}); |
|||
|
|||
it('should parse output uint', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: 'uint' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test("0x0000000000000000000000000000000000000000000000000000000000000001")[0], 1); |
|||
assert.equal(parser.test("0x000000000000000000000000000000000000000000000000000000000000000a")[0], 10); |
|||
assert.equal( |
|||
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0].toString(10), |
|||
new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).toString(10) |
|||
); |
|||
assert.equal( |
|||
parser.test("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0].toString(10), |
|||
new BigNumber("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0", 16).toString(10) |
|||
); |
|||
}); |
|||
|
|||
it('should parse output uint256', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: 'uint256' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test("0x0000000000000000000000000000000000000000000000000000000000000001")[0], 1); |
|||
assert.equal(parser.test("0x000000000000000000000000000000000000000000000000000000000000000a")[0], 10); |
|||
assert.equal( |
|||
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0].toString(10), |
|||
new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).toString(10) |
|||
); |
|||
assert.equal( |
|||
parser.test("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0].toString(10), |
|||
new BigNumber("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0", 16).toString(10) |
|||
); |
|||
}); |
|||
|
|||
it('should parse output uint128', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: 'uint128' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test("0x0000000000000000000000000000000000000000000000000000000000000001")[0], 1); |
|||
assert.equal(parser.test("0x000000000000000000000000000000000000000000000000000000000000000a")[0], 10); |
|||
assert.equal( |
|||
parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0].toString(10), |
|||
new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).toString(10) |
|||
); |
|||
assert.equal( |
|||
parser.test("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0].toString(10), |
|||
new BigNumber("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0", 16).toString(10) |
|||
); |
|||
}); |
|||
|
|||
it('should parse output int', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: 'int' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test("0x0000000000000000000000000000000000000000000000000000000000000001")[0], 1); |
|||
assert.equal(parser.test("0x000000000000000000000000000000000000000000000000000000000000000a")[0], 10); |
|||
assert.equal(parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0], -1); |
|||
assert.equal(parser.test("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0], -16); |
|||
}); |
|||
|
|||
it('should parse output int256', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: 'int256' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test("0x0000000000000000000000000000000000000000000000000000000000000001")[0], 1); |
|||
assert.equal(parser.test("0x000000000000000000000000000000000000000000000000000000000000000a")[0], 10); |
|||
assert.equal(parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0], -1); |
|||
assert.equal(parser.test("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0], -16); |
|||
}); |
|||
|
|||
it('should parse output int128', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: 'int128' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test("0x0000000000000000000000000000000000000000000000000000000000000001")[0], 1); |
|||
assert.equal(parser.test("0x000000000000000000000000000000000000000000000000000000000000000a")[0], 10); |
|||
assert.equal(parser.test("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")[0], -1); |
|||
assert.equal(parser.test("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0], -16); |
|||
}); |
|||
|
|||
it('should parse output hash', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: 'hash' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal( |
|||
parser.test("0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1")[0], |
|||
"0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1" |
|||
); |
|||
}); |
|||
|
|||
it('should parse output hash256', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: 'hash256' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal( |
|||
parser.test("0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1")[0], |
|||
"0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1" |
|||
); |
|||
}); |
|||
|
|||
it('should parse output hash160', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: 'hash160' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal( |
|||
parser.test("0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1")[0], |
|||
"0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1" |
|||
); |
|||
// TODO shouldnt' the expected hash be shorter?
|
|||
}); |
|||
|
|||
it('should parse output address', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: 'address' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal( |
|||
parser.test("0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1")[0], |
|||
"0x407d73d8a49eeb85d32cf465507dd71d507100c1" |
|||
); |
|||
}); |
|||
|
|||
it('should parse output bool', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: 'bool' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test("0x0000000000000000000000000000000000000000000000000000000000000001")[0], true); |
|||
assert.equal(parser.test("0x0000000000000000000000000000000000000000000000000000000000000000")[0], false); |
|||
|
|||
|
|||
}); |
|||
|
|||
it('should parse output real', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: 'real' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test("0x0000000000000000000000000000000100000000000000000000000000000000")[0], 1); |
|||
assert.equal(parser.test("0x0000000000000000000000000000000220000000000000000000000000000000")[0], 2.125); |
|||
assert.equal(parser.test("0x0000000000000000000000000000000880000000000000000000000000000000")[0], 8.5); |
|||
assert.equal(parser.test("0xffffffffffffffffffffffffffffffff00000000000000000000000000000000")[0], -1); |
|||
|
|||
}); |
|||
|
|||
it('should parse output ureal', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: 'ureal' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test("0x0000000000000000000000000000000100000000000000000000000000000000")[0], 1); |
|||
assert.equal(parser.test("0x0000000000000000000000000000000220000000000000000000000000000000")[0], 2.125); |
|||
assert.equal(parser.test("0x0000000000000000000000000000000880000000000000000000000000000000")[0], 8.5); |
|||
|
|||
}); |
|||
|
|||
|
|||
it('should parse multiple output strings', function() { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
|
|||
d[0].outputs = [ |
|||
{ type: "string" }, |
|||
{ type: "string" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal( |
|||
parser.test("0x" + |
|||
"0000000000000000000000000000000000000000000000000000000000000005" + |
|||
"0000000000000000000000000000000000000000000000000000000000000005" + |
|||
"68656c6c6f000000000000000000000000000000000000000000000000000000" + |
|||
"776f726c64000000000000000000000000000000000000000000000000000000")[0], |
|||
'hello' |
|||
); |
|||
assert.equal( |
|||
parser.test("0x" + |
|||
"0000000000000000000000000000000000000000000000000000000000000005" + |
|||
"0000000000000000000000000000000000000000000000000000000000000005" + |
|||
"68656c6c6f000000000000000000000000000000000000000000000000000000" + |
|||
"776f726c64000000000000000000000000000000000000000000000000000000")[1], |
|||
'world' |
|||
); |
|||
|
|||
}); |
|||
|
|||
it('should use proper method name', function () { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
d[0].name = 'helloworld'; |
|||
d[0].outputs = [ |
|||
{ type: "int" } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.helloworld("0x0000000000000000000000000000000000000000000000000000000000000001")[0], 1); |
|||
|
|||
}); |
|||
|
|||
|
|||
it('should parse multiple methods', function () { |
|||
|
|||
// given
|
|||
var d = [{ |
|||
name: "test", |
|||
inputs: [{ type: "int" }], |
|||
outputs: [{ type: "int" }] |
|||
},{ |
|||
name: "test2", |
|||
inputs: [{ type: "string" }], |
|||
outputs: [{ type: "string" }] |
|||
}]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
//then
|
|||
assert.equal(parser.test("0000000000000000000000000000000000000000000000000000000000000001")[0], 1); |
|||
assert.equal(parser.test2("0x" + |
|||
"0000000000000000000000000000000000000000000000000000000000000005" + |
|||
"68656c6c6f000000000000000000000000000000000000000000000000000000")[0], |
|||
"hello" |
|||
); |
|||
|
|||
}); |
|||
|
|||
it('should parse output array', function () { |
|||
|
|||
// given
|
|||
var d = clone(description); |
|||
d[0].outputs = [ |
|||
{ type: 'int[]' } |
|||
]; |
|||
|
|||
// when
|
|||
var parser = abi.outputParser(d); |
|||
|
|||
// then
|
|||
assert.equal(parser.test("0x" + |
|||
"0000000000000000000000000000000000000000000000000000000000000002" + |
|||
"0000000000000000000000000000000000000000000000000000000000000005" + |
|||
"0000000000000000000000000000000000000000000000000000000000000006")[0][0], |
|||
5 |
|||
); |
|||
assert.equal(parser.test("0x" + |
|||
"0000000000000000000000000000000000000000000000000000000000000002" + |
|||
"0000000000000000000000000000000000000000000000000000000000000005" + |
|||
"0000000000000000000000000000000000000000000000000000000000000006")[0][1], |
|||
6 |
|||
); |
|||
|
|||
}); |
|||
|
|||
}); |
|||
}); |
|||
|
|||
|
@ -1,2 +1,2 @@ |
|||
--reporter Spec |
|||
--reporter spec |
|||
|
|||
|
@ -0,0 +1,31 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file Exceptions.cpp
|
|||
* @author Arkadiy Paronyan arkadiy@ethdev.com |
|||
* @date 2015 |
|||
* Ethereum IDE client. |
|||
*/ |
|||
|
|||
#include <ostream> |
|||
#include <QQmlError> |
|||
#include "Exceptions.h" |
|||
|
|||
std::ostream& operator<<(std::ostream& _out, QQmlError const& _error) |
|||
{ |
|||
_out << _error.toString().toStdString(); |
|||
return _out; |
|||
} |
@ -0,0 +1,45 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file Exceptions.h
|
|||
* @author Arkadiy Paronyan arkadiy@ethdev.com |
|||
* @date 2015 |
|||
* Ethereum IDE client. |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <iosfwd> |
|||
#include <libdevcore/Exceptions.h> |
|||
|
|||
class QTextDocument; |
|||
class QQmlError; |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
struct QmlLoadException: virtual Exception {}; |
|||
struct FileIoException: virtual Exception {}; |
|||
|
|||
typedef boost::error_info<struct tagQmlError, QQmlError> QmlErrorInfo; |
|||
typedef boost::error_info<struct tagFileError, std::string> FileError; |
|||
|
|||
} |
|||
} |
|||
|
|||
std::ostream& operator<<(std::ostream& _out, QQmlError const& _error); |
@ -0,0 +1,59 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file QBigInt.cpp
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
#include <boost/variant/multivisitors.hpp> |
|||
#include <boost/variant.hpp> |
|||
#include <libdevcore/CommonJS.h> |
|||
#include "QBigInt.h" |
|||
|
|||
using namespace dev; |
|||
using namespace dev::mix; |
|||
|
|||
QString QBigInt::value() const |
|||
{ |
|||
std::ostringstream s; |
|||
s << m_internalValue; |
|||
return QString::fromStdString(s.str()); |
|||
} |
|||
|
|||
QBigInt* QBigInt::subtract(QBigInt* const& _value) const |
|||
{ |
|||
BigIntVariant toSubtract = _value->internalValue(); |
|||
return new QBigInt(boost::apply_visitor(mix::subtract(), m_internalValue, toSubtract)); |
|||
} |
|||
|
|||
QBigInt* QBigInt::add(QBigInt* const& _value) const |
|||
{ |
|||
BigIntVariant toAdd = _value->internalValue(); |
|||
return new QBigInt(boost::apply_visitor(mix::add(), m_internalValue, toAdd)); |
|||
} |
|||
|
|||
QBigInt* QBigInt::multiply(QBigInt* const& _value) const |
|||
{ |
|||
BigIntVariant toMultiply = _value->internalValue(); |
|||
return new QBigInt(boost::apply_visitor(mix::multiply(), m_internalValue, toMultiply)); |
|||
} |
|||
|
|||
QBigInt* QBigInt::divide(QBigInt* const& _value) const |
|||
{ |
|||
BigIntVariant toDivide = _value->internalValue(); |
|||
return new QBigInt(boost::apply_visitor(mix::divide(), m_internalValue, toDivide)); |
|||
} |
@ -0,0 +1,102 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file QBigInt.h
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2015 |
|||
* Represent a big integer (u256, bigint) to be used in QML. |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include "boost/variant.hpp" |
|||
#include "boost/variant/multivisitors.hpp" |
|||
#include <QObject> |
|||
#include <QQmlEngine> |
|||
#include <libdevcore/CommonJS.h> |
|||
#include <libdevcore/Common.h> |
|||
|
|||
using namespace dev; |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
using BigIntVariant = boost::variant<dev::u256, dev::bigint>; |
|||
|
|||
struct add: public boost::static_visitor<BigIntVariant> |
|||
{ |
|||
template<class T1, class T2> |
|||
BigIntVariant operator()(T1 const& _value, T2 const& _otherValue) const { return _value + _otherValue; } |
|||
}; |
|||
|
|||
struct subtract: public boost::static_visitor<BigIntVariant> |
|||
{ |
|||
template<class T1, class T2> |
|||
BigIntVariant operator()(T1 const& _value, T2 const& _otherValue) const { return _value - _otherValue; } |
|||
}; |
|||
|
|||
struct multiply: public boost::static_visitor<BigIntVariant> |
|||
{ |
|||
template<class T1, class T2> |
|||
BigIntVariant operator()(T1 const& _value, T2 const& _otherValue) const { return _value * _otherValue; } |
|||
}; |
|||
|
|||
struct divide: public boost::static_visitor<BigIntVariant> |
|||
{ |
|||
template<class T1, class T2> |
|||
BigIntVariant operator()(T1 const& _value, T2 const& _otherValue) const { return _value / _otherValue; } |
|||
}; |
|||
|
|||
/*
|
|||
* Represent big integer like big int and u256 in QML. |
|||
* The ownership is set by default to Javascript. |
|||
*/ |
|||
class QBigInt: public QObject |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
QBigInt(QObject* _parent = 0): QObject(_parent), m_internalValue(dev::u256(0)) { QQmlEngine::setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); } |
|||
QBigInt(dev::u256 const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value) { QQmlEngine::setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); } |
|||
QBigInt(dev::bigint const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value) { QQmlEngine::setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); } |
|||
QBigInt(BigIntVariant const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value){ QQmlEngine::setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); } |
|||
~QBigInt() {} |
|||
|
|||
/// @returns the current used big integer.
|
|||
BigIntVariant internalValue() { return m_internalValue; } |
|||
/// @returns a string representation of the big integer used. Invokable from QML.
|
|||
Q_INVOKABLE QString value() const; |
|||
/// Set the value of the BigInteger used. Will use u256 type. Invokable from QML.
|
|||
Q_INVOKABLE void setValue(QString const& _value) { m_internalValue = dev::jsToU256(_value.toStdString()); } |
|||
/// Subtract by @a _value. Invokable from QML.
|
|||
Q_INVOKABLE QBigInt* subtract(QBigInt* const& _value) const; |
|||
/// Add @a _value to the current big integer. Invokable from QML.
|
|||
Q_INVOKABLE QBigInt* add(QBigInt* const& _value) const; |
|||
/// Multiply by @a _value. Invokable from QML.
|
|||
Q_INVOKABLE QBigInt* multiply(QBigInt* const& _value) const; |
|||
/// divide by @a _value. Invokable from QML.
|
|||
Q_INVOKABLE QBigInt* divide(QBigInt* const& _value) const; |
|||
|
|||
protected: |
|||
BigIntVariant m_internalValue; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
|
|||
|
@ -0,0 +1,55 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file QEther.cpp
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include <QMetaEnum> |
|||
#include "QEther.h" |
|||
|
|||
using namespace dev::mix; |
|||
|
|||
QString QEther::format() const |
|||
{ |
|||
return QString::fromStdString(dev::eth::formatBalance(boost::get<dev::u256>(toWei()->internalValue()))); |
|||
} |
|||
|
|||
QBigInt* QEther::toWei() const |
|||
{ |
|||
QMetaEnum units = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("EtherUnit")); |
|||
const char* key = units.valueToKey(m_currentUnit); |
|||
for (std::pair<dev::u256, std::string> rawUnit: dev::eth::units()) |
|||
{ |
|||
if (rawUnit.second == QString(key).toLower().toStdString()) |
|||
return multiply(new QBigInt(rawUnit.first)); |
|||
} |
|||
return new QBigInt(dev::u256(0)); |
|||
} |
|||
|
|||
void QEther::setUnit(QString const& _unit) |
|||
{ |
|||
QMetaEnum units = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("EtherUnit")); |
|||
for (int k = 0; k < units.keyCount(); k++) |
|||
{ |
|||
if (QString(units.key(k)).toLower() == _unit) |
|||
{ |
|||
m_currentUnit = static_cast<EtherUnit>(units.keysToValue(units.key(k))); |
|||
return; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,92 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file QEther.h
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
* Represent an amount of Ether in QML (mapped to u256 in c++). |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QObject> |
|||
#include <libethcore/CommonEth.h> |
|||
#include "QBigInt.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
class QEther: public QBigInt |
|||
{ |
|||
Q_OBJECT |
|||
Q_ENUMS(EtherUnit) |
|||
Q_PROPERTY(QString value READ value WRITE setValue NOTIFY valueChanged) |
|||
Q_PROPERTY(EtherUnit unit READ unit WRITE setUnit NOTIFY unitChanged) |
|||
|
|||
public: |
|||
enum EtherUnit |
|||
{ |
|||
Uether, |
|||
Vether, |
|||
Dether, |
|||
Nether, |
|||
Yether, |
|||
Zether, |
|||
Eether, |
|||
Pether, |
|||
Tether, |
|||
Gether, |
|||
Mether, |
|||
Grand, |
|||
Ether, |
|||
Finney, |
|||
Szabo, |
|||
Gwei, |
|||
Mwei, |
|||
Kwei, |
|||
Wei |
|||
}; |
|||
|
|||
QEther(QObject* _parent = 0): QBigInt(dev::u256(0), _parent), m_currentUnit(EtherUnit::Wei) {} |
|||
QEther(dev::u256 _value, EtherUnit _unit, QObject* _parent = 0): QBigInt(_value, _parent), m_currentUnit(_unit) {} |
|||
~QEther() {} |
|||
|
|||
/// @returns user-friendly string representation of the amount of ether. Invokable from QML.
|
|||
Q_INVOKABLE QString format() const; |
|||
/// @returns the current amount of Ether in Wei. Invokable from QML.
|
|||
Q_INVOKABLE QBigInt* toWei() const; |
|||
/// @returns the current unit used. Invokable from QML.
|
|||
Q_INVOKABLE EtherUnit unit() const { return m_currentUnit; } |
|||
/// Set the unit to be used. Invokable from QML.
|
|||
Q_INVOKABLE void setUnit(EtherUnit const& _unit) { m_currentUnit = _unit; } |
|||
/// Set the unit to be used. Invokable from QML.
|
|||
Q_INVOKABLE void setUnit(QString const& _unit); |
|||
/// @returns the u256 value of the current amount of Ether in Wei.
|
|||
dev::u256 toU256Wei() { return boost::get<dev::u256>(toWei()->internalValue()); } |
|||
|
|||
private: |
|||
EtherUnit m_currentUnit; |
|||
|
|||
signals: |
|||
void valueChanged(); |
|||
void unitChanged(); |
|||
}; |
|||
|
|||
} |
|||
} |
|||
|
@ -0,0 +1,13 @@ |
|||
/* |
|||
* Used to instanciate a QEther obj using Qt.createComponent function. |
|||
*/ |
|||
import QtQuick 2.2 |
|||
import QtQuick.Controls 1.1 |
|||
import QtQuick.Layouts 1.1 |
|||
import QtQuick.Controls.Styles 1.1 |
|||
import org.ethereum.qml.QBigInt 1.0 |
|||
|
|||
QBigInt |
|||
{ |
|||
id: bigInt |
|||
} |
@ -0,0 +1,115 @@ |
|||
/* |
|||
* Display a row containing : |
|||
* - The amount of Ether. |
|||
* - The unit used. |
|||
* - User-friendly string representation of the amout of Ether (if displayFormattedValue == true). |
|||
* 'value' has to be a QEther obj. |
|||
*/ |
|||
import QtQuick 2.2 |
|||
import QtQuick.Controls 1.1 |
|||
import QtQuick.Layouts 1.1 |
|||
import QtQuick.Controls.Styles 1.1 |
|||
|
|||
Rectangle { |
|||
id: etherEdition |
|||
property bool displayFormattedValue; |
|||
property bool edit; |
|||
property variant value; |
|||
onValueChanged: update() |
|||
Component.onCompleted: update() |
|||
|
|||
function update() |
|||
{ |
|||
if (value !== undefined) |
|||
{ |
|||
etherValueEdit.text = value.value; |
|||
selectUnit(value.unit); |
|||
} |
|||
} |
|||
|
|||
function selectUnit(unit) |
|||
{ |
|||
units.currentIndex = unit; |
|||
} |
|||
|
|||
RowLayout |
|||
{ |
|||
anchors.fill: parent; |
|||
id: row |
|||
width: 200 |
|||
height: parent.height |
|||
Rectangle |
|||
{ |
|||
width : 200 |
|||
color: edit ? "blue" : "white" |
|||
TextField |
|||
{ |
|||
onTextChanged: |
|||
{ |
|||
if (value !== undefined) |
|||
{ |
|||
value.setValue(text) |
|||
formattedValue.text = value.format(); |
|||
} |
|||
} |
|||
width: parent.width |
|||
readOnly: !edit |
|||
visible: edit |
|||
id: etherValueEdit; |
|||
} |
|||
} |
|||
|
|||
Rectangle |
|||
{ |
|||
Layout.fillWidth: true |
|||
id: unitContainer |
|||
width: 20 |
|||
anchors.verticalCenter: parent.verticalCenter |
|||
ComboBox |
|||
{ |
|||
id: units |
|||
onCurrentTextChanged: |
|||
{ |
|||
if (value !== undefined) |
|||
{ |
|||
value.setUnit(currentText); |
|||
formattedValue.text = value.format(); |
|||
} |
|||
} |
|||
model: ListModel { |
|||
id: unitsModel |
|||
ListElement { text: "Uether"; } |
|||
ListElement { text: "Vether"; } |
|||
ListElement { text: "Dether"; } |
|||
ListElement { text: "Nether"; } |
|||
ListElement { text: "Yether"; } |
|||
ListElement { text: "Zether"; } |
|||
ListElement { text: "Eether"; } |
|||
ListElement { text: "Pether"; } |
|||
ListElement { text: "Tether"; } |
|||
ListElement { text: "Gether"; } |
|||
ListElement { text: "Mether"; } |
|||
ListElement { text: "grand"; } |
|||
ListElement { text: "ether"; } |
|||
ListElement { text: "finney"; } |
|||
ListElement { text: "szabo"; } |
|||
ListElement { text: "Gwei"; } |
|||
ListElement { text: "Mwei"; } |
|||
ListElement { text: "Kwei"; } |
|||
ListElement { text: "wei"; } |
|||
} |
|||
} |
|||
Rectangle |
|||
{ |
|||
anchors.verticalCenter: parent.verticalCenter |
|||
anchors.left: units.right |
|||
visible: displayFormattedValue |
|||
width: 20 |
|||
Text |
|||
{ |
|||
id: formattedValue |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,15 @@ |
|||
/* |
|||
* Used to instanciate a QEther obj using Qt.createComponent function. |
|||
*/ |
|||
import QtQuick 2.2 |
|||
import QtQuick.Controls 1.1 |
|||
import QtQuick.Layouts 1.1 |
|||
import QtQuick.Controls.Styles 1.1 |
|||
import org.ethereum.qml.QEther 1.0 |
|||
|
|||
QEther |
|||
{ |
|||
id: basicEther |
|||
value: "100000000000" |
|||
unit: QEther.Wei |
|||
} |
Loading…
Reference in new issue