Paweł Bylica
9 years ago
164 changed files with 0 additions and 28512 deletions
@ -1,18 +0,0 @@ |
|||
cmake_policy(SET CMP0015 NEW) |
|||
# let cmake autolink dependencies on windows |
|||
cmake_policy(SET CMP0020 NEW) |
|||
# this policy was introduced in cmake 3.0 |
|||
# remove if, once 3.0 will be used on unix |
|||
if (${CMAKE_MAJOR_VERSION} GREATER 2) |
|||
cmake_policy(SET CMP0043 OLD) |
|||
endif() |
|||
set(CMAKE_AUTOMOC OFF) |
|||
|
|||
qt5_add_resources(JSQRC js.qrc) |
|||
add_library(jsqrc STATIC ${JSQRC}) |
|||
target_link_libraries(jsqrc Qt5::Core) |
|||
|
|||
install( TARGETS jsqrc RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) |
|||
|
|||
file(GLOB_RECURSE JSFILES "ethereumjs/lib/*.js") |
|||
add_custom_target(aux_js SOURCES ${JSFILES}) |
@ -1,130 +0,0 @@ |
|||
web3.admin = {}; |
|||
web3.admin.setSessionKey = function(s) { web3.admin.sessionKey = s; }; |
|||
|
|||
var getSessionKey = function () { return web3.admin.sessionKey; }; |
|||
|
|||
web3._extend({ |
|||
property: 'admin', |
|||
methods: [new web3._extend.Method({ |
|||
name: 'web3.setVerbosity', |
|||
call: 'admin_web3_setVerbosity', |
|||
inputFormatter: [null, getSessionKey], |
|||
params: 2 |
|||
}), new web3._extend.Method({ |
|||
name: 'net.start', |
|||
call: 'admin_net_start', |
|||
inputFormatter: [getSessionKey], |
|||
params: 1 |
|||
}), new web3._extend.Method({ |
|||
name: 'net.stop', |
|||
call: 'admin_net_stop', |
|||
inputFormatter: [getSessionKey], |
|||
params: 1 |
|||
}), new web3._extend.Method({ |
|||
name: 'net.connect', |
|||
call: 'admin_net_connect', |
|||
inputFormatter: [null, getSessionKey], |
|||
params: 2 |
|||
}), new web3._extend.Method({ |
|||
name: 'net.peers', |
|||
call: 'admin_net_peers', |
|||
inputFormatter: [getSessionKey], |
|||
params: 1 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.blockQueueStatus', |
|||
call: 'admin_eth_blockQueueStatus', |
|||
inputFormatter: [getSessionKey], |
|||
params: 1 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.exit', |
|||
call: 'admin_eth_exit', |
|||
inputFormatter: [getSessionKey], |
|||
params: 1 |
|||
}), new web3._extend.Method({ |
|||
name: 'net.nodeInfo', |
|||
call: 'admin_net_nodeInfo', |
|||
inputFormatter: [getSessionKey], |
|||
params: 1 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.setAskPrice', |
|||
call: 'admin_eth_setAskPrice', |
|||
inputFormatter: [null, getSessionKey], |
|||
params: 2 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.setBidPrice', |
|||
call: 'admin_eth_setBidPrice', |
|||
inputFormatter: [null, getSessionKey], |
|||
params: 2 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.setReferencePrice', |
|||
call: 'admin_eth_setReferencePrice', |
|||
inputFormatter: [null, getSessionKey], |
|||
params: 2 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.setPriority', |
|||
call: 'admin_eth_setPriority', |
|||
inputFormatter: [null, getSessionKey], |
|||
params: 2 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.setMining', |
|||
call: 'admin_eth_setMining', |
|||
inputFormatter: [null, getSessionKey], |
|||
params: 2 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.findBlock', |
|||
call: 'admin_eth_findBlock', |
|||
inputFormatter: [null, getSessionKey], |
|||
params: 2 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.blockQueueFirstUnknown', |
|||
call: 'admin_eth_blockQueueFirstUnknown', |
|||
inputFormatter: [getSessionKey], |
|||
params: 1 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.blockQueueRetryUnknown', |
|||
call: 'admin_eth_blockQueueRetryUnknown', |
|||
inputFormatter: [getSessionKey], |
|||
params: 1 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.allAccounts', |
|||
call: 'admin_eth_allAccounts', |
|||
inputFormatter: [getSessionKey], |
|||
params: 1 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.newAccount', |
|||
call: 'admin_eth_newAccount', |
|||
inputFormatter: [null, getSessionKey], |
|||
params: 2 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.setSigningKey', |
|||
call: 'admin_eth_setSigningKey', |
|||
inputFormatter: [null, getSessionKey], |
|||
params: 2 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.setMiningBenefactor', |
|||
call: 'admin_eth_setMiningBenefactor', |
|||
inputFormatter: [null, getSessionKey], |
|||
params: 2 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.inspect', |
|||
call: 'admin_eth_inspect', |
|||
inputFormatter: [null, getSessionKey], |
|||
params: 2 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.reprocess', |
|||
call: 'admin_eth_reprocess', |
|||
inputFormatter: [null, getSessionKey], |
|||
params: 2 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.vmTrace', |
|||
call: 'admin_eth_vmTrace', |
|||
inputFormatter: [null, null, getSessionKey], |
|||
params: 3 |
|||
}), new web3._extend.Method({ |
|||
name: 'eth.getReceiptByHashAndIndex', |
|||
call: 'admin_eth_getReceiptByHashAndIndex', |
|||
inputFormatter: [null, null, getSessionKey], |
|||
params: 3 |
|||
})] |
|||
}); |
|||
|
File diff suppressed because one or more lines are too long
@ -1,7 +0,0 @@ |
|||
#!/bin/bash |
|||
|
|||
cd ethereumjs |
|||
export PATH=$PATH:$1:$2 |
|||
npm install |
|||
npm run-script build |
|||
|
@ -1,5 +0,0 @@ |
|||
{ |
|||
"directory": "bower", |
|||
"cwd": "./", |
|||
"analytics": false |
|||
} |
@ -1,12 +0,0 @@ |
|||
root = true |
|||
|
|||
[*] |
|||
indent_style = space |
|||
indent_size = 4 |
|||
end_of_line = lf |
|||
charset = utf-8 |
|||
trim_trailing_whitespace = true |
|||
insert_final_newline = true |
|||
|
|||
[*.md] |
|||
trim_trailing_whitespace = false |
@ -1,20 +0,0 @@ |
|||
# See http://help.github.com/ignore-files/ for more about ignoring files. |
|||
# |
|||
# If you find yourself ignoring temporary files generated by your text editor |
|||
# or operating system, you probably want to add a global ignore instead: |
|||
# git config --global core.excludesfile ~/.gitignore_global |
|||
|
|||
*.swp |
|||
/coverage |
|||
/tmp |
|||
*/**/*un~ |
|||
*un~ |
|||
.DS_Store |
|||
*/**/.DS_Store |
|||
ethereum/ethereum |
|||
ethereal/ethereal |
|||
example/js |
|||
node_modules |
|||
bower_components |
|||
npm-debug.log |
|||
/bower |
@ -1,19 +0,0 @@ |
|||
{ |
|||
"browserify": true, |
|||
"bitwise": true, |
|||
"camelcase": true, |
|||
"eqeqeq": true, |
|||
"freeze": true, |
|||
"funcscope": false, |
|||
"maxcomplexity": 4, /* our target is 3! */ |
|||
"maxdepth": 3, |
|||
"maxerr": 50, |
|||
/*"maxlen": 80*/ /*this should be our goal*/ |
|||
/*"maxparams": 3,*/ |
|||
"nonew": true, |
|||
"unused": true, |
|||
"undef": true, |
|||
"predef": [ |
|||
"console" |
|||
] |
|||
} |
@ -1,9 +0,0 @@ |
|||
example/js |
|||
node_modules |
|||
test |
|||
.gitignore |
|||
.editorconfig |
|||
.travis.yml |
|||
.npmignore |
|||
component.json |
|||
testling.html |
@ -1,16 +0,0 @@ |
|||
language: node_js |
|||
node_js: |
|||
- "0.12" |
|||
- "0.11" |
|||
before_script: |
|||
- npm install |
|||
- npm install jshint |
|||
- export DISPLAY=:99.0 |
|||
- sh -e /etc/init.d/xvfb start |
|||
script: |
|||
- "jshint *.js lib" |
|||
after_script: |
|||
- npm run-script build |
|||
- npm run-script test-coveralls |
|||
- cd test/node && npm install && node app.js |
|||
|
@ -1,3 +0,0 @@ |
|||
ethereum:web3@0.7.0 |
|||
meteor@1.1.6 |
|||
underscore@1.0.3 |
@ -1,14 +0,0 @@ |
|||
This file is part of web3.js. |
|||
|
|||
web3.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. |
|||
|
|||
web3.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 web3.js. If not, see <http://www.gnu.org/licenses/>. |
@ -1,107 +0,0 @@ |
|||
# Ethereum JavaScript API |
|||
|
|||
[![Join the chat at https://gitter.im/ethereum/web3.js](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ethereum/web3.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) |
|||
|
|||
This is the Ethereum compatible [JavaScript API](https://github.com/ethereum/wiki/wiki/JavaScript-API) |
|||
which implements the [Generic JSON RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) spec. It's available on npm as a node module, for bower and component as an embeddable js and as a meteor.js package. |
|||
|
|||
[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![dependency status][dep-image]][dep-url] [![dev dependency status][dep-dev-image]][dep-dev-url][![Coverage Status][coveralls-image]][coveralls-url][![Stories in Ready][waffle-image]][waffle-url] |
|||
|
|||
<!-- [![browser support](https://ci.testling.com/ethereum/ethereum.js.png)](https://ci.testling.com/ethereum/ethereum.js) --> |
|||
|
|||
You need to run a local ethrereum node to use this library. |
|||
|
|||
[Documentation](https://github.com/ethereum/wiki/wiki/JavaScript-API) |
|||
|
|||
## Installation |
|||
|
|||
### Node.js |
|||
|
|||
```bash |
|||
npm install web3 |
|||
``` |
|||
|
|||
### Meteor.js |
|||
|
|||
```bash |
|||
meteor add ethereum:web3 |
|||
``` |
|||
|
|||
### As Browser module |
|||
Bower |
|||
|
|||
```bash |
|||
bower install web3 |
|||
``` |
|||
|
|||
Component |
|||
|
|||
```bash |
|||
component install ethereum/web3.js |
|||
``` |
|||
|
|||
* Include `ethereum.min.js` in your html file. (not required for the meteor package) |
|||
|
|||
## Usage |
|||
Use the `web3` object directly from global namespace: |
|||
|
|||
```js |
|||
console.log(web3); // {eth: .., shh: ...} // it's here! |
|||
``` |
|||
|
|||
Set a provider (HttpProvider) |
|||
|
|||
```js |
|||
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545')); |
|||
``` |
|||
|
|||
There you go, now you can use it: |
|||
|
|||
```js |
|||
var coinbase = web3.eth.coinbase; |
|||
var balance = web3.eth.getBalance(coinbase); |
|||
``` |
|||
|
|||
You can find more examples in [`example`](https://github.com/ethereum/web3.js/tree/master/example) directory. |
|||
|
|||
|
|||
## Contribute! |
|||
|
|||
### Requirements |
|||
|
|||
* Node.js |
|||
* npm |
|||
|
|||
```bash |
|||
sudo apt-get update |
|||
sudo apt-get install nodejs |
|||
sudo apt-get install npm |
|||
sudo apt-get install nodejs-legacy |
|||
``` |
|||
|
|||
### Building (gulp) |
|||
|
|||
```bash |
|||
npm run-script build |
|||
``` |
|||
|
|||
|
|||
### Testing (mocha) |
|||
|
|||
```bash |
|||
npm test |
|||
``` |
|||
|
|||
[npm-image]: https://badge.fury.io/js/web3.png |
|||
[npm-url]: https://npmjs.org/package/web3 |
|||
[travis-image]: https://travis-ci.org/ethereum/web3.js.svg |
|||
[travis-url]: https://travis-ci.org/ethereum/web3.js |
|||
[dep-image]: https://david-dm.org/ethereum/web3.js.svg |
|||
[dep-url]: https://david-dm.org/ethereum/web3.js |
|||
[dep-dev-image]: https://david-dm.org/ethereum/web3.js/dev-status.svg |
|||
[dep-dev-url]: https://david-dm.org/ethereum/web3.js#info=devDependencies |
|||
[coveralls-image]: https://coveralls.io/repos/ethereum/web3.js/badge.svg?branch=master |
|||
[coveralls-url]: https://coveralls.io/r/ethereum/web3.js?branch=master |
|||
[waffle-image]: https://badge.waffle.io/ethereum/web3.js.svg?label=ready&title=Ready |
|||
[waffle-url]: http://waffle.io/ethereum/web3.js |
|||
|
@ -1,62 +0,0 @@ |
|||
{ |
|||
"name": "web3", |
|||
"namespace": "ethereum", |
|||
"version": "0.9.0", |
|||
"description": "Ethereum Compatible JavaScript API", |
|||
"main": [ |
|||
"./dist/web3.js", |
|||
"./dist/web3.min.js" |
|||
], |
|||
"dependencies": { |
|||
"bignumber.js": ">=2.0.0", |
|||
"crypto-js": "~3.1.4" |
|||
}, |
|||
"repository": { |
|||
"type": "git", |
|||
"url": "https://github.com/ethereum/web3.js.git" |
|||
}, |
|||
"homepage": "https://github.com/ethereum/web3.js", |
|||
"bugs": { |
|||
"url": "https://github.com/ethereum/web3.js/issues" |
|||
}, |
|||
"keywords": [ |
|||
"ethereum", |
|||
"javascript", |
|||
"API" |
|||
], |
|||
"authors": [ |
|||
{ |
|||
"name": "Marek Kotewicz", |
|||
"email": "marek@ethdev.com", |
|||
"homepage": "https://github.com/debris" |
|||
}, |
|||
{ |
|||
"name": "Marian Oancea", |
|||
"email": "marian@ethdev.com", |
|||
"homepage": "https://github.com/cubedro" |
|||
}, |
|||
{ |
|||
"name": "Fabian Vogelsteller", |
|||
"email": "fabian@ethdev.com", |
|||
"homepage": "https://github.com/frozeman" |
|||
} |
|||
], |
|||
"license": "LGPL-3.0", |
|||
"ignore": [ |
|||
"example", |
|||
"lib", |
|||
"node_modules", |
|||
"package.json", |
|||
"package.js", |
|||
".versions", |
|||
".bowerrc", |
|||
".editorconfig", |
|||
".gitignore", |
|||
".jshintrc", |
|||
".npmignore", |
|||
".travis.yml", |
|||
"gulpfile.js", |
|||
"index.js", |
|||
"**/*.txt" |
|||
] |
|||
} |
File diff suppressed because it is too large
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,38 +0,0 @@ |
|||
<!doctype> |
|||
<html> |
|||
|
|||
<head> |
|||
<script type="text/javascript" src="../node_modules/bignumber.js/bignumber.min.js"></script> |
|||
<script type="text/javascript" src="../dist/web3-light.js"></script> |
|||
<script type="text/javascript"> |
|||
|
|||
var web3 = require('web3'); |
|||
web3.setProvider(new web3.providers.HttpProvider()); |
|||
|
|||
function watchBalance() { |
|||
var coinbase = web3.eth.coinbase; |
|||
|
|||
var originalBalance = web3.eth.getBalance(coinbase).toNumber(); |
|||
document.getElementById('coinbase').innerText = 'coinbase: ' + coinbase; |
|||
document.getElementById('original').innerText = ' original balance: ' + originalBalance + ' watching...'; |
|||
|
|||
web3.eth.filter('latest').watch(function() { |
|||
var currentBalance = web3.eth.getBalance(coinbase).toNumber(); |
|||
document.getElementById("current").innerText = 'current: ' + currentBalance; |
|||
document.getElementById("diff").innerText = 'diff: ' + (currentBalance - originalBalance); |
|||
}); |
|||
} |
|||
|
|||
</script> |
|||
</head> |
|||
<body> |
|||
<h1>coinbase balance</h1> |
|||
<button type="button" onClick="watchBalance();">watch balance</button> |
|||
<div></div> |
|||
<div id="coinbase"></div> |
|||
<div id="original"></div> |
|||
<div id="current"></div> |
|||
<div id="diff"></div> |
|||
</body> |
|||
</html> |
|||
|
@ -1,76 +0,0 @@ |
|||
<!doctype> |
|||
<html> |
|||
|
|||
<head> |
|||
<script type="text/javascript" src="../dist/web3.js"></script> |
|||
<script type="text/javascript"> |
|||
|
|||
var web3 = require('web3'); |
|||
web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545")); |
|||
|
|||
// solidity code code |
|||
var source = "" + |
|||
"contract test {\n" + |
|||
" function multiply(uint a) constant returns(uint d) {\n" + |
|||
" return a * 7;\n" + |
|||
" }\n" + |
|||
"}\n"; |
|||
|
|||
var compiled = web3.eth.compile.solidity(source); |
|||
var code = compiled.test.code; |
|||
// contract json abi, this is autogenerated using solc CLI |
|||
var abi = compiled.test.info.abiDefinition; |
|||
|
|||
var myContract; |
|||
|
|||
function createExampleContract() { |
|||
// hide create button |
|||
document.getElementById('create').style.visibility = 'hidden'; |
|||
document.getElementById('code').innerText = code; |
|||
|
|||
// let's assume that coinbase is our account |
|||
web3.eth.defaultAccount = web3.eth.coinbase; |
|||
|
|||
// create contract |
|||
document.getElementById('status').innerText = "transaction sent, waiting for confirmation"; |
|||
web3.eth.contract(abi).new({data: code}, function (err, contract) { |
|||
if(err) { |
|||
console.error(err); |
|||
return; |
|||
|
|||
// callback fires twice, we only want the second call when the contract is deployed |
|||
} else if(contract.address){ |
|||
|
|||
myContract = contract; |
|||
console.log('address: ' + myContract.address); |
|||
document.getElementById('status').innerText = 'Mined!'; |
|||
document.getElementById('call').style.visibility = 'visible'; |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function callExampleContract() { |
|||
// this should be generated by ethereum |
|||
var param = parseInt(document.getElementById('value').value); |
|||
|
|||
// call the contract |
|||
var res = myContract.multiply(param); |
|||
document.getElementById('result').innerText = res.toString(10); |
|||
} |
|||
|
|||
</script> |
|||
</head> |
|||
<body> |
|||
<h1>contract</h1> |
|||
<div id="code"></div> |
|||
<div id="status"></div> |
|||
<div id='create'> |
|||
<button type="button" onClick="createExampleContract();">create example contract</button> |
|||
</div> |
|||
<div id='call' style='visibility: hidden;'> |
|||
<input type="number" id="value" onkeyup='callExampleContract()'></input> |
|||
</div> |
|||
<div id="result"></div> |
|||
</body> |
|||
</html> |
|||
|
@ -1,81 +0,0 @@ |
|||
<!doctype> |
|||
<html> |
|||
|
|||
<head> |
|||
<script type="text/javascript" src="../dist/web3.js"></script> |
|||
<script type="text/javascript"> |
|||
|
|||
var web3 = require('web3'); |
|||
web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545")); |
|||
|
|||
// solidity code code |
|||
var source = "" + |
|||
"contract test {\n" + |
|||
" function take(uint[] a, uint b) constant returns(uint d) {\n" + |
|||
" return a[b];\n" + |
|||
" }\n" + |
|||
"}\n"; |
|||
|
|||
var compiled = web3.eth.compile.solidity(source); |
|||
var code = compiled.test.code; |
|||
// contract json abi, this is autogenerated using solc CLI |
|||
var abi = compiled.test.info.abiDefinition; |
|||
|
|||
var myContract; |
|||
|
|||
function createExampleContract() { |
|||
// hide create button |
|||
document.getElementById('create').style.visibility = 'hidden'; |
|||
document.getElementById('code').innerText = code; |
|||
|
|||
// let's assume that coinbase is our account |
|||
web3.eth.defaultAccount = web3.eth.coinbase; |
|||
|
|||
// create contract |
|||
document.getElementById('status').innerText = "transaction sent, waiting for confirmation"; |
|||
web3.eth.contract(abi).new({data: code}, function (err, contract) { |
|||
if (err) { |
|||
console.error(err); |
|||
return; |
|||
|
|||
// callback fires twice, we only want the second call when the contract is deployed |
|||
} else if(contract.address){ |
|||
|
|||
myContract = contract; |
|||
console.log('address: ' + myContract.address); |
|||
|
|||
document.getElementById('status').innerText = 'Mined!'; |
|||
document.getElementById('call').style.visibility = 'visible'; |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function callExampleContract() { |
|||
// this should be generated by ethereum |
|||
var param = parseInt(document.getElementById('value').value); |
|||
|
|||
// call the contract |
|||
var res = myContract.take([0,6,5,2,1,5,6], param); |
|||
document.getElementById('result').innerText = res.toString(10); |
|||
} |
|||
|
|||
</script> |
|||
</head> |
|||
<body> |
|||
<h1>contract</h1> |
|||
<div id="code"></div> |
|||
<div id="status"></div> |
|||
<div id='create'> |
|||
<button type="button" onClick="createExampleContract();">create example contract</button> |
|||
</div> |
|||
<div id='call' style='visibility: hidden;'> |
|||
<div>var array = [0,6,5,2,1,5,6];</div> |
|||
<div>var x = array[ |
|||
<input type="number" id="value" onkeyup='callExampleContract()'></input> |
|||
]; |
|||
</div> |
|||
</div> |
|||
<div id="result"></div> |
|||
</body> |
|||
</html> |
|||
|
@ -1,86 +0,0 @@ |
|||
<!doctype> |
|||
<html> |
|||
<head> |
|||
<script type="text/javascript" src="../dist/web3.js"></script> |
|||
<script type="text/javascript"> |
|||
var web3 = require('web3'); |
|||
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545')); |
|||
|
|||
var source = "" + |
|||
"contract Contract { " + |
|||
" event Incremented(bool indexed odd, uint x); " + |
|||
" function Contract() { " + |
|||
" x = 70; " + |
|||
" } " + |
|||
" function inc() { " + |
|||
" ++x; " + |
|||
" Incremented(x % 2 == 1, x); " + |
|||
" } " + |
|||
" uint x; " + |
|||
"}"; |
|||
|
|||
var compiled = web3.eth.compile.solidity(source); |
|||
var code = compiled.Contract.code; |
|||
var abi = compiled.Contract.info.abiDefinition; |
|||
|
|||
var address; |
|||
var contract; |
|||
var inc; |
|||
|
|||
var update = function (err, x) { |
|||
document.getElementById('result').textContent = JSON.stringify(x, null, 2); |
|||
}; |
|||
|
|||
var createContract = function () { |
|||
// let's assume that we have a private key to coinbase ;) |
|||
web3.eth.defaultAccount = web3.eth.coinbase; |
|||
|
|||
document.getElementById('create').style.visibility = 'hidden'; |
|||
document.getElementById('status').innerText = "transaction sent, waiting for confirmation"; |
|||
|
|||
web3.eth.contract(abi).new({data: code}, function (err, c) { |
|||
if (err) { |
|||
console.error(err); |
|||
return; |
|||
|
|||
// callback fires twice, we only want the second call when the contract is deployed |
|||
} else if(contract.address){ |
|||
|
|||
contract = c; |
|||
console.log('address: ' + contract.address); |
|||
document.getElementById('status').innerText = 'Mined!'; |
|||
document.getElementById('call').style.visibility = 'visible'; |
|||
|
|||
inc = contract.Incremented({odd: true}, update); |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
var counter = 0; |
|||
var callContract = function () { |
|||
counter++; |
|||
var all = 70 + counter; |
|||
document.getElementById('count').innerText = 'Transaction sent ' + counter + ' times. ' + |
|||
'Expected x value is: ' + (all - (all % 2 ? 0 : 1)) + ' ' + |
|||
'Waiting for the blocks to be mined...'; |
|||
|
|||
contract.inc(); |
|||
}; |
|||
|
|||
|
|||
</script> |
|||
</head> |
|||
|
|||
<body> |
|||
<div id="status"></div> |
|||
<div> |
|||
<button id="create" type="button" onClick="createContract();">create contract</button> |
|||
</div> |
|||
<div> |
|||
<button id="call" style="visibility: hidden;" type="button" onClick="callContract();">test1</button> |
|||
</div> |
|||
<div id='count'></div> |
|||
<div id="result"> |
|||
</div> |
|||
</body> |
|||
</html> |
@ -1,203 +0,0 @@ |
|||
<!doctype> |
|||
<html> |
|||
|
|||
<head> |
|||
<script type="text/javascript" src="../dist/web3.js"></script> |
|||
<script type="text/javascript"> |
|||
|
|||
var web3 = require('web3'); |
|||
var BigNumber = require('bignumber.js'); |
|||
web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545")); |
|||
var from = web3.eth.coinbase; |
|||
web3.eth.defaultAccount = from; |
|||
|
|||
var nameregAbi = [ |
|||
{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"name","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"}, |
|||
{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"}, |
|||
{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"content","outputs":[{"name":"","type":"bytes32"}],"type":"function"}, |
|||
{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"addr","outputs":[{"name":"","type":"address"}],"type":"function"}, |
|||
{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserve","outputs":[],"type":"function"}, |
|||
{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"subRegistrar","outputs":[{"name":"o_subRegistrar","type":"address"}],"type":"function"}, |
|||
{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_newOwner","type":"address"}],"name":"transfer","outputs":[],"type":"function"}, |
|||
{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_registrar","type":"address"}],"name":"setSubRegistrar","outputs":[],"type":"function"}, |
|||
{"constant":false,"inputs":[],"name":"Registrar","outputs":[],"type":"function"}, |
|||
{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_a","type":"address"},{"name":"_primary","type":"bool"}],"name":"setAddress","outputs":[],"type":"function"}, |
|||
{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_content","type":"bytes32"}],"name":"setContent","outputs":[],"type":"function"}, |
|||
{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"disown","outputs":[],"type":"function"}, |
|||
{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"register","outputs":[{"name":"","type":"address"}],"type":"function"}, |
|||
{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"}],"name":"Changed","type":"event"}, |
|||
{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"addr","type":"address"}],"name":"PrimaryChanged","type":"event"} |
|||
]; |
|||
|
|||
var depositAbi = [{"constant":false,"inputs":[{"name":"name","type":"bytes32"}],"name":"deposit","outputs":[],"type":"function"}]; |
|||
|
|||
var Namereg = web3.eth.contract(nameregAbi); |
|||
var Deposit = web3.eth.contract(depositAbi); |
|||
|
|||
var namereg = web3.eth.namereg; |
|||
var deposit; |
|||
var iban; |
|||
|
|||
function validateNamereg() { |
|||
var address = document.getElementById('namereg').value; |
|||
var ok = /^(0x)?[0-9a-f]{40}$/.test(address) || address === 'default'; |
|||
if (ok) { |
|||
namereg = address === 'default' ? web3.eth.namereg : Namereg.at(address); |
|||
document.getElementById('nameregValidation').innerText = 'ok!'; |
|||
} else { |
|||
document.getElementById('nameregValidation').innerText = 'namereg address is incorrect!'; |
|||
} |
|||
return ok; |
|||
}; |
|||
|
|||
function onNameregKeyUp() { |
|||
updateIBAN(validateNamereg()); |
|||
onExchangeKeyUp(); |
|||
}; |
|||
|
|||
function validateExchange() { |
|||
var exchange = document.getElementById('exchange').value; |
|||
var ok = /^[0-9A-Z]{4}$/.test(exchange); |
|||
if (ok) { |
|||
var address = namereg.addr(exchange); |
|||
deposit = Deposit.at(address); |
|||
document.getElementById('exchangeValidation').innerText = 'ok! address of exchange: ' + address; |
|||
} else { |
|||
document.getElementById('exchangeValidation').innerText = 'exchange id is incorrect'; |
|||
} |
|||
return ok; |
|||
}; |
|||
|
|||
function onExchangeKeyUp() { |
|||
updateIBAN(validateExchange()); |
|||
}; |
|||
|
|||
function validateClient() { |
|||
var client = document.getElementById('client').value; |
|||
var ok = /^[0-9A-Z]{9}$/.test(client); |
|||
if (ok) { |
|||
document.getElementById('clientValidation').innerText = 'ok!'; |
|||
} else { |
|||
document.getElementById('clientValidation').innerText = 'client id is incorrect'; |
|||
} |
|||
return ok; |
|||
}; |
|||
|
|||
function onClientKeyUp() { |
|||
updateIBAN(validateClient()); |
|||
}; |
|||
|
|||
function validateValue() { |
|||
try { |
|||
var value = document.getElementById('value').value; |
|||
var bnValue = new BigNumber(value); |
|||
document.getElementById('valueValidation').innerText = bnValue.toString(10); |
|||
return true; |
|||
} catch (err) { |
|||
document.getElementById('valueValidation').innerText = 'Value is incorrect, cannot parse'; |
|||
return false; |
|||
} |
|||
}; |
|||
|
|||
function onValueKeyUp() { |
|||
validateValue(); |
|||
}; |
|||
|
|||
function validateIBAN() { |
|||
if (!web3.isIBAN(iban)) { |
|||
return document.getElementById('ibanValidation').innerText = ' - IBAN number is incorrect'; |
|||
} |
|||
document.getElementById('ibanValidation').innerText = ' - IBAN number correct'; |
|||
}; |
|||
|
|||
function updateIBAN(ok) { |
|||
var exchangeId = document.getElementById('exchange').value; |
|||
var clientId = document.getElementById('client').value; |
|||
iban = 'XE' + '00' + 'ETH' + exchangeId + clientId; |
|||
document.getElementById('iban').innerText = iban; |
|||
validateIBAN(); |
|||
}; |
|||
|
|||
function transfer() { |
|||
var value = new BigNumber(document.getElementById('value').value); |
|||
var exchange = document.getElementById('exchange').value; |
|||
var client = document.getElementById('client').value; |
|||
deposit.deposit(client, {value: value}); |
|||
displayTransfer("deposited client's " + client + " funds " + value.toString(10) + " to exchange " + exchange); |
|||
}; |
|||
|
|||
function displayTransfer(text) { |
|||
var node = document.createElement('li'); |
|||
var textnode = document.createTextNode(text); |
|||
node.appendChild(textnode); |
|||
document.getElementById('transfers').appendChild(node); |
|||
} |
|||
|
|||
</script> |
|||
</head> |
|||
<body> |
|||
<h1>ICAP transfer</h1> |
|||
<div> |
|||
<h4>namereg address</h4> |
|||
</div> |
|||
<div> |
|||
<text>eg. 0x436474facc88948696b371052a1befb801f003ca or 'default')</text> |
|||
</div> |
|||
<div> |
|||
<input type="text" id="namereg" onkeyup='onNameregKeyUp()' value="default"></input> |
|||
<text id="nameregValidation"></text> |
|||
</div> |
|||
|
|||
<div> |
|||
<h4>exchange identifier</h4> |
|||
</div> |
|||
<div> |
|||
<text>eg. WYWY</text> |
|||
</div> |
|||
<div> |
|||
<input type="text" id="exchange" onkeyup='onExchangeKeyUp()'></input> |
|||
<text id="exchangeValidation"></text> |
|||
</div> |
|||
|
|||
<div> |
|||
<h4>client identifier</h4> |
|||
</div> |
|||
<div> |
|||
<text>eg. GAVOFYORK</text> |
|||
</div> |
|||
<div> |
|||
<input type="text" id="client" onkeyup='onClientKeyUp()'></input> |
|||
<text id="clientValidation"></text> |
|||
</div> |
|||
|
|||
<div> |
|||
<h4>value</h4> |
|||
</div> |
|||
<div> |
|||
<text>eg. 100</text> |
|||
</div> |
|||
<div> |
|||
<input type="text" id="value" onkeyup='onValueKeyUp()'></input> |
|||
<text id="valueValidation"></text> |
|||
</div> |
|||
|
|||
<div> </div> |
|||
<div> |
|||
<text>IBAN: </text> |
|||
<text id="iban"></text> |
|||
<text id="ibanValidation"></text> |
|||
</div> |
|||
<div> </div> |
|||
<div> |
|||
<button id="transfer" type="button" onClick="transfer()">Transfer!</button> |
|||
<text id="transferValidation"></text> |
|||
</div> |
|||
|
|||
<div> |
|||
<h4>transfers</h4> |
|||
</div> |
|||
<div> |
|||
<ul id='transfers'></ul> |
|||
</div> |
|||
</body> |
|||
</html> |
@ -1,102 +0,0 @@ |
|||
<!doctype> |
|||
<html> |
|||
|
|||
<head> |
|||
<script type="text/javascript" src="../dist/web3.js"></script> |
|||
<script type="text/javascript"> |
|||
|
|||
var web3 = require('web3'); |
|||
web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545")); |
|||
var from = web3.eth.coinbase; |
|||
web3.eth.defaultAccount = from; |
|||
|
|||
window.onload = function () { |
|||
var filter = web3.eth.namereg.Changed(); |
|||
filter.watch(function (err, event) { |
|||
// live update all fields |
|||
onAddressKeyUp(); |
|||
onNameKeyUp(); |
|||
onRegisterOwnerKeyUp(); |
|||
}); |
|||
}; |
|||
|
|||
function registerOwner() { |
|||
var name = document.getElementById('registerOwner').value; |
|||
web3.eth.namereg.reserve(name); |
|||
document.getElementById('nameAvailability').innerText += ' Registering name in progress, please wait...'; |
|||
}; |
|||
|
|||
function changeAddress() { |
|||
var name = document.getElementById('registerOwner').value; |
|||
var address = document.getElementById('newAddress').value; |
|||
web3.eth.namereg.setAddress(name, address, true); |
|||
document.getElementById('currentAddress').innerText += ' Changing address in progress. Please wait.'; |
|||
}; |
|||
|
|||
function onRegisterOwnerKeyUp() { |
|||
var name = document.getElementById('registerOwner').value; |
|||
var owner = web3.eth.namereg.owner(name) |
|||
document.getElementById('currentAddress').innerText = web3.eth.namereg.addr(name); |
|||
if (owner !== '0x0000000000000000000000000000000000000000') { |
|||
if (owner === from) { |
|||
document.getElementById('nameAvailability').innerText = "This name is already owned by you " + owner; |
|||
} else { |
|||
document.getElementById('nameAvailability').innerText = "This name is not available. It's already registered by " + owner; |
|||
} |
|||
return; |
|||
} |
|||
document.getElementById('nameAvailability').innerText = "This name is available. You can register it."; |
|||
}; |
|||
|
|||
function onAddressKeyUp() { |
|||
var address = document.getElementById('address').value; |
|||
document.getElementById('nameOf').innerText = web3.eth.namereg.name(address); |
|||
}; |
|||
|
|||
function onNameKeyUp() { |
|||
var name = document.getElementById('name').value; |
|||
document.getElementById('addressOf').innerText = web3.eth.namereg.addr(name); |
|||
}; |
|||
|
|||
</script> |
|||
</head> |
|||
<body> |
|||
<i>This example shows only part of namereg functionalities. Namereg contract is available <a href="https://github.com/ethereum/dapp-bin/blob/master/GlobalRegistrar/contract.sol">here</a> |
|||
</i> |
|||
<h1>Namereg</h1> |
|||
<h3>Search for name</h3> |
|||
<div> |
|||
<text>Address: </text> |
|||
<input type="text" id="address" onkeyup='onAddressKeyUp()'></input> |
|||
<text>Name: </text> |
|||
<text id="nameOf"></text> |
|||
</div> |
|||
<h3>Search for address</h3> |
|||
<div> |
|||
<text>Name: </text> |
|||
<input type="text" id="name" onkeyup='onNameKeyUp()'></input> |
|||
<text>Address: </text> |
|||
<text id="addressOf"></text> |
|||
</div> |
|||
<h3>Register name</h3> |
|||
<div> |
|||
<text>Check if name is available: </text> |
|||
<input type="text" id="registerOwner" onkeyup='onRegisterOwnerKeyUp()'></input> |
|||
<text id='nameAvailability'></text> |
|||
</div> |
|||
<div> |
|||
<button id="registerOwnerButton" type="button" onClick="registerOwner()">Register!</button> |
|||
</div> |
|||
<h3></h3> |
|||
<i>If you own the name, you can also change the address it points to</i> |
|||
<div> |
|||
<text>Address: </text> |
|||
<input type="text" id="newAddress"></input> |
|||
<button id="changeAddress" type="button" onClick="changeAddress()">Change address!</button> |
|||
<text>Current address :</text> |
|||
<text id="currentAddress"></text> |
|||
</div> |
|||
|
|||
</body> |
|||
</html> |
|||
|
@ -1,12 +0,0 @@ |
|||
#!/usr/bin/env node
|
|||
|
|||
var web3 = require("../index.js"); |
|||
|
|||
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545')); |
|||
|
|||
var coinbase = web3.eth.coinbase; |
|||
console.log(coinbase); |
|||
|
|||
var balance = web3.eth.getBalance(coinbase); |
|||
console.log(balance.toString(10)); |
|||
|
@ -1,96 +0,0 @@ |
|||
#!/usr/bin/env node
|
|||
|
|||
'use strict'; |
|||
|
|||
var version = require('./lib/version.json'); |
|||
var path = require('path'); |
|||
|
|||
var del = require('del'); |
|||
var gulp = require('gulp'); |
|||
var browserify = require('browserify'); |
|||
var jshint = require('gulp-jshint'); |
|||
var uglify = require('gulp-uglify'); |
|||
var rename = require('gulp-rename'); |
|||
var source = require('vinyl-source-stream'); |
|||
var exorcist = require('exorcist'); |
|||
var bower = require('bower'); |
|||
var streamify = require('gulp-streamify'); |
|||
var replace = require('gulp-replace'); |
|||
|
|||
var DEST = path.join(__dirname, 'dist/'); |
|||
var src = 'index'; |
|||
var dst = 'web3'; |
|||
var lightDst = 'web3-light'; |
|||
|
|||
var browserifyOptions = { |
|||
debug: true, |
|||
insert_global_vars: false, // jshint ignore:line
|
|||
detectGlobals: false, |
|||
bundleExternal: true |
|||
}; |
|||
|
|||
gulp.task('version', function(){ |
|||
gulp.src(['./package.json']) |
|||
.pipe(replace(/\"version\"\: \"(.{5})\"/, '"version": "'+ version.version + '"')) |
|||
.pipe(gulp.dest('./')); |
|||
gulp.src(['./bower.json']) |
|||
.pipe(replace(/\"version\"\: \"(.{5})\"/, '"version": "'+ version.version + '"')) |
|||
.pipe(gulp.dest('./')); |
|||
gulp.src(['./package.js']) |
|||
.pipe(replace(/version\: \'(.{5})\'/, "version: '"+ version.version + "'")) |
|||
.pipe(gulp.dest('./')); |
|||
}); |
|||
|
|||
gulp.task('bower', ['version'], function(cb){ |
|||
bower.commands.install().on('end', function (installed){ |
|||
console.log(installed); |
|||
cb(); |
|||
}); |
|||
}); |
|||
|
|||
gulp.task('lint', ['bower'], function(){ |
|||
return gulp.src(['./*.js', './lib/*.js']) |
|||
.pipe(jshint()) |
|||
.pipe(jshint.reporter('default')); |
|||
}); |
|||
|
|||
gulp.task('clean', ['lint'], function(cb) { |
|||
del([ DEST ], cb); |
|||
}); |
|||
|
|||
gulp.task('light', ['clean'], function () { |
|||
return browserify(browserifyOptions) |
|||
.require('./' + src + '.js', {expose: 'web3'}) |
|||
.ignore('bignumber.js') |
|||
.require('./lib/utils/browser-bn.js', {expose: 'bignumber.js'}) // fake bignumber.js
|
|||
.add('./' + src + '.js') |
|||
.bundle() |
|||
.pipe(exorcist(path.join( DEST, lightDst + '.js.map'))) |
|||
.pipe(source(lightDst + '.js')) |
|||
.pipe(gulp.dest( DEST )) |
|||
.pipe(streamify(uglify())) |
|||
.pipe(rename(lightDst + '.min.js')) |
|||
.pipe(gulp.dest( DEST )); |
|||
}); |
|||
|
|||
gulp.task('standalone', ['clean'], function () { |
|||
return browserify(browserifyOptions) |
|||
.require('./' + src + '.js', {expose: 'web3'}) |
|||
.require('bignumber.js') // expose it to dapp users
|
|||
.add('./' + src + '.js') |
|||
.ignore('crypto') |
|||
.bundle() |
|||
.pipe(exorcist(path.join( DEST, dst + '.js.map'))) |
|||
.pipe(source(dst + '.js')) |
|||
.pipe(gulp.dest( DEST )) |
|||
.pipe(streamify(uglify())) |
|||
.pipe(rename(dst + '.min.js')) |
|||
.pipe(gulp.dest( DEST )); |
|||
}); |
|||
|
|||
gulp.task('watch', function() { |
|||
gulp.watch(['./lib/*.js'], ['lint', 'build']); |
|||
}); |
|||
|
|||
gulp.task('default', ['version', 'bower', 'lint', 'clean', 'light', 'standalone']); |
|||
|
@ -1,16 +0,0 @@ |
|||
var web3 = require('./lib/web3'); |
|||
|
|||
web3.providers.HttpProvider = require('./lib/web3/httpprovider'); |
|||
web3.providers.IpcProvider = require('./lib/web3/ipcprovider'); |
|||
|
|||
web3.eth.contract = require('./lib/web3/contract'); |
|||
web3.eth.namereg = require('./lib/web3/namereg'); |
|||
web3.eth.sendIBANTransaction = require('./lib/web3/transfer'); |
|||
|
|||
// dont override global variable
|
|||
if (typeof window !== 'undefined' && typeof window.web3 === 'undefined') { |
|||
window.web3 = web3; |
|||
} |
|||
|
|||
module.exports = web3; |
|||
|
@ -1,289 +0,0 @@ |
|||
/* |
|||
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 coder.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var BigNumber = require('bignumber.js'); |
|||
var utils = require('../utils/utils'); |
|||
var f = require('./formatters'); |
|||
var SolidityParam = require('./param'); |
|||
|
|||
/** |
|||
* Should be used to check if a type is an array type |
|||
* |
|||
* @method isArrayType |
|||
* @param {String} type |
|||
* @return {Bool} true is the type is an array, otherwise false |
|||
*/ |
|||
var isArrayType = function (type) { |
|||
return type.slice(-2) === '[]'; |
|||
}; |
|||
|
|||
/** |
|||
* SolidityType prototype is used to encode/decode solidity params of certain type |
|||
*/ |
|||
var SolidityType = function (config) { |
|||
this._name = config.name; |
|||
this._match = config.match; |
|||
this._mode = config.mode; |
|||
this._inputFormatter = config.inputFormatter; |
|||
this._outputFormatter = config.outputFormatter; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to determine if this SolidityType do match given type |
|||
* |
|||
* @method isType |
|||
* @param {String} name |
|||
* @return {Bool} true if type match this SolidityType, otherwise false |
|||
*/ |
|||
SolidityType.prototype.isType = function (name) { |
|||
if (this._match === 'strict') { |
|||
return this._name === name || (name.indexOf(this._name) === 0 && name.slice(this._name.length) === '[]'); |
|||
} else if (this._match === 'prefix') { |
|||
// TODO better type detection!
|
|||
return name.indexOf(this._name) === 0; |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to transform plain param to SolidityParam object |
|||
* |
|||
* @method formatInput |
|||
* @param {Object} param - plain object, or an array of objects |
|||
* @param {Bool} arrayType - true if a param should be encoded as an array |
|||
* @return {SolidityParam} encoded param wrapped in SolidityParam object |
|||
*/ |
|||
SolidityType.prototype.formatInput = function (param, arrayType) { |
|||
if (utils.isArray(param) && arrayType) { // TODO: should fail if this two are not the same
|
|||
var self = this; |
|||
return param.map(function (p) { |
|||
return self._inputFormatter(p); |
|||
}).reduce(function (acc, current) { |
|||
return acc.combine(current); |
|||
}, f.formatInputInt(param.length)).withOffset(32); |
|||
} |
|||
return this._inputFormatter(param); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to transoform SolidityParam to plain param |
|||
* |
|||
* @method formatOutput |
|||
* @param {SolidityParam} byteArray |
|||
* @param {Bool} arrayType - true if a param should be decoded as an array |
|||
* @return {Object} plain decoded param |
|||
*/ |
|||
SolidityType.prototype.formatOutput = function (param, arrayType) { |
|||
if (arrayType) { |
|||
// let's assume, that we solidity will never return long arrays :P
|
|||
var result = []; |
|||
var length = new BigNumber(param.dynamicPart().slice(0, 64), 16); |
|||
for (var i = 0; i < length * 64; i += 64) { |
|||
result.push(this._outputFormatter(new SolidityParam(param.dynamicPart().substr(i + 64, 64)))); |
|||
} |
|||
return result; |
|||
} |
|||
return this._outputFormatter(param); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to slice single param from bytes |
|||
* |
|||
* @method sliceParam |
|||
* @param {String} bytes |
|||
* @param {Number} index of param to slice |
|||
* @param {String} type |
|||
* @returns {SolidityParam} param |
|||
*/ |
|||
SolidityType.prototype.sliceParam = function (bytes, index, type) { |
|||
if (this._mode === 'bytes') { |
|||
return SolidityParam.decodeBytes(bytes, index); |
|||
} else if (isArrayType(type)) { |
|||
return SolidityParam.decodeArray(bytes, index); |
|||
} |
|||
return SolidityParam.decodeParam(bytes, index); |
|||
}; |
|||
|
|||
/** |
|||
* SolidityCoder prototype should be used to encode/decode solidity params of any type |
|||
*/ |
|||
var SolidityCoder = function (types) { |
|||
this._types = types; |
|||
}; |
|||
|
|||
/** |
|||
* This method should be used to transform type to SolidityType |
|||
* |
|||
* @method _requireType |
|||
* @param {String} type |
|||
* @returns {SolidityType} |
|||
* @throws {Error} throws if no matching type is found |
|||
*/ |
|||
SolidityCoder.prototype._requireType = function (type) { |
|||
var solidityType = this._types.filter(function (t) { |
|||
return t.isType(type); |
|||
})[0]; |
|||
|
|||
if (!solidityType) { |
|||
throw Error('invalid solidity type!: ' + type); |
|||
} |
|||
|
|||
return solidityType; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to transform plain param of given type to SolidityParam |
|||
* |
|||
* @method _formatInput |
|||
* @param {String} type of param |
|||
* @param {Object} plain param |
|||
* @return {SolidityParam} |
|||
*/ |
|||
SolidityCoder.prototype._formatInput = function (type, param) { |
|||
return this._requireType(type).formatInput(param, isArrayType(type)); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to encode plain param |
|||
* |
|||
* @method encodeParam |
|||
* @param {String} type |
|||
* @param {Object} plain param |
|||
* @return {String} encoded plain param |
|||
*/ |
|||
SolidityCoder.prototype.encodeParam = function (type, param) { |
|||
return this._formatInput(type, param).encode(); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to encode list of params |
|||
* |
|||
* @method encodeParams |
|||
* @param {Array} types |
|||
* @param {Array} params |
|||
* @return {String} encoded list of params |
|||
*/ |
|||
SolidityCoder.prototype.encodeParams = function (types, params) { |
|||
var self = this; |
|||
var solidityParams = types.map(function (type, index) { |
|||
return self._formatInput(type, params[index]); |
|||
}); |
|||
|
|||
return SolidityParam.encodeList(solidityParams); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to decode bytes to plain param |
|||
* |
|||
* @method decodeParam |
|||
* @param {String} type |
|||
* @param {String} bytes |
|||
* @return {Object} plain param |
|||
*/ |
|||
SolidityCoder.prototype.decodeParam = function (type, bytes) { |
|||
return this.decodeParams([type], bytes)[0]; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to decode list of params |
|||
* |
|||
* @method decodeParam |
|||
* @param {Array} types |
|||
* @param {String} bytes |
|||
* @return {Array} array of plain params |
|||
*/ |
|||
SolidityCoder.prototype.decodeParams = function (types, bytes) { |
|||
var self = this; |
|||
return types.map(function (type, index) { |
|||
var solidityType = self._requireType(type); |
|||
var p = solidityType.sliceParam(bytes, index, type); |
|||
return solidityType.formatOutput(p, isArrayType(type)); |
|||
}); |
|||
}; |
|||
|
|||
var coder = new SolidityCoder([ |
|||
new SolidityType({ |
|||
name: 'address', |
|||
match: 'strict', |
|||
mode: 'value', |
|||
inputFormatter: f.formatInputInt, |
|||
outputFormatter: f.formatOutputAddress |
|||
}), |
|||
new SolidityType({ |
|||
name: 'bool', |
|||
match: 'strict', |
|||
mode: 'value', |
|||
inputFormatter: f.formatInputBool, |
|||
outputFormatter: f.formatOutputBool |
|||
}), |
|||
new SolidityType({ |
|||
name: 'int', |
|||
match: 'prefix', |
|||
mode: 'value', |
|||
inputFormatter: f.formatInputInt, |
|||
outputFormatter: f.formatOutputInt, |
|||
}), |
|||
new SolidityType({ |
|||
name: 'uint', |
|||
match: 'prefix', |
|||
mode: 'value', |
|||
inputFormatter: f.formatInputInt, |
|||
outputFormatter: f.formatOutputUInt |
|||
}), |
|||
new SolidityType({ |
|||
name: 'bytes', |
|||
match: 'strict', |
|||
mode: 'bytes', |
|||
inputFormatter: f.formatInputDynamicBytes, |
|||
outputFormatter: f.formatOutputDynamicBytes |
|||
}), |
|||
new SolidityType({ |
|||
name: 'bytes', |
|||
match: 'prefix', |
|||
mode: 'value', |
|||
inputFormatter: f.formatInputBytes, |
|||
outputFormatter: f.formatOutputBytes |
|||
}), |
|||
new SolidityType({ |
|||
name: 'string', |
|||
match: 'strict', |
|||
mode: 'bytes', |
|||
inputFormatter: f.formatInputString, |
|||
outputFormatter: f.formatOutputString |
|||
}), |
|||
new SolidityType({ |
|||
name: 'real', |
|||
match: 'prefix', |
|||
mode: 'value', |
|||
inputFormatter: f.formatInputReal, |
|||
outputFormatter: f.formatOutputReal |
|||
}), |
|||
new SolidityType({ |
|||
name: 'ureal', |
|||
match: 'prefix', |
|||
mode: 'value', |
|||
inputFormatter: f.formatInputReal, |
|||
outputFormatter: f.formatOutputUReal |
|||
}) |
|||
]); |
|||
|
|||
module.exports = coder; |
|||
|
@ -1,248 +0,0 @@ |
|||
/* |
|||
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 formatters.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var BigNumber = require('bignumber.js'); |
|||
var utils = require('../utils/utils'); |
|||
var c = require('../utils/config'); |
|||
var SolidityParam = require('./param'); |
|||
|
|||
|
|||
/** |
|||
* Formats input value to byte representation of int |
|||
* If value is negative, return it's two's complement |
|||
* If the value is floating point, round it down |
|||
* |
|||
* @method formatInputInt |
|||
* @param {String|Number|BigNumber} value that needs to be formatted |
|||
* @returns {SolidityParam} |
|||
*/ |
|||
var formatInputInt = function (value) { |
|||
var padding = c.ETH_PADDING * 2; |
|||
BigNumber.config(c.ETH_BIGNUMBER_ROUNDING_MODE); |
|||
var result = utils.padLeft(utils.toTwosComplement(value).round().toString(16), padding); |
|||
return new SolidityParam(result); |
|||
}; |
|||
|
|||
/** |
|||
* Formats input bytes |
|||
* |
|||
* @method formatInputBytes |
|||
* @param {String} |
|||
* @returns {SolidityParam} |
|||
*/ |
|||
var formatInputBytes = function (value) { |
|||
var result = utils.padRight(utils.toHex(value).substr(2), 64); |
|||
return new SolidityParam(result); |
|||
}; |
|||
|
|||
/** |
|||
* Formats input bytes |
|||
* |
|||
* @method formatDynamicInputBytes |
|||
* @param {String} |
|||
* @returns {SolidityParam} |
|||
*/ |
|||
var formatInputDynamicBytes = function (value) { |
|||
value = utils.toHex(value).substr(2); |
|||
var l = Math.floor((value.length + 63) / 64); |
|||
var result = utils.padRight(value, l * 64); |
|||
var length = Math.floor(value.length / 2); |
|||
return new SolidityParam(formatInputInt(length).value + result, 32); |
|||
}; |
|||
|
|||
/** |
|||
* Formats input value to byte representation of string |
|||
* |
|||
* @method formatInputString |
|||
* @param {String} |
|||
* @returns {SolidityParam} |
|||
*/ |
|||
var formatInputString = function (value) { |
|||
var result = utils.fromAscii(value).substr(2); |
|||
var l = Math.floor((result.length + 63) / 64); |
|||
result = utils.padRight(result, l * 64); |
|||
return new SolidityParam(formatInputInt(value.length).value + result, 32); |
|||
}; |
|||
|
|||
/** |
|||
* Formats input value to byte representation of bool |
|||
* |
|||
* @method formatInputBool |
|||
* @param {Boolean} |
|||
* @returns {SolidityParam} |
|||
*/ |
|||
var formatInputBool = function (value) { |
|||
var result = '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0'); |
|||
return new SolidityParam(result); |
|||
}; |
|||
|
|||
/** |
|||
* Formats input value to byte representation of real |
|||
* Values are multiplied by 2^m and encoded as integers |
|||
* |
|||
* @method formatInputReal |
|||
* @param {String|Number|BigNumber} |
|||
* @returns {SolidityParam} |
|||
*/ |
|||
var formatInputReal = function (value) { |
|||
return formatInputInt(new BigNumber(value).times(new BigNumber(2).pow(128))); |
|||
}; |
|||
|
|||
/** |
|||
* Check if input value is negative |
|||
* |
|||
* @method signedIsNegative |
|||
* @param {String} value is hex format |
|||
* @returns {Boolean} true if it is negative, otherwise false |
|||
*/ |
|||
var signedIsNegative = function (value) { |
|||
return (new BigNumber(value.substr(0, 1), 16).toString(2).substr(0, 1)) === '1'; |
|||
}; |
|||
|
|||
/** |
|||
* Formats right-aligned output bytes to int |
|||
* |
|||
* @method formatOutputInt |
|||
* @param {SolidityParam} param |
|||
* @returns {BigNumber} right-aligned output bytes formatted to big number |
|||
*/ |
|||
var formatOutputInt = function (param) { |
|||
var value = param.staticPart() || "0"; |
|||
|
|||
// check if it's negative number
|
|||
// it it is, return two's complement
|
|||
if (signedIsNegative(value)) { |
|||
return new BigNumber(value, 16).minus(new BigNumber('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)).minus(1); |
|||
} |
|||
return new BigNumber(value, 16); |
|||
}; |
|||
|
|||
/** |
|||
* Formats right-aligned output bytes to uint |
|||
* |
|||
* @method formatOutputUInt |
|||
* @param {SolidityParam} |
|||
* @returns {BigNumeber} right-aligned output bytes formatted to uint |
|||
*/ |
|||
var formatOutputUInt = function (param) { |
|||
var value = param.staticPart() || "0"; |
|||
return new BigNumber(value, 16); |
|||
}; |
|||
|
|||
/** |
|||
* Formats right-aligned output bytes to real |
|||
* |
|||
* @method formatOutputReal |
|||
* @param {SolidityParam} |
|||
* @returns {BigNumber} input bytes formatted to real |
|||
*/ |
|||
var formatOutputReal = function (param) { |
|||
return formatOutputInt(param).dividedBy(new BigNumber(2).pow(128)); |
|||
}; |
|||
|
|||
/** |
|||
* Formats right-aligned output bytes to ureal |
|||
* |
|||
* @method formatOutputUReal |
|||
* @param {SolidityParam} |
|||
* @returns {BigNumber} input bytes formatted to ureal |
|||
*/ |
|||
var formatOutputUReal = function (param) { |
|||
return formatOutputUInt(param).dividedBy(new BigNumber(2).pow(128)); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to format output bool |
|||
* |
|||
* @method formatOutputBool |
|||
* @param {SolidityParam} |
|||
* @returns {Boolean} right-aligned input bytes formatted to bool |
|||
*/ |
|||
var formatOutputBool = function (param) { |
|||
return param.staticPart() === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to format output bytes |
|||
* |
|||
* @method formatOutputBytes |
|||
* @param {SolidityParam} left-aligned hex representation of string |
|||
* @returns {String} hex string |
|||
*/ |
|||
var formatOutputBytes = function (param) { |
|||
return '0x' + param.staticPart(); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to format output bytes |
|||
* |
|||
* @method formatOutputDynamicBytes |
|||
* @param {SolidityParam} left-aligned hex representation of string |
|||
* @returns {String} hex string |
|||
*/ |
|||
var formatOutputDynamicBytes = function (param) { |
|||
var length = (new BigNumber(param.dynamicPart().slice(0, 64), 16)).toNumber() * 2; |
|||
return '0x' + param.dynamicPart().substr(64, length); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to format output string |
|||
* |
|||
* @method formatOutputString |
|||
* @param {SolidityParam} left-aligned hex representation of string |
|||
* @returns {String} ascii string |
|||
*/ |
|||
var formatOutputString = function (param) { |
|||
var length = (new BigNumber(param.dynamicPart().slice(0, 64), 16)).toNumber() * 2; |
|||
return utils.toAscii(param.dynamicPart().substr(64, length)); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to format output address |
|||
* |
|||
* @method formatOutputAddress |
|||
* @param {SolidityParam} right-aligned input bytes |
|||
* @returns {String} address |
|||
*/ |
|||
var formatOutputAddress = function (param) { |
|||
var value = param.staticPart(); |
|||
return "0x" + value.slice(value.length - 40, value.length); |
|||
}; |
|||
|
|||
module.exports = { |
|||
formatInputInt: formatInputInt, |
|||
formatInputBytes: formatInputBytes, |
|||
formatInputDynamicBytes: formatInputDynamicBytes, |
|||
formatInputString: formatInputString, |
|||
formatInputBool: formatInputBool, |
|||
formatInputReal: formatInputReal, |
|||
formatOutputInt: formatOutputInt, |
|||
formatOutputUInt: formatOutputUInt, |
|||
formatOutputReal: formatOutputReal, |
|||
formatOutputUReal: formatOutputUReal, |
|||
formatOutputBool: formatOutputBool, |
|||
formatOutputBytes: formatOutputBytes, |
|||
formatOutputDynamicBytes: formatOutputDynamicBytes, |
|||
formatOutputString: formatOutputString, |
|||
formatOutputAddress: formatOutputAddress |
|||
}; |
|||
|
@ -1,211 +0,0 @@ |
|||
/* |
|||
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 param.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var utils = require('../utils/utils'); |
|||
|
|||
/** |
|||
* SolidityParam object prototype. |
|||
* Should be used when encoding, decoding solidity bytes |
|||
*/ |
|||
var SolidityParam = function (value, offset) { |
|||
this.value = value || ''; |
|||
this.offset = offset; // offset in bytes
|
|||
}; |
|||
|
|||
/** |
|||
* This method should be used to get length of params's dynamic part |
|||
* |
|||
* @method dynamicPartLength |
|||
* @returns {Number} length of dynamic part (in bytes) |
|||
*/ |
|||
SolidityParam.prototype.dynamicPartLength = function () { |
|||
return this.dynamicPart().length / 2; |
|||
}; |
|||
|
|||
/** |
|||
* This method should be used to create copy of solidity param with different offset |
|||
* |
|||
* @method withOffset |
|||
* @param {Number} offset length in bytes |
|||
* @returns {SolidityParam} new solidity param with applied offset |
|||
*/ |
|||
SolidityParam.prototype.withOffset = function (offset) { |
|||
return new SolidityParam(this.value, offset); |
|||
}; |
|||
|
|||
/** |
|||
* This method should be used to combine solidity params together |
|||
* eg. when appending an array |
|||
* |
|||
* @method combine |
|||
* @param {SolidityParam} param with which we should combine |
|||
* @param {SolidityParam} result of combination |
|||
*/ |
|||
SolidityParam.prototype.combine = function (param) { |
|||
return new SolidityParam(this.value + param.value); |
|||
}; |
|||
|
|||
/** |
|||
* This method should be called to check if param has dynamic size. |
|||
* If it has, it returns true, otherwise false |
|||
* |
|||
* @method isDynamic |
|||
* @returns {Boolean} |
|||
*/ |
|||
SolidityParam.prototype.isDynamic = function () { |
|||
return this.value.length > 64 || this.offset !== undefined; |
|||
}; |
|||
|
|||
/** |
|||
* This method should be called to transform offset to bytes |
|||
* |
|||
* @method offsetAsBytes |
|||
* @returns {String} bytes representation of offset |
|||
*/ |
|||
SolidityParam.prototype.offsetAsBytes = function () { |
|||
return !this.isDynamic() ? '' : utils.padLeft(utils.toTwosComplement(this.offset).toString(16), 64); |
|||
}; |
|||
|
|||
/** |
|||
* This method should be called to get static part of param |
|||
* |
|||
* @method staticPart |
|||
* @returns {String} offset if it is a dynamic param, otherwise value |
|||
*/ |
|||
SolidityParam.prototype.staticPart = function () { |
|||
if (!this.isDynamic()) { |
|||
return this.value; |
|||
} |
|||
return this.offsetAsBytes(); |
|||
}; |
|||
|
|||
/** |
|||
* This method should be called to get dynamic part of param |
|||
* |
|||
* @method dynamicPart |
|||
* @returns {String} returns a value if it is a dynamic param, otherwise empty string |
|||
*/ |
|||
SolidityParam.prototype.dynamicPart = function () { |
|||
return this.isDynamic() ? this.value : ''; |
|||
}; |
|||
|
|||
/** |
|||
* This method should be called to encode param |
|||
* |
|||
* @method encode |
|||
* @returns {String} |
|||
*/ |
|||
SolidityParam.prototype.encode = function () { |
|||
return this.staticPart() + this.dynamicPart(); |
|||
}; |
|||
|
|||
/** |
|||
* This method should be called to encode array of params |
|||
* |
|||
* @method encodeList |
|||
* @param {Array[SolidityParam]} params |
|||
* @returns {String} |
|||
*/ |
|||
SolidityParam.encodeList = function (params) { |
|||
|
|||
// updating offsets
|
|||
var totalOffset = params.length * 32; |
|||
var offsetParams = params.map(function (param) { |
|||
if (!param.isDynamic()) { |
|||
return param; |
|||
} |
|||
var offset = totalOffset; |
|||
totalOffset += param.dynamicPartLength(); |
|||
return param.withOffset(offset); |
|||
}); |
|||
|
|||
// encode everything!
|
|||
return offsetParams.reduce(function (result, param) { |
|||
return result + param.dynamicPart(); |
|||
}, offsetParams.reduce(function (result, param) { |
|||
return result + param.staticPart(); |
|||
}, '')); |
|||
}; |
|||
|
|||
/** |
|||
* This method should be used to decode plain (static) solidity param at given index |
|||
* |
|||
* @method decodeParam |
|||
* @param {String} bytes |
|||
* @param {Number} index |
|||
* @returns {SolidityParam} |
|||
*/ |
|||
SolidityParam.decodeParam = function (bytes, index) { |
|||
index = index || 0; |
|||
return new SolidityParam(bytes.substr(index * 64, 64)); |
|||
}; |
|||
|
|||
/** |
|||
* This method should be called to get offset value from bytes at given index |
|||
* |
|||
* @method getOffset |
|||
* @param {String} bytes |
|||
* @param {Number} index |
|||
* @returns {Number} offset as number |
|||
*/ |
|||
var getOffset = function (bytes, index) { |
|||
// we can do this cause offset is rather small
|
|||
return parseInt('0x' + bytes.substr(index * 64, 64)); |
|||
}; |
|||
|
|||
/** |
|||
* This method should be called to decode solidity bytes param at given index |
|||
* |
|||
* @method decodeBytes |
|||
* @param {String} bytes |
|||
* @param {Number} index |
|||
* @returns {SolidityParam} |
|||
*/ |
|||
SolidityParam.decodeBytes = function (bytes, index) { |
|||
index = index || 0; |
|||
|
|||
var offset = getOffset(bytes, index); |
|||
|
|||
var l = parseInt('0x' + bytes.substr(offset * 2, 64)); |
|||
l = Math.floor((l + 31) / 32); |
|||
|
|||
// (1 + l) * , cause we also parse length
|
|||
return new SolidityParam(bytes.substr(offset * 2, (1 + l) * 64), 0); |
|||
}; |
|||
|
|||
/** |
|||
* This method should be used to decode solidity array at given index |
|||
* |
|||
* @method decodeArray |
|||
* @param {String} bytes |
|||
* @param {Number} index |
|||
* @returns {SolidityParam} |
|||
*/ |
|||
SolidityParam.decodeArray = function (bytes, index) { |
|||
index = index || 0; |
|||
var offset = getOffset(bytes, index); |
|||
var length = parseInt('0x' + bytes.substr(offset * 2, 64)); |
|||
return new SolidityParam(bytes.substr(offset * 2, (length + 1) * 64), 0); |
|||
}; |
|||
|
|||
module.exports = SolidityParam; |
|||
|
@ -1,4 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
module.exports = BigNumber; // jshint ignore:line
|
|||
|
@ -1,9 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
// go env doesn't have and need XMLHttpRequest
|
|||
if (typeof XMLHttpRequest === 'undefined') { |
|||
exports.XMLHttpRequest = {}; |
|||
} else { |
|||
exports.XMLHttpRequest = XMLHttpRequest; // jshint ignore:line
|
|||
} |
|||
|
@ -1,78 +0,0 @@ |
|||
/* |
|||
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 config.js |
|||
* @authors: |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
/** |
|||
* Utils |
|||
* |
|||
* @module utils |
|||
*/ |
|||
|
|||
/** |
|||
* Utility functions |
|||
* |
|||
* @class [utils] config |
|||
* @constructor |
|||
*/ |
|||
|
|||
/// required to define ETH_BIGNUMBER_ROUNDING_MODE
|
|||
var BigNumber = require('bignumber.js'); |
|||
|
|||
var ETH_UNITS = [ |
|||
'wei', |
|||
'kwei', |
|||
'Mwei', |
|||
'Gwei', |
|||
'szabo', |
|||
'finney', |
|||
'femtoether', |
|||
'picoether', |
|||
'nanoether', |
|||
'microether', |
|||
'milliether', |
|||
'nano', |
|||
'micro', |
|||
'milli', |
|||
'ether', |
|||
'grand', |
|||
'Mether', |
|||
'Gether', |
|||
'Tether', |
|||
'Pether', |
|||
'Eether', |
|||
'Zether', |
|||
'Yether', |
|||
'Nether', |
|||
'Dether', |
|||
'Vether', |
|||
'Uether' |
|||
]; |
|||
|
|||
module.exports = { |
|||
ETH_PADDING: 32, |
|||
ETH_SIGNATURE_LENGTH: 4, |
|||
ETH_UNITS: ETH_UNITS, |
|||
ETH_BIGNUMBER_ROUNDING_MODE: { ROUNDING_MODE: BigNumber.ROUND_DOWN }, |
|||
ETH_POLLING_TIMEOUT: 1000/2, |
|||
defaultBlock: 'latest', |
|||
defaultAccount: undefined |
|||
}; |
|||
|
@ -1,39 +0,0 @@ |
|||
/* |
|||
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 sha3.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var utils = require('./utils'); |
|||
var sha3 = require('crypto-js/sha3'); |
|||
|
|||
module.exports = function (str, isNew) { |
|||
if (str.substr(0, 2) === '0x' && !isNew) { |
|||
console.warn('requirement of using web3.fromAscii before sha3 is deprecated'); |
|||
console.warn('new usage: \'web3.sha3("hello")\''); |
|||
console.warn('see https://github.com/ethereum/web3.js/pull/205'); |
|||
console.warn('if you need to hash hex value, you can do \'sha3("0xfff", true)\''); |
|||
str = utils.toAscii(str); |
|||
} |
|||
|
|||
return sha3(str, { |
|||
outputLength: 256 |
|||
}).toString(); |
|||
}; |
|||
|
@ -1,510 +0,0 @@ |
|||
/* |
|||
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 utils.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
/** |
|||
* Utils |
|||
* |
|||
* @module utils |
|||
*/ |
|||
|
|||
/** |
|||
* Utility functions |
|||
* |
|||
* @class [utils] utils |
|||
* @constructor |
|||
*/ |
|||
|
|||
var BigNumber = require('bignumber.js'); |
|||
|
|||
var unitMap = { |
|||
'wei': '1', |
|||
'kwei': '1000', |
|||
'ada': '1000', |
|||
'femtoether': '1000', |
|||
'mwei': '1000000', |
|||
'babbage': '1000000', |
|||
'picoether': '1000000', |
|||
'gwei': '1000000000', |
|||
'shannon': '1000000000', |
|||
'nanoether': '1000000000', |
|||
'nano': '1000000000', |
|||
'szabo': '1000000000000', |
|||
'microether': '1000000000000', |
|||
'micro': '1000000000000', |
|||
'finney': '1000000000000000', |
|||
'milliether': '1000000000000000', |
|||
'milli': '1000000000000000', |
|||
'ether': '1000000000000000000', |
|||
'kether': '1000000000000000000000', |
|||
'grand': '1000000000000000000000', |
|||
'einstein': '1000000000000000000000', |
|||
'mether': '1000000000000000000000000', |
|||
'gether': '1000000000000000000000000000', |
|||
'tether': '1000000000000000000000000000000' |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to pad string to expected length |
|||
* |
|||
* @method padLeft |
|||
* @param {String} string to be padded |
|||
* @param {Number} characters that result string should have |
|||
* @param {String} sign, by default 0 |
|||
* @returns {String} right aligned string |
|||
*/ |
|||
var padLeft = function (string, chars, sign) { |
|||
return new Array(chars - string.length + 1).join(sign ? sign : "0") + string; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to pad string to expected length |
|||
* |
|||
* @method padRight |
|||
* @param {String} string to be padded |
|||
* @param {Number} characters that result string should have |
|||
* @param {String} sign, by default 0 |
|||
* @returns {String} right aligned string |
|||
*/ |
|||
var padRight = function (string, chars, sign) { |
|||
return string + (new Array(chars - string.length + 1).join(sign ? sign : "0")); |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to get sting from it's hex representation |
|||
* |
|||
* @method toAscii |
|||
* @param {String} string in hex |
|||
* @returns {String} ascii string representation of hex value |
|||
*/ |
|||
var toAscii = function(hex) { |
|||
// Find termination
|
|||
var str = ""; |
|||
var i = 0, l = hex.length; |
|||
if (hex.substring(0, 2) === '0x') { |
|||
i = 2; |
|||
} |
|||
for (; i < l; i+=2) { |
|||
var code = parseInt(hex.substr(i, 2), 16); |
|||
str += String.fromCharCode(code); |
|||
} |
|||
|
|||
return str; |
|||
}; |
|||
|
|||
/** |
|||
* Shold be called to get hex representation (prefixed by 0x) of ascii string |
|||
* |
|||
* @method toHexNative |
|||
* @param {String} string |
|||
* @returns {String} hex representation of input string |
|||
*/ |
|||
var toHexNative = function(str) { |
|||
var hex = ""; |
|||
for(var i = 0; i < str.length; i++) { |
|||
var n = str.charCodeAt(i).toString(16); |
|||
hex += n.length < 2 ? '0' + n : n; |
|||
} |
|||
|
|||
return hex; |
|||
}; |
|||
|
|||
/** |
|||
* Shold be called to get hex representation (prefixed by 0x) of ascii string |
|||
* |
|||
* @method fromAscii |
|||
* @param {String} string |
|||
* @param {Number} optional padding |
|||
* @returns {String} hex representation of input string |
|||
*/ |
|||
var fromAscii = function(str, pad) { |
|||
pad = pad === undefined ? 0 : pad; |
|||
var hex = toHexNative(str); |
|||
while (hex.length < pad*2) |
|||
hex += "00"; |
|||
return "0x" + hex; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to create full function/event name from json abi |
|||
* |
|||
* @method transformToFullName |
|||
* @param {Object} json-abi |
|||
* @return {String} full fnction/event name |
|||
*/ |
|||
var transformToFullName = function (json) { |
|||
if (json.name.indexOf('(') !== -1) { |
|||
return json.name; |
|||
} |
|||
|
|||
var typeName = json.inputs.map(function(i){return i.type; }).join(); |
|||
return json.name + '(' + typeName + ')'; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to get display name of contract function |
|||
* |
|||
* @method extractDisplayName |
|||
* @param {String} name of function/event |
|||
* @returns {String} display name for function/event eg. multiply(uint256) -> multiply |
|||
*/ |
|||
var extractDisplayName = function (name) { |
|||
var length = name.indexOf('('); |
|||
return length !== -1 ? name.substr(0, length) : name; |
|||
}; |
|||
|
|||
/// @returns overloaded part of function/event name
|
|||
var extractTypeName = function (name) { |
|||
/// TODO: make it invulnerable
|
|||
var length = name.indexOf('('); |
|||
return length !== -1 ? name.substr(length + 1, name.length - 1 - (length + 1)).replace(' ', '') : ""; |
|||
}; |
|||
|
|||
/** |
|||
* Converts value to it's decimal representation in string |
|||
* |
|||
* @method toDecimal |
|||
* @param {String|Number|BigNumber} |
|||
* @return {String} |
|||
*/ |
|||
var toDecimal = function (value) { |
|||
return toBigNumber(value).toNumber(); |
|||
}; |
|||
|
|||
/** |
|||
* Converts value to it's hex representation |
|||
* |
|||
* @method fromDecimal |
|||
* @param {String|Number|BigNumber} |
|||
* @return {String} |
|||
*/ |
|||
var fromDecimal = function (value) { |
|||
var number = toBigNumber(value); |
|||
var result = number.toString(16); |
|||
|
|||
return number.lessThan(0) ? '-0x' + result.substr(1) : '0x' + result; |
|||
}; |
|||
|
|||
/** |
|||
* Auto converts any given value into it's hex representation. |
|||
* |
|||
* And even stringifys objects before. |
|||
* |
|||
* @method toHex |
|||
* @param {String|Number|BigNumber|Object} |
|||
* @return {String} |
|||
*/ |
|||
var toHex = function (val) { |
|||
/*jshint maxcomplexity: 8 */ |
|||
|
|||
if (isBoolean(val)) |
|||
return fromDecimal(+val); |
|||
|
|||
if (isBigNumber(val)) |
|||
return fromDecimal(val); |
|||
|
|||
if (isObject(val)) |
|||
return fromAscii(JSON.stringify(val)); |
|||
|
|||
// if its a negative number, pass it through fromDecimal
|
|||
if (isString(val)) { |
|||
if (val.indexOf('-0x') === 0) |
|||
return fromDecimal(val); |
|||
else if (!isFinite(val)) |
|||
return fromAscii(val); |
|||
else if(val.indexOf('0x') === 0) |
|||
return val; |
|||
} |
|||
|
|||
return fromDecimal(val); |
|||
}; |
|||
|
|||
/** |
|||
* Returns value of unit in Wei |
|||
* |
|||
* @method getValueOfUnit |
|||
* @param {String} unit the unit to convert to, default ether |
|||
* @returns {BigNumber} value of the unit (in Wei) |
|||
* @throws error if the unit is not correct:w |
|||
*/ |
|||
var getValueOfUnit = function (unit) { |
|||
unit = unit ? unit.toLowerCase() : 'ether'; |
|||
var unitValue = unitMap[unit]; |
|||
if (unitValue === undefined) { |
|||
throw new Error('This unit doesn\'t exists, please use the one of the following units' + JSON.stringify(unitMap, null, 2)); |
|||
} |
|||
return new BigNumber(unitValue, 10); |
|||
}; |
|||
|
|||
/** |
|||
* Takes a number of wei and converts it to any other ether unit. |
|||
* |
|||
* Possible units are: |
|||
* SI Short SI Full Effigy Other |
|||
* - kwei femtoether ada |
|||
* - mwei picoether babbage |
|||
* - gwei nanoether shannon nano |
|||
* - -- microether szabo micro |
|||
* - -- milliether finney milli |
|||
* - ether -- -- |
|||
* - kether einstein grand |
|||
* - mether |
|||
* - gether |
|||
* - tether |
|||
* |
|||
* @method fromWei |
|||
* @param {Number|String} number can be a number, number string or a HEX of a decimal |
|||
* @param {String} unit the unit to convert to, default ether |
|||
* @return {String|Object} When given a BigNumber object it returns one as well, otherwise a number |
|||
*/ |
|||
var fromWei = function(number, unit) { |
|||
var returnValue = toBigNumber(number).dividedBy(getValueOfUnit(unit)); |
|||
|
|||
return isBigNumber(number) ? returnValue : returnValue.toString(10); |
|||
}; |
|||
|
|||
/** |
|||
* Takes a number of a unit and converts it to wei. |
|||
* |
|||
* Possible units are: |
|||
* SI Short SI Full Effigy Other |
|||
* - kwei femtoether ada |
|||
* - mwei picoether babbage |
|||
* - gwei nanoether shannon nano |
|||
* - -- microether szabo micro |
|||
* - -- milliether finney milli |
|||
* - ether -- -- |
|||
* - kether einstein grand |
|||
* - mether |
|||
* - gether |
|||
* - tether |
|||
* |
|||
* @method toWei |
|||
* @param {Number|String|BigNumber} number can be a number, number string or a HEX of a decimal |
|||
* @param {String} unit the unit to convert from, default ether |
|||
* @return {String|Object} When given a BigNumber object it returns one as well, otherwise a number |
|||
*/ |
|||
var toWei = function(number, unit) { |
|||
var returnValue = toBigNumber(number).times(getValueOfUnit(unit)); |
|||
|
|||
return isBigNumber(number) ? returnValue : returnValue.toString(10); |
|||
}; |
|||
|
|||
/** |
|||
* Takes an input and transforms it into an bignumber |
|||
* |
|||
* @method toBigNumber |
|||
* @param {Number|String|BigNumber} a number, string, HEX string or BigNumber |
|||
* @return {BigNumber} BigNumber |
|||
*/ |
|||
var toBigNumber = function(number) { |
|||
/*jshint maxcomplexity:5 */ |
|||
number = number || 0; |
|||
if (isBigNumber(number)) |
|||
return number; |
|||
|
|||
if (isString(number) && (number.indexOf('0x') === 0 || number.indexOf('-0x') === 0)) { |
|||
return new BigNumber(number.replace('0x',''), 16); |
|||
} |
|||
|
|||
return new BigNumber(number.toString(10), 10); |
|||
}; |
|||
|
|||
/** |
|||
* Takes and input transforms it into bignumber and if it is negative value, into two's complement |
|||
* |
|||
* @method toTwosComplement |
|||
* @param {Number|String|BigNumber} |
|||
* @return {BigNumber} |
|||
*/ |
|||
var toTwosComplement = function (number) { |
|||
var bigNumber = toBigNumber(number); |
|||
if (bigNumber.lessThan(0)) { |
|||
return new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).plus(bigNumber).plus(1); |
|||
} |
|||
return bigNumber; |
|||
}; |
|||
|
|||
/** |
|||
* Checks if the given string is strictly an address |
|||
* |
|||
* @method isStrictAddress |
|||
* @param {String} address the given HEX adress |
|||
* @return {Boolean} |
|||
*/ |
|||
var isStrictAddress = function (address) { |
|||
return /^0x[0-9a-f]{40}$/.test(address); |
|||
}; |
|||
|
|||
/** |
|||
* Checks if the given string is an address |
|||
* |
|||
* @method isAddress |
|||
* @param {String} address the given HEX adress |
|||
* @return {Boolean} |
|||
*/ |
|||
var isAddress = function (address) { |
|||
return /^(0x)?[0-9a-f]{40}$/.test(address); |
|||
}; |
|||
|
|||
/** |
|||
* Transforms given string to valid 20 bytes-length addres with 0x prefix |
|||
* |
|||
* @method toAddress |
|||
* @param {String} address |
|||
* @return {String} formatted address |
|||
*/ |
|||
var toAddress = function (address) { |
|||
if (isStrictAddress(address)) { |
|||
return address; |
|||
} |
|||
|
|||
if (/^[0-9a-f]{40}$/.test(address)) { |
|||
return '0x' + address; |
|||
} |
|||
|
|||
return '0x' + padLeft(toHex(address).substr(2), 40); |
|||
}; |
|||
|
|||
|
|||
/** |
|||
* Returns true if object is BigNumber, otherwise false |
|||
* |
|||
* @method isBigNumber |
|||
* @param {Object} |
|||
* @return {Boolean} |
|||
*/ |
|||
var isBigNumber = function (object) { |
|||
return object instanceof BigNumber || |
|||
(object && object.constructor && object.constructor.name === 'BigNumber'); |
|||
}; |
|||
|
|||
/** |
|||
* Returns true if object is string, otherwise false |
|||
* |
|||
* @method isString |
|||
* @param {Object} |
|||
* @return {Boolean} |
|||
*/ |
|||
var isString = function (object) { |
|||
return typeof object === 'string' || |
|||
(object && object.constructor && object.constructor.name === 'String'); |
|||
}; |
|||
|
|||
/** |
|||
* Returns true if object is function, otherwise false |
|||
* |
|||
* @method isFunction |
|||
* @param {Object} |
|||
* @return {Boolean} |
|||
*/ |
|||
var isFunction = function (object) { |
|||
return typeof object === 'function'; |
|||
}; |
|||
|
|||
/** |
|||
* Returns true if object is Objet, otherwise false |
|||
* |
|||
* @method isObject |
|||
* @param {Object} |
|||
* @return {Boolean} |
|||
*/ |
|||
var isObject = function (object) { |
|||
return typeof object === 'object'; |
|||
}; |
|||
|
|||
/** |
|||
* Returns true if object is boolean, otherwise false |
|||
* |
|||
* @method isBoolean |
|||
* @param {Object} |
|||
* @return {Boolean} |
|||
*/ |
|||
var isBoolean = function (object) { |
|||
return typeof object === 'boolean'; |
|||
}; |
|||
|
|||
/** |
|||
* Returns true if object is array, otherwise false |
|||
* |
|||
* @method isArray |
|||
* @param {Object} |
|||
* @return {Boolean} |
|||
*/ |
|||
var isArray = function (object) { |
|||
return object instanceof Array; |
|||
}; |
|||
|
|||
/** |
|||
* Returns true if given string is valid json object |
|||
* |
|||
* @method isJson |
|||
* @param {String} |
|||
* @return {Boolean} |
|||
*/ |
|||
var isJson = function (str) { |
|||
try { |
|||
return !!JSON.parse(str); |
|||
} catch (e) { |
|||
return false; |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* This method should be called to check if string is valid ethereum IBAN number |
|||
* Supports direct and indirect IBANs |
|||
* |
|||
* @method isIBAN |
|||
* @param {String} |
|||
* @return {Boolean} |
|||
*/ |
|||
var isIBAN = function (iban) { |
|||
return /^XE[0-9]{2}(ETH[0-9A-Z]{13}|[0-9A-Z]{30})$/.test(iban); |
|||
}; |
|||
|
|||
module.exports = { |
|||
padLeft: padLeft, |
|||
padRight: padRight, |
|||
toHex: toHex, |
|||
toDecimal: toDecimal, |
|||
fromDecimal: fromDecimal, |
|||
toAscii: toAscii, |
|||
fromAscii: fromAscii, |
|||
transformToFullName: transformToFullName, |
|||
extractDisplayName: extractDisplayName, |
|||
extractTypeName: extractTypeName, |
|||
toWei: toWei, |
|||
fromWei: fromWei, |
|||
toBigNumber: toBigNumber, |
|||
toTwosComplement: toTwosComplement, |
|||
toAddress: toAddress, |
|||
isBigNumber: isBigNumber, |
|||
isStrictAddress: isStrictAddress, |
|||
isAddress: isAddress, |
|||
isFunction: isFunction, |
|||
isString: isString, |
|||
isObject: isObject, |
|||
isBoolean: isBoolean, |
|||
isArray: isArray, |
|||
isJson: isJson, |
|||
isIBAN: isIBAN |
|||
}; |
|||
|
@ -1,3 +0,0 @@ |
|||
{ |
|||
"version": "0.9.0" |
|||
} |
@ -1,175 +0,0 @@ |
|||
/* |
|||
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 web3.js |
|||
* @authors: |
|||
* Jeffrey Wilcke <jeff@ethdev.com> |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* Marian Oancea <marian@ethdev.com> |
|||
* Fabian Vogelsteller <fabian@ethdev.com> |
|||
* Gav Wood <g@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
var version = require('./version.json'); |
|||
var net = require('./web3/net'); |
|||
var eth = require('./web3/eth'); |
|||
var db = require('./web3/db'); |
|||
var shh = require('./web3/shh'); |
|||
var watches = require('./web3/watches'); |
|||
var Filter = require('./web3/filter'); |
|||
var utils = require('./utils/utils'); |
|||
var formatters = require('./web3/formatters'); |
|||
var RequestManager = require('./web3/requestmanager'); |
|||
var c = require('./utils/config'); |
|||
var Property = require('./web3/property'); |
|||
var Batch = require('./web3/batch'); |
|||
var sha3 = require('./utils/sha3'); |
|||
|
|||
var web3Properties = [ |
|||
new Property({ |
|||
name: 'version.client', |
|||
getter: 'web3_clientVersion' |
|||
}), |
|||
new Property({ |
|||
name: 'version.network', |
|||
getter: 'net_version', |
|||
inputFormatter: utils.toDecimal |
|||
}), |
|||
new Property({ |
|||
name: 'version.ethereum', |
|||
getter: 'eth_protocolVersion', |
|||
inputFormatter: utils.toDecimal |
|||
}), |
|||
new Property({ |
|||
name: 'version.whisper', |
|||
getter: 'shh_version', |
|||
inputFormatter: utils.toDecimal |
|||
}) |
|||
]; |
|||
|
|||
/// creates methods in a given object based on method description on input
|
|||
/// setups api calls for these methods
|
|||
var setupMethods = function (obj, methods) { |
|||
methods.forEach(function (method) { |
|||
method.attachToObject(obj); |
|||
}); |
|||
}; |
|||
|
|||
/// creates properties in a given object based on properties description on input
|
|||
/// setups api calls for these properties
|
|||
var setupProperties = function (obj, properties) { |
|||
properties.forEach(function (property) { |
|||
property.attachToObject(obj); |
|||
}); |
|||
}; |
|||
|
|||
/// setups web3 object, and it's in-browser executed methods
|
|||
var web3 = {}; |
|||
web3.providers = {}; |
|||
web3.currentProvider = null; |
|||
web3.version = {}; |
|||
web3.version.api = version.version; |
|||
web3.eth = {}; |
|||
|
|||
/*jshint maxparams:4 */ |
|||
web3.eth.filter = function (fil, callback) { |
|||
return new Filter(fil, watches.eth(), formatters.outputLogFormatter, callback); |
|||
}; |
|||
/*jshint maxparams:3 */ |
|||
|
|||
web3.shh = {}; |
|||
web3.shh.filter = function (fil, callback) { |
|||
return new Filter(fil, watches.shh(), formatters.outputPostFormatter, callback); |
|||
}; |
|||
web3.net = {}; |
|||
web3.db = {}; |
|||
web3.setProvider = function (provider) { |
|||
this.currentProvider = provider; |
|||
RequestManager.getInstance().setProvider(provider); |
|||
}; |
|||
web3.isConnected = function(){ |
|||
return (this.currentProvider && this.currentProvider.isConnected()); |
|||
}; |
|||
web3.reset = function () { |
|||
RequestManager.getInstance().reset(); |
|||
c.defaultBlock = 'latest'; |
|||
c.defaultAccount = undefined; |
|||
}; |
|||
web3.toHex = utils.toHex; |
|||
web3.toAscii = utils.toAscii; |
|||
web3.fromAscii = utils.fromAscii; |
|||
web3.toDecimal = utils.toDecimal; |
|||
web3.fromDecimal = utils.fromDecimal; |
|||
web3.toBigNumber = utils.toBigNumber; |
|||
web3.toWei = utils.toWei; |
|||
web3.fromWei = utils.fromWei; |
|||
web3.isAddress = utils.isAddress; |
|||
web3.isIBAN = utils.isIBAN; |
|||
web3.sha3 = sha3; |
|||
web3.createBatch = function () { |
|||
return new Batch(); |
|||
}; |
|||
|
|||
// ADD defaultblock
|
|||
Object.defineProperty(web3.eth, 'defaultBlock', { |
|||
get: function () { |
|||
return c.defaultBlock; |
|||
}, |
|||
set: function (val) { |
|||
c.defaultBlock = val; |
|||
return val; |
|||
} |
|||
}); |
|||
|
|||
Object.defineProperty(web3.eth, 'defaultAccount', { |
|||
get: function () { |
|||
return c.defaultAccount; |
|||
}, |
|||
set: function (val) { |
|||
c.defaultAccount = val; |
|||
return val; |
|||
} |
|||
}); |
|||
|
|||
|
|||
// EXTEND
|
|||
web3._extend = function(extension){ |
|||
/*jshint maxcomplexity: 6 */ |
|||
|
|||
if(extension.property && !web3[extension.property]) |
|||
web3[extension.property] = {}; |
|||
|
|||
setupMethods(web3[extension.property] || web3, extension.methods || []); |
|||
setupProperties(web3[extension.property] || web3, extension.properties || []); |
|||
}; |
|||
web3._extend.formatters = formatters; |
|||
web3._extend.utils = utils; |
|||
web3._extend.Method = require('./web3/method'); |
|||
web3._extend.Property = require('./web3/property'); |
|||
|
|||
|
|||
/// setups all api methods
|
|||
setupProperties(web3, web3Properties); |
|||
setupMethods(web3.net, net.methods); |
|||
setupProperties(web3.net, net.properties); |
|||
setupMethods(web3.eth, eth.methods); |
|||
setupProperties(web3.eth, eth.properties); |
|||
setupMethods(web3.db, db.methods); |
|||
setupMethods(web3.shh, shh.methods); |
|||
|
|||
module.exports = web3; |
|||
|
@ -1,80 +0,0 @@ |
|||
/* |
|||
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 allevents.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
var sha3 = require('../utils/sha3'); |
|||
var SolidityEvent = require('./event'); |
|||
var formatters = require('./formatters'); |
|||
var utils = require('../utils/utils'); |
|||
var Filter = require('./filter'); |
|||
var watches = require('./watches'); |
|||
|
|||
var AllSolidityEvents = function (json, address) { |
|||
this._json = json; |
|||
this._address = address; |
|||
}; |
|||
|
|||
AllSolidityEvents.prototype.encode = function (options) { |
|||
options = options || {}; |
|||
var result = {}; |
|||
|
|||
['fromBlock', 'toBlock'].filter(function (f) { |
|||
return options[f] !== undefined; |
|||
}).forEach(function (f) { |
|||
result[f] = formatters.inputBlockNumberFormatter(options[f]); |
|||
}); |
|||
|
|||
result.address = this._address; |
|||
|
|||
return result; |
|||
}; |
|||
|
|||
AllSolidityEvents.prototype.decode = function (data) { |
|||
data.data = data.data || ''; |
|||
data.topics = data.topics || []; |
|||
|
|||
var eventTopic = data.topics[0].slice(2); |
|||
var match = this._json.filter(function (j) { |
|||
return eventTopic === sha3(utils.transformToFullName(j)); |
|||
})[0]; |
|||
|
|||
if (!match) { // cannot find matching event?
|
|||
console.warn('cannot find event for log'); |
|||
return data; |
|||
} |
|||
|
|||
var event = new SolidityEvent(match, this._address); |
|||
return event.decode(data); |
|||
}; |
|||
|
|||
AllSolidityEvents.prototype.execute = function (options, callback) { |
|||
var o = this.encode(options); |
|||
var formatter = this.decode.bind(this); |
|||
return new Filter(o, watches.eth(), formatter, callback); |
|||
}; |
|||
|
|||
AllSolidityEvents.prototype.attachToContract = function (contract) { |
|||
var execute = this.execute.bind(this); |
|||
contract.allEvents = execute; |
|||
}; |
|||
|
|||
module.exports = AllSolidityEvents; |
|||
|
@ -1,66 +0,0 @@ |
|||
/* |
|||
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 batch.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var RequestManager = require('./requestmanager'); |
|||
var Jsonrpc = require('./jsonrpc'); |
|||
var errors = require('./errors'); |
|||
|
|||
var Batch = function () { |
|||
this.requests = []; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to add create new request to batch request |
|||
* |
|||
* @method add |
|||
* @param {Object} jsonrpc requet object |
|||
*/ |
|||
Batch.prototype.add = function (request) { |
|||
this.requests.push(request); |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to execute batch request |
|||
* |
|||
* @method execute |
|||
*/ |
|||
Batch.prototype.execute = function () { |
|||
var requests = this.requests; |
|||
RequestManager.getInstance().sendBatch(requests, function (err, results) { |
|||
results = results || []; |
|||
requests.map(function (request, index) { |
|||
return results[index] || {}; |
|||
}).forEach(function (result, index) { |
|||
if (requests[index].callback) { |
|||
|
|||
if (!Jsonrpc.getInstance().isValidResponse(result)) { |
|||
return requests[index].callback(errors.InvalidResponse(result)); |
|||
} |
|||
|
|||
requests[index].callback(null, (requests[index].format ? requests[index].format(result.result) : result.result)); |
|||
} |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
module.exports = Batch; |
|||
|
@ -1,277 +0,0 @@ |
|||
/* |
|||
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 contract.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
var web3 = require('../web3'); |
|||
var utils = require('../utils/utils'); |
|||
var coder = require('../solidity/coder'); |
|||
var SolidityEvent = require('./event'); |
|||
var SolidityFunction = require('./function'); |
|||
var AllEvents = require('./allevents'); |
|||
|
|||
/** |
|||
* Should be called to encode constructor params |
|||
* |
|||
* @method encodeConstructorParams |
|||
* @param {Array} abi |
|||
* @param {Array} constructor params |
|||
*/ |
|||
var encodeConstructorParams = function (abi, params) { |
|||
return abi.filter(function (json) { |
|||
return json.type === 'constructor' && json.inputs.length === params.length; |
|||
}).map(function (json) { |
|||
return json.inputs.map(function (input) { |
|||
return input.type; |
|||
}); |
|||
}).map(function (types) { |
|||
return coder.encodeParams(types, params); |
|||
})[0] || ''; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to add functions to contract object |
|||
* |
|||
* @method addFunctionsToContract |
|||
* @param {Contract} contract |
|||
* @param {Array} abi |
|||
*/ |
|||
var addFunctionsToContract = function (contract, abi) { |
|||
abi.filter(function (json) { |
|||
return json.type === 'function'; |
|||
}).map(function (json) { |
|||
return new SolidityFunction(json, contract.address); |
|||
}).forEach(function (f) { |
|||
f.attachToContract(contract); |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to add events to contract object |
|||
* |
|||
* @method addEventsToContract |
|||
* @param {Contract} contract |
|||
* @param {Array} abi |
|||
*/ |
|||
var addEventsToContract = function (contract, abi) { |
|||
var events = abi.filter(function (json) { |
|||
return json.type === 'event'; |
|||
}); |
|||
|
|||
var All = new AllEvents(events, contract.address); |
|||
All.attachToContract(contract); |
|||
|
|||
events.map(function (json) { |
|||
return new SolidityEvent(json, contract.address); |
|||
}).forEach(function (e) { |
|||
e.attachToContract(contract); |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to create new ContractFactory |
|||
* |
|||
* @method contract |
|||
* @param {Array} abi |
|||
* @returns {ContractFactory} new contract factory |
|||
*/ |
|||
var contract = function (abi) { |
|||
return new ContractFactory(abi); |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to check if the contract gets properly deployed on the blockchain. |
|||
* |
|||
* @method checkForContractAddress |
|||
* @param {Object} contract |
|||
* @param {Function} callback |
|||
* @returns {Undefined} |
|||
*/ |
|||
var checkForContractAddress = function(contract, abi, callback){ |
|||
var count = 0, |
|||
callbackFired = false; |
|||
|
|||
// wait for receipt
|
|||
var filter = web3.eth.filter('latest', function(e){ |
|||
if(!e && !callbackFired) { |
|||
count++; |
|||
|
|||
// console.log('Checking for contract address', count);
|
|||
|
|||
// stop watching after 50 blocks (timeout)
|
|||
if(count > 50) { |
|||
|
|||
filter.stopWatching(); |
|||
callbackFired = true; |
|||
|
|||
if(callback) |
|||
callback(new Error('Contract transaction couldn\'t be found after 50 blocks')); |
|||
else |
|||
throw new Error('Contract transaction couldn\'t be found after 50 blocks'); |
|||
|
|||
|
|||
} else { |
|||
|
|||
web3.eth.getTransactionReceipt(contract.transactionHash, function(e, receipt){ |
|||
if(receipt && !callbackFired) { |
|||
|
|||
web3.eth.getCode(receipt.contractAddress, function(e, code){ |
|||
/*jshint maxcomplexity: 5 */ |
|||
|
|||
if(callbackFired) |
|||
return; |
|||
|
|||
filter.stopWatching(); |
|||
callbackFired = true; |
|||
|
|||
if(code.length > 2) { |
|||
|
|||
// console.log('Contract code deployed!');
|
|||
|
|||
contract.address = receipt.contractAddress; |
|||
|
|||
// attach events and methods
|
|||
addFunctionsToContract(contract, abi); |
|||
addEventsToContract(contract, abi); |
|||
|
|||
// call callback for the second time
|
|||
if(callback) |
|||
callback(null, contract); |
|||
|
|||
} else { |
|||
if(callback) |
|||
callback(new Error('The contract code couldn\'t be stored, please check your gas amount.')); |
|||
else |
|||
throw new Error('The contract code couldn\'t be stored, please check your gas amount.'); |
|||
} |
|||
}); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to create new ContractFactory instance |
|||
* |
|||
* @method ContractFactory |
|||
* @param {Array} abi |
|||
*/ |
|||
var ContractFactory = function (abi) { |
|||
this.abi = abi; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to create new contract on a blockchain |
|||
* |
|||
* @method new |
|||
* @param {Any} contract constructor param1 (optional) |
|||
* @param {Any} contract constructor param2 (optional) |
|||
* @param {Object} contract transaction object (required) |
|||
* @param {Function} callback |
|||
* @returns {Contract} returns contract instance |
|||
*/ |
|||
ContractFactory.prototype.new = function () { |
|||
var _this = this; |
|||
var contract = new Contract(this.abi); |
|||
|
|||
// parse arguments
|
|||
var options = {}; // required!
|
|||
var callback; |
|||
|
|||
var args = Array.prototype.slice.call(arguments); |
|||
if (utils.isFunction(args[args.length - 1])) { |
|||
callback = args.pop(); |
|||
} |
|||
|
|||
var last = args[args.length - 1]; |
|||
if (utils.isObject(last) && !utils.isArray(last)) { |
|||
options = args.pop(); |
|||
} |
|||
|
|||
// throw an error if there are no options
|
|||
|
|||
var bytes = encodeConstructorParams(this.abi, args); |
|||
options.data += bytes; |
|||
|
|||
|
|||
if(callback) { |
|||
|
|||
// wait for the contract address adn check if the code was deployed
|
|||
web3.eth.sendTransaction(options, function (err, hash) { |
|||
if (err) { |
|||
callback(err); |
|||
} else { |
|||
// add the transaction hash
|
|||
contract.transactionHash = hash; |
|||
|
|||
// call callback for the first time
|
|||
callback(null, contract); |
|||
|
|||
checkForContractAddress(contract, _this.abi, callback); |
|||
} |
|||
}); |
|||
} else { |
|||
var hash = web3.eth.sendTransaction(options); |
|||
// add the transaction hash
|
|||
contract.transactionHash = hash; |
|||
checkForContractAddress(contract, _this.abi); |
|||
} |
|||
|
|||
return contract; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to get access to existing contract on a blockchain |
|||
* |
|||
* @method at |
|||
* @param {Address} contract address (required) |
|||
* @param {Function} callback {optional) |
|||
* @returns {Contract} returns contract if no callback was passed, |
|||
* otherwise calls callback function (err, contract) |
|||
*/ |
|||
ContractFactory.prototype.at = function (address, callback) { |
|||
var contract = new Contract(this.abi, address); |
|||
// TODO: address is required
|
|||
|
|||
// attach functions
|
|||
addFunctionsToContract(contract, this.abi); |
|||
addEventsToContract(contract, this.abi); |
|||
|
|||
if (callback) { |
|||
callback(null, contract); |
|||
} |
|||
return contract; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to create new contract instance |
|||
* |
|||
* @method Contract |
|||
* @param {Array} abi |
|||
* @param {Address} contract address |
|||
*/ |
|||
var Contract = function (abi, address) { |
|||
this.address = address; |
|||
}; |
|||
|
|||
module.exports = contract; |
|||
|
@ -1,56 +0,0 @@ |
|||
/* |
|||
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 db.js |
|||
* @authors: |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var Method = require('./method'); |
|||
|
|||
var putString = new Method({ |
|||
name: 'putString', |
|||
call: 'db_putString', |
|||
params: 3 |
|||
}); |
|||
|
|||
|
|||
var getString = new Method({ |
|||
name: 'getString', |
|||
call: 'db_getString', |
|||
params: 2 |
|||
}); |
|||
|
|||
var putHex = new Method({ |
|||
name: 'putHex', |
|||
call: 'db_putHex', |
|||
params: 3 |
|||
}); |
|||
|
|||
var getHex = new Method({ |
|||
name: 'getHex', |
|||
call: 'db_getHex', |
|||
params: 2 |
|||
}); |
|||
|
|||
var methods = [ |
|||
putString, getString, putHex, getHex |
|||
]; |
|||
|
|||
module.exports = { |
|||
methods: methods |
|||
}; |
@ -1,38 +0,0 @@ |
|||
/* |
|||
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 errors.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
module.exports = { |
|||
InvalidNumberOfParams: function () { |
|||
return new Error('Invalid number of input parameters'); |
|||
}, |
|||
InvalidConnection: function (host){ |
|||
return new Error('CONNECTION ERROR: Couldn\'t connect to node '+ host +', is it running?'); |
|||
}, |
|||
InvalidProvider: function () { |
|||
return new Error('Providor not set or invalid'); |
|||
}, |
|||
InvalidResponse: function (result){ |
|||
var message = !!result && !!result.error && !!result.error.message ? result.error.message : 'Invalid JSON RPC response: '+ result; |
|||
return new Error(message); |
|||
} |
|||
}; |
|||
|
@ -1,291 +0,0 @@ |
|||
/* |
|||
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 eth.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @author Fabian Vogelsteller <fabian@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
/** |
|||
* Web3 |
|||
* |
|||
* @module web3 |
|||
*/ |
|||
|
|||
/** |
|||
* Eth methods and properties |
|||
* |
|||
* An example method object can look as follows: |
|||
* |
|||
* { |
|||
* name: 'getBlock', |
|||
* call: blockCall, |
|||
* params: 2, |
|||
* outputFormatter: formatters.outputBlockFormatter, |
|||
* inputFormatter: [ // can be a formatter funciton or an array of functions. Where each item in the array will be used for one parameter
|
|||
* utils.toHex, // formats paramter 1
|
|||
* function(param){ return !!param; } // formats paramter 2
|
|||
* ] |
|||
* }, |
|||
* |
|||
* @class [web3] eth |
|||
* @constructor |
|||
*/ |
|||
|
|||
"use strict"; |
|||
|
|||
var formatters = require('./formatters'); |
|||
var utils = require('../utils/utils'); |
|||
var Method = require('./method'); |
|||
var Property = require('./property'); |
|||
|
|||
var blockCall = function (args) { |
|||
return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? "eth_getBlockByHash" : "eth_getBlockByNumber"; |
|||
}; |
|||
|
|||
var transactionFromBlockCall = function (args) { |
|||
return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getTransactionByBlockHashAndIndex' : 'eth_getTransactionByBlockNumberAndIndex'; |
|||
}; |
|||
|
|||
var uncleCall = function (args) { |
|||
return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleByBlockHashAndIndex' : 'eth_getUncleByBlockNumberAndIndex'; |
|||
}; |
|||
|
|||
var getBlockTransactionCountCall = function (args) { |
|||
return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getBlockTransactionCountByHash' : 'eth_getBlockTransactionCountByNumber'; |
|||
}; |
|||
|
|||
var uncleCountCall = function (args) { |
|||
return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleCountByBlockHash' : 'eth_getUncleCountByBlockNumber'; |
|||
}; |
|||
|
|||
/// @returns an array of objects describing web3.eth api methods
|
|||
|
|||
var getBalance = new Method({ |
|||
name: 'getBalance', |
|||
call: 'eth_getBalance', |
|||
params: 2, |
|||
inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter], |
|||
outputFormatter: formatters.outputBigNumberFormatter |
|||
}); |
|||
|
|||
var getStorageAt = new Method({ |
|||
name: 'getStorageAt', |
|||
call: 'eth_getStorageAt', |
|||
params: 3, |
|||
inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter] |
|||
}); |
|||
|
|||
var getCode = new Method({ |
|||
name: 'getCode', |
|||
call: 'eth_getCode', |
|||
params: 2, |
|||
inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter] |
|||
}); |
|||
|
|||
var getBlock = new Method({ |
|||
name: 'getBlock', |
|||
call: blockCall, |
|||
params: 2, |
|||
inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }], |
|||
outputFormatter: formatters.outputBlockFormatter |
|||
}); |
|||
|
|||
var getUncle = new Method({ |
|||
name: 'getUncle', |
|||
call: uncleCall, |
|||
params: 2, |
|||
inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex], |
|||
outputFormatter: formatters.outputBlockFormatter, |
|||
|
|||
}); |
|||
|
|||
var getCompilers = new Method({ |
|||
name: 'getCompilers', |
|||
call: 'eth_getCompilers', |
|||
params: 0 |
|||
}); |
|||
|
|||
var getBlockTransactionCount = new Method({ |
|||
name: 'getBlockTransactionCount', |
|||
call: getBlockTransactionCountCall, |
|||
params: 1, |
|||
inputFormatter: [formatters.inputBlockNumberFormatter], |
|||
outputFormatter: utils.toDecimal |
|||
}); |
|||
|
|||
var getBlockUncleCount = new Method({ |
|||
name: 'getBlockUncleCount', |
|||
call: uncleCountCall, |
|||
params: 1, |
|||
inputFormatter: [formatters.inputBlockNumberFormatter], |
|||
outputFormatter: utils.toDecimal |
|||
}); |
|||
|
|||
var getTransaction = new Method({ |
|||
name: 'getTransaction', |
|||
call: 'eth_getTransactionByHash', |
|||
params: 1, |
|||
outputFormatter: formatters.outputTransactionFormatter |
|||
}); |
|||
|
|||
var getTransactionFromBlock = new Method({ |
|||
name: 'getTransactionFromBlock', |
|||
call: transactionFromBlockCall, |
|||
params: 2, |
|||
inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex], |
|||
outputFormatter: formatters.outputTransactionFormatter |
|||
}); |
|||
|
|||
var getTransactionReceipt = new Method({ |
|||
name: 'getTransactionReceipt', |
|||
call: 'eth_getTransactionReceipt', |
|||
params: 1, |
|||
outputFormatter: formatters.outputTransactionReceiptFormatter |
|||
}); |
|||
|
|||
var getTransactionCount = new Method({ |
|||
name: 'getTransactionCount', |
|||
call: 'eth_getTransactionCount', |
|||
params: 2, |
|||
inputFormatter: [null, formatters.inputDefaultBlockNumberFormatter], |
|||
outputFormatter: utils.toDecimal |
|||
}); |
|||
|
|||
var sendRawTransaction = new Method({ |
|||
name: 'sendRawTransaction', |
|||
call: 'eth_sendRawTransaction', |
|||
params: 1, |
|||
inputFormatter: [null] |
|||
}); |
|||
|
|||
var sendTransaction = new Method({ |
|||
name: 'sendTransaction', |
|||
call: 'eth_sendTransaction', |
|||
params: 1, |
|||
inputFormatter: [formatters.inputTransactionFormatter] |
|||
}); |
|||
|
|||
var call = new Method({ |
|||
name: 'call', |
|||
call: 'eth_call', |
|||
params: 2, |
|||
inputFormatter: [formatters.inputTransactionFormatter, formatters.inputDefaultBlockNumberFormatter] |
|||
}); |
|||
|
|||
var estimateGas = new Method({ |
|||
name: 'estimateGas', |
|||
call: 'eth_estimateGas', |
|||
params: 1, |
|||
inputFormatter: [formatters.inputTransactionFormatter], |
|||
outputFormatter: utils.toDecimal |
|||
}); |
|||
|
|||
var compileSolidity = new Method({ |
|||
name: 'compile.solidity', |
|||
call: 'eth_compileSolidity', |
|||
params: 1 |
|||
}); |
|||
|
|||
var compileLLL = new Method({ |
|||
name: 'compile.lll', |
|||
call: 'eth_compileLLL', |
|||
params: 1 |
|||
}); |
|||
|
|||
var compileSerpent = new Method({ |
|||
name: 'compile.serpent', |
|||
call: 'eth_compileSerpent', |
|||
params: 1 |
|||
}); |
|||
|
|||
var submitWork = new Method({ |
|||
name: 'submitWork', |
|||
call: 'eth_submitWork', |
|||
params: 3 |
|||
}); |
|||
|
|||
var getWork = new Method({ |
|||
name: 'getWork', |
|||
call: 'eth_getWork', |
|||
params: 0 |
|||
}); |
|||
|
|||
var methods = [ |
|||
getBalance, |
|||
getStorageAt, |
|||
getCode, |
|||
getBlock, |
|||
getUncle, |
|||
getCompilers, |
|||
getBlockTransactionCount, |
|||
getBlockUncleCount, |
|||
getTransaction, |
|||
getTransactionFromBlock, |
|||
getTransactionReceipt, |
|||
getTransactionCount, |
|||
call, |
|||
estimateGas, |
|||
sendRawTransaction, |
|||
sendTransaction, |
|||
compileSolidity, |
|||
compileLLL, |
|||
compileSerpent, |
|||
submitWork, |
|||
getWork |
|||
]; |
|||
|
|||
/// @returns an array of objects describing web3.eth api properties
|
|||
|
|||
|
|||
|
|||
var properties = [ |
|||
new Property({ |
|||
name: 'coinbase', |
|||
getter: 'eth_coinbase' |
|||
}), |
|||
new Property({ |
|||
name: 'mining', |
|||
getter: 'eth_mining' |
|||
}), |
|||
new Property({ |
|||
name: 'hashrate', |
|||
getter: 'eth_hashrate', |
|||
outputFormatter: utils.toDecimal |
|||
}), |
|||
new Property({ |
|||
name: 'gasPrice', |
|||
getter: 'eth_gasPrice', |
|||
outputFormatter: formatters.outputBigNumberFormatter |
|||
}), |
|||
new Property({ |
|||
name: 'accounts', |
|||
getter: 'eth_accounts' |
|||
}), |
|||
new Property({ |
|||
name: 'blockNumber', |
|||
getter: 'eth_blockNumber', |
|||
outputFormatter: utils.toDecimal |
|||
}) |
|||
]; |
|||
|
|||
module.exports = { |
|||
methods: methods, |
|||
properties: properties |
|||
}; |
|||
|
@ -1,207 +0,0 @@ |
|||
/* |
|||
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 event.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
var utils = require('../utils/utils'); |
|||
var coder = require('../solidity/coder'); |
|||
var formatters = require('./formatters'); |
|||
var sha3 = require('../utils/sha3'); |
|||
var Filter = require('./filter'); |
|||
var watches = require('./watches'); |
|||
|
|||
/** |
|||
* This prototype should be used to create event filters |
|||
*/ |
|||
var SolidityEvent = function (json, address) { |
|||
this._params = json.inputs; |
|||
this._name = utils.transformToFullName(json); |
|||
this._address = address; |
|||
this._anonymous = json.anonymous; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to get filtered param types |
|||
* |
|||
* @method types |
|||
* @param {Bool} decide if returned typed should be indexed |
|||
* @return {Array} array of types |
|||
*/ |
|||
SolidityEvent.prototype.types = function (indexed) { |
|||
return this._params.filter(function (i) { |
|||
return i.indexed === indexed; |
|||
}).map(function (i) { |
|||
return i.type; |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to get event display name |
|||
* |
|||
* @method displayName |
|||
* @return {String} event display name |
|||
*/ |
|||
SolidityEvent.prototype.displayName = function () { |
|||
return utils.extractDisplayName(this._name); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to get event type name |
|||
* |
|||
* @method typeName |
|||
* @return {String} event type name |
|||
*/ |
|||
SolidityEvent.prototype.typeName = function () { |
|||
return utils.extractTypeName(this._name); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to get event signature |
|||
* |
|||
* @method signature |
|||
* @return {String} event signature |
|||
*/ |
|||
SolidityEvent.prototype.signature = function () { |
|||
return sha3(this._name); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to encode indexed params and options to one final object |
|||
* |
|||
* @method encode |
|||
* @param {Object} indexed |
|||
* @param {Object} options |
|||
* @return {Object} everything combined together and encoded |
|||
*/ |
|||
SolidityEvent.prototype.encode = function (indexed, options) { |
|||
indexed = indexed || {}; |
|||
options = options || {}; |
|||
var result = {}; |
|||
|
|||
['fromBlock', 'toBlock'].filter(function (f) { |
|||
return options[f] !== undefined; |
|||
}).forEach(function (f) { |
|||
result[f] = formatters.inputBlockNumberFormatter(options[f]); |
|||
}); |
|||
|
|||
result.topics = []; |
|||
|
|||
result.address = this._address; |
|||
if (!this._anonymous) { |
|||
result.topics.push('0x' + this.signature()); |
|||
} |
|||
|
|||
var indexedTopics = this._params.filter(function (i) { |
|||
return i.indexed === true; |
|||
}).map(function (i) { |
|||
var value = indexed[i.name]; |
|||
if (value === undefined || value === null) { |
|||
return null; |
|||
} |
|||
|
|||
if (utils.isArray(value)) { |
|||
return value.map(function (v) { |
|||
return '0x' + coder.encodeParam(i.type, v); |
|||
}); |
|||
} |
|||
return '0x' + coder.encodeParam(i.type, value); |
|||
}); |
|||
|
|||
result.topics = result.topics.concat(indexedTopics); |
|||
|
|||
return result; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to decode indexed params and options |
|||
* |
|||
* @method decode |
|||
* @param {Object} data |
|||
* @return {Object} result object with decoded indexed && not indexed params |
|||
*/ |
|||
SolidityEvent.prototype.decode = function (data) { |
|||
|
|||
data.data = data.data || ''; |
|||
data.topics = data.topics || []; |
|||
|
|||
var argTopics = this._anonymous ? data.topics : data.topics.slice(1); |
|||
var indexedData = argTopics.map(function (topics) { return topics.slice(2); }).join(""); |
|||
var indexedParams = coder.decodeParams(this.types(true), indexedData); |
|||
|
|||
var notIndexedData = data.data.slice(2); |
|||
var notIndexedParams = coder.decodeParams(this.types(false), notIndexedData); |
|||
|
|||
var result = formatters.outputLogFormatter(data); |
|||
result.event = this.displayName(); |
|||
result.address = data.address; |
|||
|
|||
result.args = this._params.reduce(function (acc, current) { |
|||
acc[current.name] = current.indexed ? indexedParams.shift() : notIndexedParams.shift(); |
|||
return acc; |
|||
}, {}); |
|||
|
|||
delete result.data; |
|||
delete result.topics; |
|||
|
|||
return result; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to create new filter object from event |
|||
* |
|||
* @method execute |
|||
* @param {Object} indexed |
|||
* @param {Object} options |
|||
* @return {Object} filter object |
|||
*/ |
|||
SolidityEvent.prototype.execute = function (indexed, options, callback) { |
|||
|
|||
if (utils.isFunction(arguments[arguments.length - 1])) { |
|||
callback = arguments[arguments.length - 1]; |
|||
if(arguments.length === 2) |
|||
options = null; |
|||
if(arguments.length === 1) { |
|||
options = null; |
|||
indexed = {}; |
|||
} |
|||
} |
|||
|
|||
var o = this.encode(indexed, options); |
|||
var formatter = this.decode.bind(this); |
|||
return new Filter(o, watches.eth(), formatter, callback); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to attach event to contract object |
|||
* |
|||
* @method attachToContract |
|||
* @param {Contract} |
|||
*/ |
|||
SolidityEvent.prototype.attachToContract = function (contract) { |
|||
var execute = this.execute.bind(this); |
|||
var displayName = this.displayName(); |
|||
if (!contract[displayName]) { |
|||
contract[displayName] = execute; |
|||
} |
|||
contract[displayName][this.typeName()] = this.execute.bind(this, contract); |
|||
}; |
|||
|
|||
module.exports = SolidityEvent; |
|||
|
@ -1,209 +0,0 @@ |
|||
/* |
|||
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> |
|||
* Fabian Vogelsteller <fabian@ethdev.com> |
|||
* Gav Wood <g@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
var RequestManager = require('./requestmanager'); |
|||
var formatters = require('./formatters'); |
|||
var utils = require('../utils/utils'); |
|||
|
|||
/** |
|||
* Converts a given topic to a hex string, but also allows null values. |
|||
* |
|||
* @param {Mixed} value |
|||
* @return {String} |
|||
*/ |
|||
var toTopic = function(value){ |
|||
|
|||
if(value === null || typeof value === 'undefined') |
|||
return null; |
|||
|
|||
value = String(value); |
|||
|
|||
if(value.indexOf('0x') === 0) |
|||
return value; |
|||
else |
|||
return utils.fromAscii(value); |
|||
}; |
|||
|
|||
/// This method should be called on options object, to verify deprecated properties && lazy load dynamic ones
|
|||
/// @param should be string or object
|
|||
/// @returns options string or object
|
|||
var getOptions = function (options) { |
|||
|
|||
if (utils.isString(options)) { |
|||
return options; |
|||
} |
|||
|
|||
options = options || {}; |
|||
|
|||
// make sure topics, get converted to hex
|
|||
options.topics = options.topics || []; |
|||
options.topics = options.topics.map(function(topic){ |
|||
return (utils.isArray(topic)) ? topic.map(toTopic) : toTopic(topic); |
|||
}); |
|||
|
|||
// lazy load
|
|||
return { |
|||
topics: options.topics, |
|||
to: options.to, |
|||
address: options.address, |
|||
fromBlock: formatters.inputBlockNumberFormatter(options.fromBlock), |
|||
toBlock: formatters.inputBlockNumberFormatter(options.toBlock) |
|||
}; |
|||
}; |
|||
|
|||
/** |
|||
Adds the callback and sets up the methods, to iterate over the results. |
|||
|
|||
@method getLogsAtStart |
|||
@param {Object} self |
|||
@param {funciton} |
|||
*/ |
|||
var getLogsAtStart = function(self, callback){ |
|||
// call getFilterLogs for the first watch callback start
|
|||
if (!utils.isString(self.options)) { |
|||
self.get(function (err, messages) { |
|||
// don't send all the responses to all the watches again... just to self one
|
|||
if (err) { |
|||
callback(err); |
|||
} |
|||
|
|||
if(utils.isArray(messages)) { |
|||
messages.forEach(function (message) { |
|||
callback(null, message); |
|||
}); |
|||
} |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
Adds the callback and sets up the methods, to iterate over the results. |
|||
|
|||
@method pollFilter |
|||
@param {Object} self |
|||
*/ |
|||
var pollFilter = function(self) { |
|||
|
|||
var onMessage = function (error, messages) { |
|||
if (error) { |
|||
return self.callbacks.forEach(function (callback) { |
|||
callback(error); |
|||
}); |
|||
} |
|||
|
|||
messages.forEach(function (message) { |
|||
message = self.formatter ? self.formatter(message) : message; |
|||
self.callbacks.forEach(function (callback) { |
|||
callback(null, message); |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
RequestManager.getInstance().startPolling({ |
|||
method: self.implementation.poll.call, |
|||
params: [self.filterId], |
|||
}, self.filterId, onMessage, self.stopWatching.bind(self)); |
|||
|
|||
}; |
|||
|
|||
var Filter = function (options, methods, formatter, callback) { |
|||
var self = this; |
|||
var implementation = {}; |
|||
methods.forEach(function (method) { |
|||
method.attachToObject(implementation); |
|||
}); |
|||
this.options = getOptions(options); |
|||
this.implementation = implementation; |
|||
this.filterId = null; |
|||
this.callbacks = []; |
|||
this.pollFilters = []; |
|||
this.formatter = formatter; |
|||
this.implementation.newFilter(this.options, function(error, id){ |
|||
if(error) { |
|||
self.callbacks.forEach(function(cb){ |
|||
cb(error); |
|||
}); |
|||
} else { |
|||
self.filterId = id; |
|||
|
|||
// get filter logs for the already existing watch calls
|
|||
self.callbacks.forEach(function(cb){ |
|||
getLogsAtStart(self, cb); |
|||
}); |
|||
if(self.callbacks.length > 0) |
|||
pollFilter(self); |
|||
|
|||
// start to watch immediately
|
|||
if(callback) { |
|||
return self.watch(callback); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
}; |
|||
|
|||
Filter.prototype.watch = function (callback) { |
|||
this.callbacks.push(callback); |
|||
|
|||
if(this.filterId) { |
|||
getLogsAtStart(this, callback); |
|||
pollFilter(this); |
|||
} |
|||
|
|||
return this; |
|||
}; |
|||
|
|||
Filter.prototype.stopWatching = function () { |
|||
RequestManager.getInstance().stopPolling(this.filterId); |
|||
// remove filter async
|
|||
this.implementation.uninstallFilter(this.filterId, function(){}); |
|||
this.callbacks = []; |
|||
}; |
|||
|
|||
Filter.prototype.get = function (callback) { |
|||
var self = this; |
|||
if (utils.isFunction(callback)) { |
|||
this.implementation.getLogs(this.filterId, function(err, res){ |
|||
if (err) { |
|||
callback(err); |
|||
} else { |
|||
callback(null, res.map(function (log) { |
|||
return self.formatter ? self.formatter(log) : log; |
|||
})); |
|||
} |
|||
}); |
|||
} else { |
|||
var logs = this.implementation.getLogs(this.filterId); |
|||
return logs.map(function (log) { |
|||
return self.formatter ? self.formatter(log) : log; |
|||
}); |
|||
} |
|||
|
|||
return this; |
|||
}; |
|||
|
|||
module.exports = Filter; |
|||
|
@ -1,245 +0,0 @@ |
|||
/* |
|||
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 formatters.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @author Fabian Vogelsteller <fabian@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var utils = require('../utils/utils'); |
|||
var config = require('../utils/config'); |
|||
|
|||
/** |
|||
* Should the format output to a big number |
|||
* |
|||
* @method outputBigNumberFormatter |
|||
* @param {String|Number|BigNumber} |
|||
* @returns {BigNumber} object |
|||
*/ |
|||
var outputBigNumberFormatter = function (number) { |
|||
return utils.toBigNumber(number); |
|||
}; |
|||
|
|||
var isPredefinedBlockNumber = function (blockNumber) { |
|||
return blockNumber === 'latest' || blockNumber === 'pending' || blockNumber === 'earliest'; |
|||
}; |
|||
|
|||
var inputDefaultBlockNumberFormatter = function (blockNumber) { |
|||
if (blockNumber === undefined) { |
|||
return config.defaultBlock; |
|||
} |
|||
return inputBlockNumberFormatter(blockNumber); |
|||
}; |
|||
|
|||
var inputBlockNumberFormatter = function (blockNumber) { |
|||
if (blockNumber === undefined) { |
|||
return undefined; |
|||
} else if (isPredefinedBlockNumber(blockNumber)) { |
|||
return blockNumber; |
|||
} |
|||
return utils.toHex(blockNumber); |
|||
}; |
|||
|
|||
/** |
|||
* Formats the input of a transaction and converts all values to HEX |
|||
* |
|||
* @method inputTransactionFormatter |
|||
* @param {Object} transaction options |
|||
* @returns object |
|||
*/ |
|||
var inputTransactionFormatter = function (options){ |
|||
|
|||
options.from = options.from || config.defaultAccount; |
|||
|
|||
// make code -> data
|
|||
if (options.code) { |
|||
options.data = options.code; |
|||
delete options.code; |
|||
} |
|||
|
|||
['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) { |
|||
return options[key] !== undefined; |
|||
}).forEach(function(key){ |
|||
options[key] = utils.fromDecimal(options[key]); |
|||
}); |
|||
|
|||
return options; |
|||
}; |
|||
|
|||
/** |
|||
* Formats the output of a transaction to its proper values |
|||
* |
|||
* @method outputTransactionFormatter |
|||
* @param {Object} tx |
|||
* @returns {Object} |
|||
*/ |
|||
var outputTransactionFormatter = function (tx){ |
|||
if(tx.blockNumber !== null) |
|||
tx.blockNumber = utils.toDecimal(tx.blockNumber); |
|||
if(tx.transactionIndex !== null) |
|||
tx.transactionIndex = utils.toDecimal(tx.transactionIndex); |
|||
tx.nonce = utils.toDecimal(tx.nonce); |
|||
tx.gas = utils.toDecimal(tx.gas); |
|||
tx.gasPrice = utils.toBigNumber(tx.gasPrice); |
|||
tx.value = utils.toBigNumber(tx.value); |
|||
return tx; |
|||
}; |
|||
|
|||
/** |
|||
* Formats the output of a transaction receipt to its proper values |
|||
* |
|||
* @method outputTransactionReceiptFormatter |
|||
* @param {Object} receipt |
|||
* @returns {Object} |
|||
*/ |
|||
var outputTransactionReceiptFormatter = function (receipt){ |
|||
if(receipt.blockNumber !== null) |
|||
receipt.blockNumber = utils.toDecimal(receipt.blockNumber); |
|||
if(receipt.transactionIndex !== null) |
|||
receipt.transactionIndex = utils.toDecimal(receipt.transactionIndex); |
|||
receipt.cumulativeGasUsed = utils.toDecimal(receipt.cumulativeGasUsed); |
|||
receipt.gasUsed = utils.toDecimal(receipt.gasUsed); |
|||
|
|||
if(utils.isArray(receipt.logs)) { |
|||
receipt.logs = receipt.logs.map(function(log){ |
|||
return outputLogFormatter(log); |
|||
}); |
|||
} |
|||
|
|||
return receipt; |
|||
}; |
|||
|
|||
/** |
|||
* Formats the output of a block to its proper values |
|||
* |
|||
* @method outputBlockFormatter |
|||
* @param {Object} block |
|||
* @returns {Object} |
|||
*/ |
|||
var outputBlockFormatter = function(block) { |
|||
|
|||
// transform to number
|
|||
block.gasLimit = utils.toDecimal(block.gasLimit); |
|||
block.gasUsed = utils.toDecimal(block.gasUsed); |
|||
block.size = utils.toDecimal(block.size); |
|||
block.timestamp = utils.toDecimal(block.timestamp); |
|||
if(block.number !== null) |
|||
block.number = utils.toDecimal(block.number); |
|||
|
|||
block.difficulty = utils.toBigNumber(block.difficulty); |
|||
block.totalDifficulty = utils.toBigNumber(block.totalDifficulty); |
|||
|
|||
if (utils.isArray(block.transactions)) { |
|||
block.transactions.forEach(function(item){ |
|||
if(!utils.isString(item)) |
|||
return outputTransactionFormatter(item); |
|||
}); |
|||
} |
|||
|
|||
return block; |
|||
}; |
|||
|
|||
/** |
|||
* Formats the output of a log |
|||
* |
|||
* @method outputLogFormatter |
|||
* @param {Object} log object |
|||
* @returns {Object} log |
|||
*/ |
|||
var outputLogFormatter = function(log) { |
|||
if(log.blockNumber !== null) |
|||
log.blockNumber = utils.toDecimal(log.blockNumber); |
|||
if(log.transactionIndex !== null) |
|||
log.transactionIndex = utils.toDecimal(log.transactionIndex); |
|||
if(log.logIndex !== null) |
|||
log.logIndex = utils.toDecimal(log.logIndex); |
|||
|
|||
return log; |
|||
}; |
|||
|
|||
/** |
|||
* Formats the input of a whisper post and converts all values to HEX |
|||
* |
|||
* @method inputPostFormatter |
|||
* @param {Object} transaction object |
|||
* @returns {Object} |
|||
*/ |
|||
var inputPostFormatter = function(post) { |
|||
|
|||
post.payload = utils.toHex(post.payload); |
|||
post.ttl = utils.fromDecimal(post.ttl); |
|||
post.workToProve = utils.fromDecimal(post.workToProve); |
|||
post.priority = utils.fromDecimal(post.priority); |
|||
|
|||
// fallback
|
|||
if (!utils.isArray(post.topics)) { |
|||
post.topics = post.topics ? [post.topics] : []; |
|||
} |
|||
|
|||
// format the following options
|
|||
post.topics = post.topics.map(function(topic){ |
|||
return utils.fromAscii(topic); |
|||
}); |
|||
|
|||
return post; |
|||
}; |
|||
|
|||
/** |
|||
* Formats the output of a received post message |
|||
* |
|||
* @method outputPostFormatter |
|||
* @param {Object} |
|||
* @returns {Object} |
|||
*/ |
|||
var outputPostFormatter = function(post){ |
|||
|
|||
post.expiry = utils.toDecimal(post.expiry); |
|||
post.sent = utils.toDecimal(post.sent); |
|||
post.ttl = utils.toDecimal(post.ttl); |
|||
post.workProved = utils.toDecimal(post.workProved); |
|||
post.payloadRaw = post.payload; |
|||
post.payload = utils.toAscii(post.payload); |
|||
|
|||
if (utils.isJson(post.payload)) { |
|||
post.payload = JSON.parse(post.payload); |
|||
} |
|||
|
|||
// format the following options
|
|||
if (!post.topics) { |
|||
post.topics = []; |
|||
} |
|||
post.topics = post.topics.map(function(topic){ |
|||
return utils.toAscii(topic); |
|||
}); |
|||
|
|||
return post; |
|||
}; |
|||
|
|||
module.exports = { |
|||
inputDefaultBlockNumberFormatter: inputDefaultBlockNumberFormatter, |
|||
inputBlockNumberFormatter: inputBlockNumberFormatter, |
|||
inputTransactionFormatter: inputTransactionFormatter, |
|||
inputPostFormatter: inputPostFormatter, |
|||
outputBigNumberFormatter: outputBigNumberFormatter, |
|||
outputTransactionFormatter: outputTransactionFormatter, |
|||
outputTransactionReceiptFormatter: outputTransactionReceiptFormatter, |
|||
outputBlockFormatter: outputBlockFormatter, |
|||
outputLogFormatter: outputLogFormatter, |
|||
outputPostFormatter: outputPostFormatter |
|||
}; |
|||
|
@ -1,235 +0,0 @@ |
|||
/* |
|||
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 function.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var web3 = require('../web3'); |
|||
var coder = require('../solidity/coder'); |
|||
var utils = require('../utils/utils'); |
|||
var formatters = require('./formatters'); |
|||
var sha3 = require('../utils/sha3'); |
|||
|
|||
/** |
|||
* This prototype should be used to call/sendTransaction to solidity functions |
|||
*/ |
|||
var SolidityFunction = function (json, address) { |
|||
this._inputTypes = json.inputs.map(function (i) { |
|||
return i.type; |
|||
}); |
|||
this._outputTypes = json.outputs.map(function (i) { |
|||
return i.type; |
|||
}); |
|||
this._constant = json.constant; |
|||
this._name = utils.transformToFullName(json); |
|||
this._address = address; |
|||
}; |
|||
|
|||
SolidityFunction.prototype.extractCallback = function (args) { |
|||
if (utils.isFunction(args[args.length - 1])) { |
|||
return args.pop(); // modify the args array!
|
|||
} |
|||
}; |
|||
|
|||
SolidityFunction.prototype.extractDefaultBlock = function (args) { |
|||
if (args.length > this._inputTypes.length && !utils.isObject(args[args.length -1])) { |
|||
return formatters.inputDefaultBlockNumberFormatter(args.pop()); // modify the args array!
|
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to create payload from arguments |
|||
* |
|||
* @method toPayload |
|||
* @param {Array} solidity function params |
|||
* @param {Object} optional payload options |
|||
*/ |
|||
SolidityFunction.prototype.toPayload = function (args) { |
|||
var options = {}; |
|||
if (args.length > this._inputTypes.length && utils.isObject(args[args.length -1])) { |
|||
options = args[args.length - 1]; |
|||
} |
|||
options.to = this._address; |
|||
options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args); |
|||
return options; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to get function signature |
|||
* |
|||
* @method signature |
|||
* @return {String} function signature |
|||
*/ |
|||
SolidityFunction.prototype.signature = function () { |
|||
return sha3(this._name).slice(0, 8); |
|||
}; |
|||
|
|||
|
|||
SolidityFunction.prototype.unpackOutput = function (output) { |
|||
if (!output) { |
|||
return; |
|||
} |
|||
|
|||
output = output.length >= 2 ? output.slice(2) : output; |
|||
var result = coder.decodeParams(this._outputTypes, output); |
|||
return result.length === 1 ? result[0] : result; |
|||
}; |
|||
|
|||
/** |
|||
* Calls a contract function. |
|||
* |
|||
* @method call |
|||
* @param {...Object} Contract function arguments |
|||
* @param {function} If the last argument is a function, the contract function |
|||
* call will be asynchronous, and the callback will be passed the |
|||
* error and result. |
|||
* @return {String} output bytes |
|||
*/ |
|||
SolidityFunction.prototype.call = function () { |
|||
var args = Array.prototype.slice.call(arguments).filter(function (a) {return a !== undefined; }); |
|||
var callback = this.extractCallback(args); |
|||
var defaultBlock = this.extractDefaultBlock(args); |
|||
var payload = this.toPayload(args); |
|||
|
|||
|
|||
if (!callback) { |
|||
var output = web3.eth.call(payload, defaultBlock); |
|||
return this.unpackOutput(output); |
|||
} |
|||
|
|||
var self = this; |
|||
web3.eth.call(payload, defaultBlock, function (error, output) { |
|||
callback(error, self.unpackOutput(output)); |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to sendTransaction to solidity function |
|||
* |
|||
* @method sendTransaction |
|||
* @param {Object} options |
|||
*/ |
|||
SolidityFunction.prototype.sendTransaction = function () { |
|||
var args = Array.prototype.slice.call(arguments).filter(function (a) {return a !== undefined; }); |
|||
var callback = this.extractCallback(args); |
|||
var payload = this.toPayload(args); |
|||
|
|||
if (!callback) { |
|||
return web3.eth.sendTransaction(payload); |
|||
} |
|||
|
|||
web3.eth.sendTransaction(payload, callback); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to estimateGas of solidity function |
|||
* |
|||
* @method estimateGas |
|||
* @param {Object} options |
|||
*/ |
|||
SolidityFunction.prototype.estimateGas = function () { |
|||
var args = Array.prototype.slice.call(arguments); |
|||
var callback = this.extractCallback(args); |
|||
var payload = this.toPayload(args); |
|||
|
|||
if (!callback) { |
|||
return web3.eth.estimateGas(payload); |
|||
} |
|||
|
|||
web3.eth.estimateGas(payload, callback); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to get function display name |
|||
* |
|||
* @method displayName |
|||
* @return {String} display name of the function |
|||
*/ |
|||
SolidityFunction.prototype.displayName = function () { |
|||
return utils.extractDisplayName(this._name); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to get function type name |
|||
* |
|||
* @method typeName |
|||
* @return {String} type name of the function |
|||
*/ |
|||
SolidityFunction.prototype.typeName = function () { |
|||
return utils.extractTypeName(this._name); |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to get rpc requests from solidity function |
|||
* |
|||
* @method request |
|||
* @returns {Object} |
|||
*/ |
|||
SolidityFunction.prototype.request = function () { |
|||
var args = Array.prototype.slice.call(arguments); |
|||
var callback = this.extractCallback(args); |
|||
var payload = this.toPayload(args); |
|||
var format = this.unpackOutput.bind(this); |
|||
|
|||
return { |
|||
method: this._constant ? 'eth_call' : 'eth_sendTransaction', |
|||
callback: callback, |
|||
params: [payload], |
|||
format: format |
|||
}; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to execute function |
|||
* |
|||
* @method execute |
|||
*/ |
|||
SolidityFunction.prototype.execute = function () { |
|||
var transaction = !this._constant; |
|||
|
|||
// send transaction
|
|||
if (transaction) { |
|||
return this.sendTransaction.apply(this, Array.prototype.slice.call(arguments)); |
|||
} |
|||
|
|||
// call
|
|||
return this.call.apply(this, Array.prototype.slice.call(arguments)); |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to attach function to contract |
|||
* |
|||
* @method attachToContract |
|||
* @param {Contract} |
|||
*/ |
|||
SolidityFunction.prototype.attachToContract = function (contract) { |
|||
var execute = this.execute.bind(this); |
|||
execute.request = this.request.bind(this); |
|||
execute.call = this.call.bind(this); |
|||
execute.sendTransaction = this.sendTransaction.bind(this); |
|||
execute.estimateGas = this.estimateGas.bind(this); |
|||
var displayName = this.displayName(); |
|||
if (!contract[displayName]) { |
|||
contract[displayName] = execute; |
|||
} |
|||
contract[displayName][this.typeName()] = execute; // circular!!!!
|
|||
}; |
|||
|
|||
module.exports = SolidityFunction; |
|||
|
@ -1,111 +0,0 @@ |
|||
/* |
|||
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 httpprovider.js |
|||
* @authors: |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* Marian Oancea <marian@ethdev.com> |
|||
* Fabian Vogelsteller <fabian@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
"use strict"; |
|||
|
|||
var XMLHttpRequest = (typeof window !== 'undefined' && window.XMLHttpRequest) ? window.XMLHttpRequest : require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line
|
|||
var errors = require('./errors'); |
|||
|
|||
var HttpProvider = function (host) { |
|||
this.host = host || 'http://localhost:8545'; |
|||
}; |
|||
|
|||
HttpProvider.prototype.isConnected = function() { |
|||
var request = new XMLHttpRequest(); |
|||
|
|||
request.open('POST', this.host, false); |
|||
request.setRequestHeader('Content-type','application/json'); |
|||
|
|||
try { |
|||
request.send(JSON.stringify({ |
|||
id: 9999999999, |
|||
jsonrpc: '2.0', |
|||
method: 'net_listening', |
|||
params: [] |
|||
})); |
|||
return true; |
|||
} catch(e) { |
|||
return false; |
|||
} |
|||
}; |
|||
|
|||
HttpProvider.prototype.send = function (payload) { |
|||
var request = new XMLHttpRequest(); |
|||
|
|||
request.open('POST', this.host, false); |
|||
request.setRequestHeader('Content-type','application/json'); |
|||
|
|||
try { |
|||
request.send(JSON.stringify(payload)); |
|||
} catch(error) { |
|||
throw errors.InvalidConnection(this.host); |
|||
} |
|||
|
|||
|
|||
// check request.status
|
|||
// TODO: throw an error here! it cannot silently fail!!!
|
|||
//if (request.status !== 200) {
|
|||
//return;
|
|||
//}
|
|||
|
|||
var result = request.responseText; |
|||
|
|||
try { |
|||
result = JSON.parse(result); |
|||
} catch(e) { |
|||
throw errors.InvalidResponse(request.responseText); |
|||
} |
|||
|
|||
return result; |
|||
}; |
|||
|
|||
HttpProvider.prototype.sendAsync = function (payload, callback) { |
|||
var request = new XMLHttpRequest(); |
|||
request.onreadystatechange = function() { |
|||
if (request.readyState === 4) { |
|||
var result = request.responseText; |
|||
var error = null; |
|||
|
|||
try { |
|||
result = JSON.parse(result); |
|||
} catch(e) { |
|||
error = errors.InvalidResponse(request.responseText); |
|||
} |
|||
|
|||
callback(error, result); |
|||
} |
|||
}; |
|||
|
|||
request.open('POST', this.host, true); |
|||
request.setRequestHeader('Content-type','application/json'); |
|||
|
|||
try { |
|||
request.send(JSON.stringify(payload)); |
|||
} catch(error) { |
|||
callback(errors.InvalidConnection(this.host)); |
|||
} |
|||
}; |
|||
|
|||
module.exports = HttpProvider; |
|||
|
@ -1,108 +0,0 @@ |
|||
/* |
|||
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 icap.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var utils = require('../utils/utils'); |
|||
|
|||
/** |
|||
* This prototype should be used to extract necessary information from iban address |
|||
* |
|||
* @param {String} iban |
|||
*/ |
|||
var ICAP = function (iban) { |
|||
this._iban = iban; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to check if icap is correct |
|||
* |
|||
* @method isValid |
|||
* @returns {Boolean} true if it is, otherwise false |
|||
*/ |
|||
ICAP.prototype.isValid = function () { |
|||
return utils.isIBAN(this._iban); |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to check if iban number is direct |
|||
* |
|||
* @method isDirect |
|||
* @returns {Boolean} true if it is, otherwise false |
|||
*/ |
|||
ICAP.prototype.isDirect = function () { |
|||
return this._iban.length === 34; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to check if iban number if indirect |
|||
* |
|||
* @method isIndirect |
|||
* @returns {Boolean} true if it is, otherwise false |
|||
*/ |
|||
ICAP.prototype.isIndirect = function () { |
|||
return this._iban.length === 20; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to get iban checksum |
|||
* Uses the mod-97-10 checksumming protocol (ISO/IEC 7064:2003) |
|||
* |
|||
* @method checksum |
|||
* @returns {String} checksum |
|||
*/ |
|||
ICAP.prototype.checksum = function () { |
|||
return this._iban.substr(2, 2); |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to get institution identifier |
|||
* eg. XREG |
|||
* |
|||
* @method institution |
|||
* @returns {String} institution identifier |
|||
*/ |
|||
ICAP.prototype.institution = function () { |
|||
return this.isIndirect() ? this._iban.substr(7, 4) : ''; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to get client identifier within institution |
|||
* eg. GAVOFYORK |
|||
* |
|||
* @method client |
|||
* @returns {String} client identifier |
|||
*/ |
|||
ICAP.prototype.client = function () { |
|||
return this.isIndirect() ? this._iban.substr(11) : ''; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to get client direct address |
|||
* |
|||
* @method address |
|||
* @returns {String} client direct address |
|||
*/ |
|||
ICAP.prototype.address = function () { |
|||
return this.isDirect() ? this._iban.substr(4) : ''; |
|||
}; |
|||
|
|||
module.exports = ICAP; |
|||
|
@ -1,211 +0,0 @@ |
|||
/* |
|||
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 ipcprovider.js |
|||
* @authors: |
|||
* Fabian Vogelsteller <fabian@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
"use strict"; |
|||
|
|||
var utils = require('../utils/utils'); |
|||
var errors = require('./errors'); |
|||
|
|||
var errorTimeout = '{"jsonrpc": "2.0", "error": {"code": -32603, "message": "IPC Request timed out for method \'__method__\'"}, "id": "__id__"}'; |
|||
|
|||
|
|||
var IpcProvider = function (path, net) { |
|||
var _this = this; |
|||
this.responseCallbacks = {}; |
|||
this.path = path; |
|||
|
|||
net = net || require('net'); |
|||
|
|||
this.connection = net.connect({path: this.path}); |
|||
|
|||
this.connection.on('error', function(e){ |
|||
console.error('IPC Connection Error', e); |
|||
_this._timeout(); |
|||
}); |
|||
|
|||
this.connection.on('end', function(){ |
|||
_this._timeout(); |
|||
}); |
|||
|
|||
|
|||
// LISTEN FOR CONNECTION RESPONSES
|
|||
this.connection.on('data', function(data) { |
|||
/*jshint maxcomplexity: 6 */ |
|||
|
|||
_this._parseResponse(data.toString()).forEach(function(result){ |
|||
|
|||
var id = null; |
|||
|
|||
// get the id which matches the returned id
|
|||
if(utils.isArray(result)) { |
|||
result.forEach(function(load){ |
|||
if(_this.responseCallbacks[load.id]) |
|||
id = load.id; |
|||
}); |
|||
} else { |
|||
id = result.id; |
|||
} |
|||
|
|||
// fire the callback
|
|||
if(_this.responseCallbacks[id]) { |
|||
_this.responseCallbacks[id](null, result); |
|||
delete _this.responseCallbacks[id]; |
|||
} |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
Will parse the response and make an array out of it. |
|||
|
|||
@method _parseResponse |
|||
@param {String} data |
|||
*/ |
|||
IpcProvider.prototype._parseResponse = function(data) { |
|||
var _this = this, |
|||
returnValues = []; |
|||
|
|||
// DE-CHUNKER
|
|||
var dechunkedData = data |
|||
.replace(/\}\{/g,'}|--|{') // }{
|
|||
.replace(/\}\]\[\{/g,'}]|--|[{') // }][{
|
|||
.replace(/\}\[\{/g,'}|--|[{') // }[{
|
|||
.replace(/\}\]\{/g,'}]|--|{') // }]{
|
|||
.split('|--|'); |
|||
|
|||
dechunkedData.forEach(function(data){ |
|||
|
|||
// prepend the last chunk
|
|||
if(_this.lastChunk) |
|||
data = _this.lastChunk + data; |
|||
|
|||
var result = null; |
|||
|
|||
try { |
|||
result = JSON.parse(data); |
|||
|
|||
} catch(e) { |
|||
|
|||
_this.lastChunk = data; |
|||
|
|||
// start timeout to cancel all requests
|
|||
clearTimeout(_this.lastChunkTimeout); |
|||
_this.lastChunkTimeout = setTimeout(function(){ |
|||
_this.timeout(); |
|||
throw errors.InvalidResponse(data); |
|||
}, 1000 * 15); |
|||
|
|||
return; |
|||
} |
|||
|
|||
// cancel timeout and set chunk to null
|
|||
clearTimeout(_this.lastChunkTimeout); |
|||
_this.lastChunk = null; |
|||
|
|||
if(result) |
|||
returnValues.push(result); |
|||
}); |
|||
|
|||
return returnValues; |
|||
}; |
|||
|
|||
|
|||
/** |
|||
Get the adds a callback to the responseCallbacks object, |
|||
which will be called if a response matching the response Id will arrive. |
|||
|
|||
@method _addResponseCallback |
|||
*/ |
|||
IpcProvider.prototype._addResponseCallback = function(payload, callback) { |
|||
var id = payload.id || payload[0].id; |
|||
var method = payload.method || payload[0].method; |
|||
|
|||
this.responseCallbacks[id] = callback; |
|||
this.responseCallbacks[id].method = method; |
|||
}; |
|||
|
|||
/** |
|||
Timeout all requests when the end/error event is fired |
|||
|
|||
@method _timeout |
|||
*/ |
|||
IpcProvider.prototype._timeout = function() { |
|||
for(var key in this.responseCallbacks) { |
|||
if(this.responseCallbacks.hasOwnProperty(key)){ |
|||
this.responseCallbacks[key](errorTimeout.replace('__id__', key).replace('__method__', this.responseCallbacks[key].method)); |
|||
delete this.responseCallbacks[key]; |
|||
} |
|||
} |
|||
}; |
|||
|
|||
|
|||
/** |
|||
Check if the current connection is still valid. |
|||
|
|||
@method isConnected |
|||
*/ |
|||
IpcProvider.prototype.isConnected = function() { |
|||
var _this = this; |
|||
|
|||
// try reconnect, when connection is gone
|
|||
if(!_this.connection.writable) |
|||
_this.connection.connect({path: _this.path}); |
|||
|
|||
return !!this.connection.writable; |
|||
}; |
|||
|
|||
IpcProvider.prototype.send = function (payload) { |
|||
|
|||
if(this.connection.writeSync) { |
|||
var result; |
|||
|
|||
// try reconnect, when connection is gone
|
|||
if(!this.connection.writable) |
|||
this.connection.connect({path: this.path}); |
|||
|
|||
var data = this.connection.writeSync(JSON.stringify(payload)); |
|||
|
|||
try { |
|||
result = JSON.parse(data); |
|||
} catch(e) { |
|||
throw errors.InvalidResponse(data); |
|||
} |
|||
|
|||
return result; |
|||
|
|||
} else { |
|||
throw new Error('You tried to send "'+ payload.method +'" synchronously. Synchronous requests are not supported by the IPC provider.'); |
|||
} |
|||
}; |
|||
|
|||
IpcProvider.prototype.sendAsync = function (payload, callback) { |
|||
// try reconnect, when connection is gone
|
|||
if(!this.connection.writable) |
|||
this.connection.connect({path: this.path}); |
|||
|
|||
|
|||
this.connection.write(JSON.stringify(payload)); |
|||
this._addResponseCallback(payload, callback); |
|||
}; |
|||
|
|||
module.exports = IpcProvider; |
|||
|
@ -1,91 +0,0 @@ |
|||
/* |
|||
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 jsonrpc.js |
|||
* @authors: |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var Jsonrpc = function () { |
|||
// singleton pattern
|
|||
if (arguments.callee._singletonInstance) { |
|||
return arguments.callee._singletonInstance; |
|||
} |
|||
arguments.callee._singletonInstance = this; |
|||
|
|||
this.messageId = 1; |
|||
}; |
|||
|
|||
/** |
|||
* @return {Jsonrpc} singleton |
|||
*/ |
|||
Jsonrpc.getInstance = function () { |
|||
var instance = new Jsonrpc(); |
|||
return instance; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to valid json create payload object |
|||
* |
|||
* @method toPayload |
|||
* @param {Function} method of jsonrpc call, required |
|||
* @param {Array} params, an array of method params, optional |
|||
* @returns {Object} valid jsonrpc payload object |
|||
*/ |
|||
Jsonrpc.prototype.toPayload = function (method, params) { |
|||
if (!method) |
|||
console.error('jsonrpc method should be specified!'); |
|||
|
|||
return { |
|||
jsonrpc: '2.0', |
|||
method: method, |
|||
params: params || [], |
|||
id: this.messageId++ |
|||
}; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to check if jsonrpc response is valid |
|||
* |
|||
* @method isValidResponse |
|||
* @param {Object} |
|||
* @returns {Boolean} true if response is valid, otherwise false |
|||
*/ |
|||
Jsonrpc.prototype.isValidResponse = function (response) { |
|||
return !!response && |
|||
!response.error && |
|||
response.jsonrpc === '2.0' && |
|||
typeof response.id === 'number' && |
|||
response.result !== undefined; // only undefined is not valid json object
|
|||
}; |
|||
|
|||
/** |
|||
* Should be called to create batch payload object |
|||
* |
|||
* @method toBatchPayload |
|||
* @param {Array} messages, an array of objects with method (required) and params (optional) fields |
|||
* @returns {Array} batch payload |
|||
*/ |
|||
Jsonrpc.prototype.toBatchPayload = function (messages) { |
|||
var self = this; |
|||
return messages.map(function (message) { |
|||
return self.toPayload(message.method, message.params); |
|||
}); |
|||
}; |
|||
|
|||
module.exports = Jsonrpc; |
|||
|
@ -1,172 +0,0 @@ |
|||
/* |
|||
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 method.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var RequestManager = require('./requestmanager'); |
|||
var utils = require('../utils/utils'); |
|||
var errors = require('./errors'); |
|||
|
|||
var Method = function (options) { |
|||
this.name = options.name; |
|||
this.call = options.call; |
|||
this.params = options.params || 0; |
|||
this.inputFormatter = options.inputFormatter; |
|||
this.outputFormatter = options.outputFormatter; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to determine name of the jsonrpc method based on arguments |
|||
* |
|||
* @method getCall |
|||
* @param {Array} arguments |
|||
* @return {String} name of jsonrpc method |
|||
*/ |
|||
Method.prototype.getCall = function (args) { |
|||
return utils.isFunction(this.call) ? this.call(args) : this.call; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to extract callback from array of arguments. Modifies input param |
|||
* |
|||
* @method extractCallback |
|||
* @param {Array} arguments |
|||
* @return {Function|Null} callback, if exists |
|||
*/ |
|||
Method.prototype.extractCallback = function (args) { |
|||
if (utils.isFunction(args[args.length - 1])) { |
|||
return args.pop(); // modify the args array!
|
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to check if the number of arguments is correct |
|||
* |
|||
* @method validateArgs |
|||
* @param {Array} arguments |
|||
* @throws {Error} if it is not |
|||
*/ |
|||
Method.prototype.validateArgs = function (args) { |
|||
if (args.length !== this.params) { |
|||
throw errors.InvalidNumberOfParams(); |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to format input args of method |
|||
* |
|||
* @method formatInput |
|||
* @param {Array} |
|||
* @return {Array} |
|||
*/ |
|||
Method.prototype.formatInput = function (args) { |
|||
if (!this.inputFormatter) { |
|||
return args; |
|||
} |
|||
|
|||
return this.inputFormatter.map(function (formatter, index) { |
|||
return formatter ? formatter(args[index]) : args[index]; |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to format output(result) of method |
|||
* |
|||
* @method formatOutput |
|||
* @param {Object} |
|||
* @return {Object} |
|||
*/ |
|||
Method.prototype.formatOutput = function (result) { |
|||
return this.outputFormatter && result ? this.outputFormatter(result) : result; |
|||
}; |
|||
|
|||
/** |
|||
* Should attach function to method |
|||
* |
|||
* @method attachToObject |
|||
* @param {Object} |
|||
* @param {Function} |
|||
*/ |
|||
Method.prototype.attachToObject = function (obj) { |
|||
var func = this.send.bind(this); |
|||
func.request = this.request.bind(this); |
|||
func.call = this.call; // that's ugly. filter.js uses it
|
|||
var name = this.name.split('.'); |
|||
if (name.length > 1) { |
|||
obj[name[0]] = obj[name[0]] || {}; |
|||
obj[name[0]][name[1]] = func; |
|||
} else { |
|||
obj[name[0]] = func; |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* Should create payload from given input args |
|||
* |
|||
* @method toPayload |
|||
* @param {Array} args |
|||
* @return {Object} |
|||
*/ |
|||
Method.prototype.toPayload = function (args) { |
|||
var call = this.getCall(args); |
|||
var callback = this.extractCallback(args); |
|||
var params = this.formatInput(args); |
|||
this.validateArgs(params); |
|||
|
|||
return { |
|||
method: call, |
|||
params: params, |
|||
callback: callback |
|||
}; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to create pure JSONRPC request which can be used in batch request |
|||
* |
|||
* @method request |
|||
* @param {...} params |
|||
* @return {Object} jsonrpc request |
|||
*/ |
|||
Method.prototype.request = function () { |
|||
var payload = this.toPayload(Array.prototype.slice.call(arguments)); |
|||
payload.format = this.formatOutput.bind(this); |
|||
return payload; |
|||
}; |
|||
|
|||
/** |
|||
* Should send request to the API |
|||
* |
|||
* @method send |
|||
* @param list of params |
|||
* @return result |
|||
*/ |
|||
Method.prototype.send = function () { |
|||
var payload = this.toPayload(Array.prototype.slice.call(arguments)); |
|||
if (payload.callback) { |
|||
var self = this; |
|||
return RequestManager.getInstance().sendAsync(payload, function (err, result) { |
|||
payload.callback(err, self.formatOutput(result)); |
|||
}); |
|||
} |
|||
return this.formatOutput(RequestManager.getInstance().send(payload)); |
|||
}; |
|||
|
|||
module.exports = Method; |
|||
|
@ -1,46 +0,0 @@ |
|||
/* |
|||
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 namereg.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var contract = require('./contract'); |
|||
|
|||
var address = '0xc6d9d2cd449a754c494264e1809c50e34d64562b'; |
|||
|
|||
var abi = [ |
|||
{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"name","outputs":[{"name":"o_name","type":"bytes32"}],"type":"function"}, |
|||
{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"}, |
|||
{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"content","outputs":[{"name":"","type":"bytes32"}],"type":"function"}, |
|||
{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"addr","outputs":[{"name":"","type":"address"}],"type":"function"}, |
|||
{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"reserve","outputs":[],"type":"function"}, |
|||
{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"subRegistrar","outputs":[{"name":"o_subRegistrar","type":"address"}],"type":"function"}, |
|||
{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_newOwner","type":"address"}],"name":"transfer","outputs":[],"type":"function"}, |
|||
{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_registrar","type":"address"}],"name":"setSubRegistrar","outputs":[],"type":"function"}, |
|||
{"constant":false,"inputs":[],"name":"Registrar","outputs":[],"type":"function"}, |
|||
{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_a","type":"address"},{"name":"_primary","type":"bool"}],"name":"setAddress","outputs":[],"type":"function"}, |
|||
{"constant":false,"inputs":[{"name":"_name","type":"bytes32"},{"name":"_content","type":"bytes32"}],"name":"setContent","outputs":[],"type":"function"}, |
|||
{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"disown","outputs":[],"type":"function"}, |
|||
{"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"register","outputs":[{"name":"","type":"address"}],"type":"function"}, |
|||
{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"}],"name":"Changed","type":"event"}, |
|||
{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"bytes32"},{"indexed":true,"name":"addr","type":"address"}],"name":"PrimaryChanged","type":"event"} |
|||
]; |
|||
|
|||
module.exports = contract(abi).at(address); |
|||
|
@ -1,48 +0,0 @@ |
|||
/* |
|||
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 eth.js |
|||
* @authors: |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var utils = require('../utils/utils'); |
|||
var Property = require('./property'); |
|||
|
|||
/// @returns an array of objects describing web3.eth api methods
|
|||
var methods = [ |
|||
]; |
|||
|
|||
/// @returns an array of objects describing web3.eth api properties
|
|||
var properties = [ |
|||
new Property({ |
|||
name: 'listening', |
|||
getter: 'net_listening' |
|||
}), |
|||
new Property({ |
|||
name: 'peerCount', |
|||
getter: 'net_peerCount', |
|||
outputFormatter: utils.toDecimal |
|||
}) |
|||
]; |
|||
|
|||
|
|||
module.exports = { |
|||
methods: methods, |
|||
properties: properties |
|||
}; |
|||
|
@ -1,150 +0,0 @@ |
|||
/* |
|||
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 property.js |
|||
* @author Fabian Vogelsteller <fabian@frozeman.de> |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var RequestManager = require('./requestmanager'); |
|||
var utils = require('../utils/utils'); |
|||
|
|||
var Property = function (options) { |
|||
this.name = options.name; |
|||
this.getter = options.getter; |
|||
this.setter = options.setter; |
|||
this.outputFormatter = options.outputFormatter; |
|||
this.inputFormatter = options.inputFormatter; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to format input args of method |
|||
* |
|||
* @method formatInput |
|||
* @param {Array} |
|||
* @return {Array} |
|||
*/ |
|||
Property.prototype.formatInput = function (arg) { |
|||
return this.inputFormatter ? this.inputFormatter(arg) : arg; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to format output(result) of method |
|||
* |
|||
* @method formatOutput |
|||
* @param {Object} |
|||
* @return {Object} |
|||
*/ |
|||
Property.prototype.formatOutput = function (result) { |
|||
return this.outputFormatter && result !== null ? this.outputFormatter(result) : result; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to extract callback from array of arguments. Modifies input param |
|||
* |
|||
* @method extractCallback |
|||
* @param {Array} arguments |
|||
* @return {Function|Null} callback, if exists |
|||
*/ |
|||
Property.prototype.extractCallback = function (args) { |
|||
if (utils.isFunction(args[args.length - 1])) { |
|||
return args.pop(); // modify the args array!
|
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* Should attach function to method |
|||
* |
|||
* @method attachToObject |
|||
* @param {Object} |
|||
* @param {Function} |
|||
*/ |
|||
Property.prototype.attachToObject = function (obj) { |
|||
var proto = { |
|||
get: this.get.bind(this), |
|||
}; |
|||
|
|||
var names = this.name.split('.'); |
|||
var name = names[0]; |
|||
if (names.length > 1) { |
|||
obj[names[0]] = obj[names[0]] || {}; |
|||
obj = obj[names[0]]; |
|||
name = names[1]; |
|||
} |
|||
|
|||
Object.defineProperty(obj, name, proto); |
|||
|
|||
var toAsyncName = function (prefix, name) { |
|||
return prefix + name.charAt(0).toUpperCase() + name.slice(1); |
|||
}; |
|||
|
|||
var func = this.getAsync.bind(this); |
|||
func.request = this.request.bind(this); |
|||
|
|||
obj[toAsyncName('get', name)] = func; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to get value of the property |
|||
* |
|||
* @method get |
|||
* @return {Object} value of the property |
|||
*/ |
|||
Property.prototype.get = function () { |
|||
return this.formatOutput(RequestManager.getInstance().send({ |
|||
method: this.getter |
|||
})); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to asynchrounously get value of property |
|||
* |
|||
* @method getAsync |
|||
* @param {Function} |
|||
*/ |
|||
Property.prototype.getAsync = function (callback) { |
|||
var self = this; |
|||
RequestManager.getInstance().sendAsync({ |
|||
method: this.getter |
|||
}, function (err, result) { |
|||
if (err) { |
|||
return callback(err); |
|||
} |
|||
callback(err, self.formatOutput(result)); |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to create pure JSONRPC request which can be used in batch request |
|||
* |
|||
* @method request |
|||
* @param {...} params |
|||
* @return {Object} jsonrpc request |
|||
*/ |
|||
Property.prototype.request = function () { |
|||
var payload = { |
|||
method: this.getter, |
|||
params: [], |
|||
callback: this.extractCallback(Array.prototype.slice.call(arguments)) |
|||
}; |
|||
payload.format = this.formatOutput.bind(this); |
|||
return payload; |
|||
}; |
|||
|
|||
module.exports = Property; |
|||
|
@ -1,263 +0,0 @@ |
|||
/* |
|||
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 requestmanager.js |
|||
* @author Jeffrey Wilcke <jeff@ethdev.com> |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @author Marian Oancea <marian@ethdev.com> |
|||
* @author Fabian Vogelsteller <fabian@ethdev.com> |
|||
* @author Gav Wood <g@ethdev.com> |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
var Jsonrpc = require('./jsonrpc'); |
|||
var utils = require('../utils/utils'); |
|||
var c = require('../utils/config'); |
|||
var errors = require('./errors'); |
|||
|
|||
/** |
|||
* It's responsible for passing messages to providers |
|||
* It's also responsible for polling the ethereum node for incoming messages |
|||
* Default poll timeout is 1 second |
|||
* Singleton |
|||
*/ |
|||
var RequestManager = function (provider) { |
|||
// singleton pattern
|
|||
if (arguments.callee._singletonInstance) { |
|||
return arguments.callee._singletonInstance; |
|||
} |
|||
arguments.callee._singletonInstance = this; |
|||
|
|||
this.provider = provider; |
|||
this.polls = {}; |
|||
this.timeout = null; |
|||
this.isPolling = false; |
|||
}; |
|||
|
|||
/** |
|||
* @return {RequestManager} singleton |
|||
*/ |
|||
RequestManager.getInstance = function () { |
|||
var instance = new RequestManager(); |
|||
return instance; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to synchronously send request |
|||
* |
|||
* @method send |
|||
* @param {Object} data |
|||
* @return {Object} |
|||
*/ |
|||
RequestManager.prototype.send = function (data) { |
|||
if (!this.provider) { |
|||
console.error(errors.InvalidProvider()); |
|||
return null; |
|||
} |
|||
|
|||
var payload = Jsonrpc.getInstance().toPayload(data.method, data.params); |
|||
var result = this.provider.send(payload); |
|||
|
|||
if (!Jsonrpc.getInstance().isValidResponse(result)) { |
|||
throw errors.InvalidResponse(result); |
|||
} |
|||
|
|||
return result.result; |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to asynchronously send request |
|||
* |
|||
* @method sendAsync |
|||
* @param {Object} data |
|||
* @param {Function} callback |
|||
*/ |
|||
RequestManager.prototype.sendAsync = function (data, callback) { |
|||
if (!this.provider) { |
|||
return callback(errors.InvalidProvider()); |
|||
} |
|||
|
|||
var payload = Jsonrpc.getInstance().toPayload(data.method, data.params); |
|||
this.provider.sendAsync(payload, function (err, result) { |
|||
if (err) { |
|||
return callback(err); |
|||
} |
|||
|
|||
if (!Jsonrpc.getInstance().isValidResponse(result)) { |
|||
return callback(errors.InvalidResponse(result)); |
|||
} |
|||
|
|||
callback(null, result.result); |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to asynchronously send batch request |
|||
* |
|||
* @method sendBatch |
|||
* @param {Array} batch data |
|||
* @param {Function} callback |
|||
*/ |
|||
RequestManager.prototype.sendBatch = function (data, callback) { |
|||
if (!this.provider) { |
|||
return callback(errors.InvalidProvider()); |
|||
} |
|||
|
|||
var payload = Jsonrpc.getInstance().toBatchPayload(data); |
|||
|
|||
this.provider.sendAsync(payload, function (err, results) { |
|||
if (err) { |
|||
return callback(err); |
|||
} |
|||
|
|||
if (!utils.isArray(results)) { |
|||
return callback(errors.InvalidResponse(results)); |
|||
} |
|||
|
|||
callback(err, results); |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to set provider of request manager |
|||
* |
|||
* @method setProvider |
|||
* @param {Object} |
|||
*/ |
|||
RequestManager.prototype.setProvider = function (p) { |
|||
this.provider = p; |
|||
|
|||
if (this.provider && !this.isPolling) { |
|||
this.poll(); |
|||
this.isPolling = true; |
|||
} |
|||
}; |
|||
|
|||
/*jshint maxparams:4 */ |
|||
|
|||
/** |
|||
* Should be used to start polling |
|||
* |
|||
* @method startPolling |
|||
* @param {Object} data |
|||
* @param {Number} pollId |
|||
* @param {Function} callback |
|||
* @param {Function} uninstall |
|||
* |
|||
* @todo cleanup number of params |
|||
*/ |
|||
RequestManager.prototype.startPolling = function (data, pollId, callback, uninstall) { |
|||
this.polls['poll_'+ pollId] = {data: data, id: pollId, callback: callback, uninstall: uninstall}; |
|||
}; |
|||
/*jshint maxparams:3 */ |
|||
|
|||
/** |
|||
* Should be used to stop polling for filter with given id |
|||
* |
|||
* @method stopPolling |
|||
* @param {Number} pollId |
|||
*/ |
|||
RequestManager.prototype.stopPolling = function (pollId) { |
|||
delete this.polls['poll_'+ pollId]; |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to reset the polling mechanism of the request manager |
|||
* |
|||
* @method reset |
|||
*/ |
|||
RequestManager.prototype.reset = function () { |
|||
for (var key in this.polls) { |
|||
this.polls[key].uninstall(); |
|||
} |
|||
this.polls = {}; |
|||
|
|||
if (this.timeout) { |
|||
clearTimeout(this.timeout); |
|||
this.timeout = null; |
|||
} |
|||
this.poll(); |
|||
}; |
|||
|
|||
/** |
|||
* Should be called to poll for changes on filter with given id |
|||
* |
|||
* @method poll |
|||
*/ |
|||
RequestManager.prototype.poll = function () { |
|||
/*jshint maxcomplexity: 6 */ |
|||
this.timeout = setTimeout(this.poll.bind(this), c.ETH_POLLING_TIMEOUT); |
|||
|
|||
if (Object.keys(this.polls).length === 0) { |
|||
return; |
|||
} |
|||
|
|||
if (!this.provider) { |
|||
console.error(errors.InvalidProvider()); |
|||
return; |
|||
} |
|||
|
|||
var pollsData = []; |
|||
var pollsKeys = []; |
|||
for (var key in this.polls) { |
|||
pollsData.push(this.polls[key].data); |
|||
pollsKeys.push(key); |
|||
} |
|||
|
|||
if (pollsData.length === 0) { |
|||
return; |
|||
} |
|||
|
|||
var payload = Jsonrpc.getInstance().toBatchPayload(pollsData); |
|||
|
|||
var self = this; |
|||
this.provider.sendAsync(payload, function (error, results) { |
|||
// TODO: console log?
|
|||
if (error) { |
|||
return; |
|||
} |
|||
|
|||
if (!utils.isArray(results)) { |
|||
throw errors.InvalidResponse(results); |
|||
} |
|||
|
|||
results.map(function (result, index) { |
|||
var key = pollsKeys[index]; |
|||
// make sure the filter is still installed after arrival of the request
|
|||
if (self.polls[key]) { |
|||
result.callback = self.polls[key].callback; |
|||
return result; |
|||
} else |
|||
return false; |
|||
}).filter(function (result) { |
|||
return !!result; |
|||
}).filter(function (result) { |
|||
var valid = Jsonrpc.getInstance().isValidResponse(result); |
|||
if (!valid) { |
|||
result.callback(errors.InvalidResponse(result)); |
|||
} |
|||
return valid; |
|||
}).filter(function (result) { |
|||
return utils.isArray(result.result) && result.result.length > 0; |
|||
}).forEach(function (result) { |
|||
result.callback(null, result.result); |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
module.exports = RequestManager; |
|||
|
@ -1,90 +0,0 @@ |
|||
/* |
|||
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 shh.js |
|||
* @authors: |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var Method = require('./method'); |
|||
var formatters = require('./formatters'); |
|||
|
|||
var post = new Method({ |
|||
name: 'post', |
|||
call: 'shh_post', |
|||
params: 1, |
|||
inputFormatter: [formatters.inputPostFormatter] |
|||
}); |
|||
|
|||
var newIdentity = new Method({ |
|||
name: 'newIdentity', |
|||
call: 'shh_newIdentity', |
|||
params: 0 |
|||
}); |
|||
|
|||
var hasIdentity = new Method({ |
|||
name: 'hasIdentity', |
|||
call: 'shh_hasIdentity', |
|||
params: 1 |
|||
}); |
|||
|
|||
var newGroup = new Method({ |
|||
name: 'newGroup', |
|||
call: 'shh_newGroup', |
|||
params: 0 |
|||
}); |
|||
|
|||
var addToGroup = new Method({ |
|||
name: 'addToGroup', |
|||
call: 'shh_addToGroup', |
|||
params: 0 |
|||
}); |
|||
|
|||
|
|||
var newFilter = new Method({ |
|||
name: 'newFilter', |
|||
call: 'shh_newFilter', |
|||
params: 1 |
|||
}); |
|||
|
|||
var getFilterChanges = new Method({ |
|||
name: 'getFilterChanges', |
|||
call: 'shh_getFilterChanges', |
|||
params: 1 |
|||
}); |
|||
|
|||
var getMessages = new Method({ |
|||
name: 'getMessages', |
|||
call: 'shh_getMessages', |
|||
params: 1 |
|||
}) |
|||
|
|||
var methods = [ |
|||
post, |
|||
newIdentity, |
|||
hasIdentity, |
|||
newGroup, |
|||
addToGroup, |
|||
newFilter, |
|||
getFilterChanges, |
|||
getMessages |
|||
]; |
|||
|
|||
module.exports = { |
|||
methods: methods |
|||
}; |
|||
|
@ -1,94 +0,0 @@ |
|||
/* |
|||
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 transfer.js |
|||
* @author Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var web3 = require('../web3'); |
|||
var ICAP = require('./icap'); |
|||
var namereg = require('./namereg'); |
|||
var contract = require('./contract'); |
|||
|
|||
/** |
|||
* Should be used to make ICAP transfer |
|||
* |
|||
* @method transfer |
|||
* @param {String} iban number |
|||
* @param {String} from (address) |
|||
* @param {Value} value to be tranfered |
|||
* @param {Function} callback, callback |
|||
*/ |
|||
var transfer = function (from, iban, value, callback) { |
|||
var icap = new ICAP(iban); |
|||
if (!icap.isValid()) { |
|||
throw new Error('invalid iban address'); |
|||
} |
|||
|
|||
if (icap.isDirect()) { |
|||
return transferToAddress(from, icap.address(), value, callback); |
|||
} |
|||
|
|||
if (!callback) { |
|||
var address = namereg.addr(icap.institution()); |
|||
return deposit(from, address, value, icap.client()); |
|||
} |
|||
|
|||
namereg.addr(icap.insitution(), function (err, address) { |
|||
return deposit(from, address, value, icap.client(), callback); |
|||
}); |
|||
|
|||
}; |
|||
|
|||
/** |
|||
* Should be used to transfer funds to certain address |
|||
* |
|||
* @method transferToAddress |
|||
* @param {String} address |
|||
* @param {String} from (address) |
|||
* @param {Value} value to be tranfered |
|||
* @param {Function} callback, callback |
|||
*/ |
|||
var transferToAddress = function (from, address, value, callback) { |
|||
return web3.eth.sendTransaction({ |
|||
address: address, |
|||
from: from, |
|||
value: value |
|||
}, callback); |
|||
}; |
|||
|
|||
/** |
|||
* Should be used to deposit funds to generic Exchange contract (must implement deposit(bytes32) method!) |
|||
* |
|||
* @method deposit |
|||
* @param {String} address |
|||
* @param {String} from (address) |
|||
* @param {Value} value to be tranfered |
|||
* @param {String} client unique identifier |
|||
* @param {Function} callback, callback |
|||
*/ |
|||
var deposit = function (from, address, value, client, callback) { |
|||
var abi = [{"constant":false,"inputs":[{"name":"name","type":"bytes32"}],"name":"deposit","outputs":[],"type":"function"}]; |
|||
return contract(abi).at(address).deposit(client, { |
|||
from: from, |
|||
value: value |
|||
}, callback); |
|||
}; |
|||
|
|||
module.exports = transfer; |
|||
|
@ -1,114 +0,0 @@ |
|||
/* |
|||
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 watches.js |
|||
* @authors: |
|||
* Marek Kotewicz <marek@ethdev.com> |
|||
* @date 2015 |
|||
*/ |
|||
|
|||
var Method = require('./method'); |
|||
|
|||
/// @returns an array of objects describing web3.eth.filter api methods
|
|||
var eth = function () { |
|||
var newFilterCall = function (args) { |
|||
var type = args[0]; |
|||
|
|||
switch(type) { |
|||
case 'latest': |
|||
args.shift(); |
|||
this.params = 0; |
|||
return 'eth_newBlockFilter'; |
|||
case 'pending': |
|||
args.shift(); |
|||
this.params = 0; |
|||
return 'eth_newPendingTransactionFilter'; |
|||
default: |
|||
return 'eth_newFilter'; |
|||
} |
|||
}; |
|||
|
|||
var newFilter = new Method({ |
|||
name: 'newFilter', |
|||
call: newFilterCall, |
|||
params: 1 |
|||
}); |
|||
|
|||
var uninstallFilter = new Method({ |
|||
name: 'uninstallFilter', |
|||
call: 'eth_uninstallFilter', |
|||
params: 1 |
|||
}); |
|||
|
|||
var getLogs = new Method({ |
|||
name: 'getLogs', |
|||
call: 'eth_getFilterLogs', |
|||
params: 1 |
|||
}); |
|||
|
|||
var poll = new Method({ |
|||
name: 'poll', |
|||
call: 'eth_getFilterChanges', |
|||
params: 1 |
|||
}); |
|||
|
|||
return [ |
|||
newFilter, |
|||
uninstallFilter, |
|||
getLogs, |
|||
poll |
|||
]; |
|||
}; |
|||
|
|||
/// @returns an array of objects describing web3.shh.watch api methods
|
|||
var shh = function () { |
|||
var newFilter = new Method({ |
|||
name: 'newFilter', |
|||
call: 'shh_newFilter', |
|||
params: 1 |
|||
}); |
|||
|
|||
var uninstallFilter = new Method({ |
|||
name: 'uninstallFilter', |
|||
call: 'shh_uninstallFilter', |
|||
params: 1 |
|||
}); |
|||
|
|||
var getLogs = new Method({ |
|||
name: 'getLogs', |
|||
call: 'shh_getMessages', |
|||
params: 1 |
|||
}); |
|||
|
|||
var poll = new Method({ |
|||
name: 'poll', |
|||
call: 'shh_getFilterChanges', |
|||
params: 1 |
|||
}); |
|||
|
|||
return [ |
|||
newFilter, |
|||
uninstallFilter, |
|||
getLogs, |
|||
poll |
|||
]; |
|||
}; |
|||
|
|||
module.exports = { |
|||
eth: eth, |
|||
shh: shh |
|||
}; |
|||
|
@ -1,17 +0,0 @@ |
|||
/* jshint ignore:start */ |
|||
|
|||
|
|||
// Browser environment
|
|||
if(typeof window !== 'undefined') { |
|||
web3 = (typeof window.web3 !== 'undefined') ? window.web3 : require('web3'); |
|||
BigNumber = (typeof window.BigNumber !== 'undefined') ? window.BigNumber : require('bignumber.js'); |
|||
} |
|||
|
|||
|
|||
// Node environment
|
|||
if(typeof global !== 'undefined') { |
|||
web3 = (typeof global.web3 !== 'undefined') ? global.web3 : require('web3'); |
|||
BigNumber = (typeof global.BigNumber !== 'undefined') ? global.BigNumber : require('bignumber.js'); |
|||
} |
|||
|
|||
/* jshint ignore:end */ |
@ -1,28 +0,0 @@ |
|||
/* jshint ignore:start */ |
|||
Package.describe({ |
|||
name: 'ethereum:web3', |
|||
version: '0.9.0', |
|||
summary: 'Ethereum JavaScript API, middleware to talk to a ethreum node over RPC', |
|||
git: 'https://github.com/ethereum/ethereum.js', |
|||
// By default, Meteor will default to using README.md for documentation.
|
|||
// To avoid submitting documentation, set this field to null.
|
|||
documentation: 'README.md' |
|||
}); |
|||
|
|||
Package.onUse(function(api) { |
|||
api.versionsFrom('1.0.3.2'); |
|||
|
|||
// api.use('3stack:bignumber@2.0.0', 'client');
|
|||
|
|||
api.export(['web3', 'BigNumber'], ['client', 'server']); |
|||
|
|||
api.addFiles('dist/web3.js', 'client'); |
|||
api.addFiles('package-init.js', 'client'); |
|||
}); |
|||
|
|||
// Package.onTest(function(api) {
|
|||
// api.use('tinytest');
|
|||
// api.use('test');
|
|||
// api.addFiles('test-tests.js');
|
|||
// });
|
|||
/* jshint ignore:end */ |
@ -1,86 +0,0 @@ |
|||
{ |
|||
"name": "web3", |
|||
"namespace": "ethereum", |
|||
"version": "0.9.0", |
|||
"description": "Ethereum JavaScript API, middleware to talk to a ethereum node over RPC", |
|||
"main": "./index.js", |
|||
"directories": { |
|||
"lib": "./lib" |
|||
}, |
|||
"dependencies": { |
|||
"bignumber.js": "debris/bignumber.js#master", |
|||
"crypto-js": "^3.1.4", |
|||
"xmlhttprequest": "*" |
|||
}, |
|||
"browser": { |
|||
"xmlhttprequest": "./lib/utils/browser-xhr.js" |
|||
}, |
|||
"devDependencies": { |
|||
"bower": ">=1.4.1", |
|||
"browserify": ">=10.0", |
|||
"chai": "^3.0.0", |
|||
"coveralls": "^2.11.2", |
|||
"del": ">=1.2.0", |
|||
"exorcist": "^0.4.0", |
|||
"gulp": ">=3.9.0", |
|||
"gulp-jshint": ">=1.5.0", |
|||
"gulp-rename": ">=1.2.0", |
|||
"gulp-replace": "^0.5.3", |
|||
"gulp-streamify": "0.0.5", |
|||
"gulp-uglify": ">=1.2.0", |
|||
"istanbul": "^0.3.5", |
|||
"jshint": ">=2.5.0", |
|||
"mocha": ">=2.1.0", |
|||
"sandboxed-module": "^2.0.2", |
|||
"vinyl-source-stream": "^1.1.0" |
|||
}, |
|||
"scripts": { |
|||
"build": "gulp", |
|||
"watch": "gulp watch", |
|||
"lint": "jshint *.js lib", |
|||
"test": "mocha", |
|||
"test-coveralls": "istanbul cover _mocha -- -R spec && cat coverage/lcov.info | coveralls --verbose" |
|||
}, |
|||
"repository": { |
|||
"type": "git", |
|||
"url": "https://github.com/ethereum/web3.js.git" |
|||
}, |
|||
"homepage": "https://github.com/ethereum/web3.js", |
|||
"bugs": { |
|||
"url": "https://github.com/ethereum/web3.js/issues" |
|||
}, |
|||
"keywords": [ |
|||
"ethereum", |
|||
"javascript", |
|||
"API" |
|||
], |
|||
"author": "ethdev.com", |
|||
"authors": [ |
|||
{ |
|||
"name": "Marek Kotewicz", |
|||
"email": "marek@ethdev.com", |
|||
"url": "https://github.com/debris" |
|||
}, |
|||
{ |
|||
"name": "Fabian Vogelsteller", |
|||
"email": "fabian@ethdev.com", |
|||
"homepage": "http://frozeman.de" |
|||
}, |
|||
{ |
|||
"name": "Marian Oancea", |
|||
"email": "marian@ethdev.com", |
|||
"url": "https://github.com/cubedro" |
|||
}, |
|||
{ |
|||
"name": "Gav Wood", |
|||
"email": "g@ethdev.com", |
|||
"homepage": "http://gavwood.com" |
|||
}, |
|||
{ |
|||
"name": "Jeffery Wilcke", |
|||
"email": "jeff@ethdev.com", |
|||
"url": "https://github.com/obscuren" |
|||
} |
|||
], |
|||
"license": "LGPL-3.0" |
|||
} |
File diff suppressed because it is too large
@ -1,69 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var web3 = require('../index'); |
|||
var FakeHttpProvider = require('./helpers/FakeHttpProvider'); |
|||
|
|||
// use sendTransaction as dummy
|
|||
var method = 'sendTransaction'; |
|||
|
|||
var tests = [{ |
|||
result: '0xb', |
|||
formattedResult: '0xb', |
|||
call: 'eth_'+ method |
|||
}]; |
|||
|
|||
describe('async', function () { |
|||
tests.forEach(function (test, index) { |
|||
it('test: ' + index, function (done) { |
|||
|
|||
// given
|
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
provider.injectResult(test.result); |
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.jsonrpc, '2.0'); |
|||
assert.equal(payload.method, test.call); |
|||
assert.deepEqual(payload.params, [{}]); |
|||
}); |
|||
|
|||
// when
|
|||
web3.eth[method]({}, function(error, result){ |
|||
|
|||
// then
|
|||
assert.isNull(error); |
|||
assert.strictEqual(test.formattedResult, result); |
|||
|
|||
done(); |
|||
}); |
|||
|
|||
}); |
|||
|
|||
it('error test: ' + index, function (done) { |
|||
|
|||
// given
|
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
provider.injectError({ |
|||
message: test.result, |
|||
code: -32603 |
|||
}); |
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.jsonrpc, '2.0'); |
|||
assert.equal(payload.method, test.call); |
|||
assert.deepEqual(payload.params, [{}]); |
|||
}); |
|||
|
|||
// when
|
|||
web3.eth[method]({}, function(error, result){ |
|||
|
|||
// then
|
|||
assert.isUndefined(result); |
|||
assert.strictEqual(test.formattedResult, error.message); |
|||
|
|||
done(); |
|||
}); |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
@ -1,201 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var web3 = require('../index'); |
|||
var FakeHttpProvider = require('./helpers/FakeHttpProvider'); |
|||
var bn = require('bignumber.js'); |
|||
|
|||
describe('lib/web3/batch', function () { |
|||
describe('execute', function () { |
|||
it('should execute batch request', function (done) { |
|||
|
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
|
|||
var result = '0x126'; |
|||
var result2 = '0x127'; |
|||
provider.injectBatchResults([result, result2]); |
|||
|
|||
var counter = 0; |
|||
var callback = function (err, r) { |
|||
counter++; |
|||
assert.deepEqual(new bn(result), r); |
|||
}; |
|||
|
|||
var callback2 = function (err, r) { |
|||
assert.equal(counter, 1); |
|||
assert.deepEqual(new bn(result2), r); |
|||
done(); |
|||
}; |
|||
|
|||
provider.injectValidation(function (payload) { |
|||
var first = payload[0]; |
|||
var second = payload[1]; |
|||
|
|||
assert.equal(first.method, 'eth_getBalance'); |
|||
assert.deepEqual(first.params, ['0x0000000000000000000000000000000000000000', 'latest']); |
|||
assert.equal(second.method, 'eth_getBalance'); |
|||
assert.deepEqual(second.params, ['0x0000000000000000000000000000000000000005', 'latest']); |
|||
}); |
|||
|
|||
var batch = web3.createBatch(); |
|||
batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000000', 'latest', callback)); |
|||
batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000005', 'latest', callback2)); |
|||
batch.execute(); |
|||
}); |
|||
|
|||
it('should execute batch request for async properties', function (done) { |
|||
|
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
|
|||
var result = []; |
|||
var result2 = '0xb'; |
|||
provider.injectBatchResults([result, result2]); |
|||
|
|||
var counter = 0; |
|||
var callback = function (err, r) { |
|||
counter++; |
|||
assert.isArray(result, r); |
|||
}; |
|||
|
|||
var callback2 = function (err, r) { |
|||
assert.equal(counter, 1); |
|||
assert.equal(r, 11); |
|||
done(); |
|||
}; |
|||
|
|||
provider.injectValidation(function (payload) { |
|||
var first = payload[0]; |
|||
var second = payload[1]; |
|||
|
|||
assert.equal(first.method, 'eth_accounts'); |
|||
assert.deepEqual(first.params, []); |
|||
assert.equal(second.method, 'net_peerCount'); |
|||
assert.deepEqual(second.params, []); |
|||
}); |
|||
|
|||
var batch = web3.createBatch(); |
|||
batch.add(web3.eth.getAccounts.request(callback)); |
|||
batch.add(web3.net.getPeerCount.request(callback2)); |
|||
batch.execute(); |
|||
}); |
|||
|
|||
it('should execute batch request with contract', function (done) { |
|||
|
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
|
|||
var abi = [{ |
|||
"name": "balance(address)", |
|||
"type": "function", |
|||
"inputs": [{ |
|||
"name": "who", |
|||
"type": "address" |
|||
}], |
|||
"constant": true, |
|||
"outputs": [{ |
|||
"name": "value", |
|||
"type": "uint256" |
|||
}] |
|||
}]; |
|||
|
|||
|
|||
var address = '0x1000000000000000000000000000000000000001'; |
|||
var result = '0x126'; |
|||
var result2 = '0x0000000000000000000000000000000000000000000000000000000000000123'; |
|||
|
|||
var counter = 0; |
|||
var callback = function (err, r) { |
|||
counter++; |
|||
assert.deepEqual(new bn(result), r); |
|||
}; |
|||
|
|||
var callback2 = function (err, r) { |
|||
assert.equal(counter, 1); |
|||
assert.deepEqual(new bn(result2), r); |
|||
done(); |
|||
}; |
|||
|
|||
provider.injectValidation(function (payload) { |
|||
var first = payload[0]; |
|||
var second = payload[1]; |
|||
|
|||
assert.equal(first.method, 'eth_getBalance'); |
|||
assert.deepEqual(first.params, ['0x0000000000000000000000000000000000000000', 'latest']); |
|||
assert.equal(second.method, 'eth_call'); |
|||
assert.deepEqual(second.params, [{ |
|||
'to': '0x1000000000000000000000000000000000000001', |
|||
'data': '0xe3d670d70000000000000000000000001000000000000000000000000000000000000001' |
|||
}]); |
|||
}); |
|||
|
|||
var batch = web3.createBatch(); |
|||
batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000000', 'latest', callback)); |
|||
batch.add(web3.eth.contract(abi).at(address).balance.request(address, callback2)); |
|||
provider.injectBatchResults([result, result2]); |
|||
batch.execute(); |
|||
}); |
|||
|
|||
it('should execute batch requests and receive errors', function (done) { |
|||
|
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
|
|||
var abi = [{ |
|||
"name": "balance(address)", |
|||
"type": "function", |
|||
"inputs": [{ |
|||
"name": "who", |
|||
"type": "address" |
|||
}], |
|||
"constant": true, |
|||
"outputs": [{ |
|||
"name": "value", |
|||
"type": "uint256" |
|||
}] |
|||
}]; |
|||
|
|||
|
|||
var address = '0x1000000000000000000000000000000000000001'; |
|||
var result = 'Something went wrong'; |
|||
var result2 = 'Something went wrong 2'; |
|||
|
|||
|
|||
var counter = 0; |
|||
var callback = function (err, r) { |
|||
counter++; |
|||
assert.isNotNull(err); |
|||
}; |
|||
|
|||
var callback2 = function (err, r) { |
|||
assert.equal(counter, 1); |
|||
assert.isNotNull(err); |
|||
done(); |
|||
}; |
|||
|
|||
provider.injectValidation(function (payload) { |
|||
var first = payload[0]; |
|||
var second = payload[1]; |
|||
|
|||
assert.equal(first.method, 'eth_getBalance'); |
|||
assert.deepEqual(first.params, ['0x0000000000000000000000000000000000000000', 'latest']); |
|||
assert.equal(second.method, 'eth_call'); |
|||
assert.deepEqual(second.params, [{ |
|||
'to': '0x1000000000000000000000000000000000000001', |
|||
'data': '0xe3d670d70000000000000000000000001000000000000000000000000000000000000001' |
|||
}]); |
|||
}); |
|||
|
|||
var batch = web3.createBatch(); |
|||
batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000000', 'latest', callback)); |
|||
batch.add(web3.eth.contract(abi).at(address).balance.request(address, callback2)); |
|||
provider.injectBatchResults([result, result2], true); // injects error
|
|||
batch.execute(); |
|||
}); |
|||
}); |
|||
}); |
|||
|
@ -1,153 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var coder = require('../lib/solidity/coder'); |
|||
var BigNumber = require('bignumber.js'); |
|||
var bn = BigNumber; |
|||
|
|||
|
|||
describe('lib/solidity/coder', function () { |
|||
describe('decodeParam', function () { |
|||
var test = function (t) { |
|||
it('should turn ' + t.value + ' to ' + t.expected, function () { |
|||
assert.deepEqual(coder.decodeParam(t.type, t.value), t.expected); |
|||
}); |
|||
}; |
|||
|
|||
|
|||
test({ type: 'int', expected: new bn(1), value: '0000000000000000000000000000000000000000000000000000000000000001'}); |
|||
test({ type: 'int', expected: new bn(16), value: '0000000000000000000000000000000000000000000000000000000000000010'}); |
|||
test({ type: 'int', expected: new bn(-1), value: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); |
|||
test({ type: 'int256', expected: new bn(1), value: '0000000000000000000000000000000000000000000000000000000000000001'}); |
|||
test({ type: 'int256', expected: new bn(16), value: '0000000000000000000000000000000000000000000000000000000000000010'}); |
|||
test({ type: 'int256', expected: new bn(-1), value: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); |
|||
test({ type: 'int8', expected: new bn(16), value: '0000000000000000000000000000000000000000000000000000000000000010'}); |
|||
test({ type: 'int32', expected: new bn(16), value: '0000000000000000000000000000000000000000000000000000000000000010'}); |
|||
test({ type: 'int64', expected: new bn(16), value: '0000000000000000000000000000000000000000000000000000000000000010'}); |
|||
test({ type: 'int128', expected: new bn(16), value: '0000000000000000000000000000000000000000000000000000000000000010'}); |
|||
test({ type: 'bytes32', expected: '0x6761766f66796f726b0000000000000000000000000000000000000000000000', |
|||
value: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'bytes', expected: '0x6761766f66796f726b', |
|||
value: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000009' + |
|||
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'bytes32', expected: '0x731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', |
|||
value: '731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); |
|||
test({ type: 'bytes', expected: '0x731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', |
|||
value: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); |
|||
test({ type: 'bytes', expected: '0x731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', |
|||
value: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000040' + |
|||
'731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); |
|||
test({ type: 'bytes', expected: '0x131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', |
|||
value: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000060' + |
|||
'131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); |
|||
test({ type: 'string', expected: 'gavofyork', value: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000009' + |
|||
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'string', expected: '\xc3\xa4\x00\x00\xc3\xa4', |
|||
value: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000006' + |
|||
'c3a40000c3a40000000000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'string', expected: '\xc3', |
|||
value: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'c300000000000000000000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'bytes', expected: '0xc3a40000c3a4', |
|||
value: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000006' + |
|||
'c3a40000c3a40000000000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'bytes32', expected: '0xc3a40000c3a40000000000000000000000000000000000000000000000000000', |
|||
value: 'c3a40000c3a40000000000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'int[]', expected: [], value: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'int[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003'}); |
|||
test({ type: 'int256[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003'}); |
|||
test({ type: 'int[]', expected: [new bn(1), new bn(2), new bn(3)], |
|||
value: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000002' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003'}); |
|||
test({ type: 'bool', expected: true, value: '0000000000000000000000000000000000000000000000000000000000000001'}); |
|||
test({ type: 'bool', expected: false, value: '0000000000000000000000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'real', expected: new bn(1), value: '0000000000000000000000000000000100000000000000000000000000000000'}); |
|||
test({ type: 'real', expected: new bn(2.125), value: '0000000000000000000000000000000220000000000000000000000000000000'}); |
|||
test({ type: 'real', expected: new bn(8.5), value: '0000000000000000000000000000000880000000000000000000000000000000'}); |
|||
test({ type: 'real', expected: new bn(-1), value: 'ffffffffffffffffffffffffffffffff00000000000000000000000000000000'}); |
|||
test({ type: 'ureal', expected: new bn(1), value: '0000000000000000000000000000000100000000000000000000000000000000'}); |
|||
test({ type: 'ureal', expected: new bn(2.125), value: '0000000000000000000000000000000220000000000000000000000000000000'}); |
|||
test({ type: 'ureal', expected: new bn(8.5), value: '0000000000000000000000000000000880000000000000000000000000000000'}); |
|||
test({ type: 'address', expected: '0x407d73d8a49eeb85d32cf465507dd71d507100c1', |
|||
value: '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1'}); |
|||
test({ type: 'string', expected: 'welcome to ethereum. welcome to ethereum. welcome to ethereum.', |
|||
value: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'000000000000000000000000000000000000000000000000000000000000003e' + |
|||
'77656c636f6d6520746f20657468657265756d2e2077656c636f6d6520746f20' + |
|||
'657468657265756d2e2077656c636f6d6520746f20657468657265756d2e0000'}); |
|||
}); |
|||
}); |
|||
|
|||
describe('lib/solidity/coder', function () { |
|||
describe('decodeParams', function () { |
|||
var test = function (t) { |
|||
it('should turn ' + t.values + ' to ' + t.expected, function () { |
|||
assert.deepEqual(coder.decodeParams(t.types, t.values), t.expected); |
|||
}); |
|||
}; |
|||
|
|||
|
|||
test({ types: ['int'], expected: [new bn(1)], values: '0000000000000000000000000000000000000000000000000000000000000001'}); |
|||
test({ types: ['bytes32', 'int'], expected: ['0x6761766f66796f726b0000000000000000000000000000000000000000000000', new bn(5)], |
|||
values: '6761766f66796f726b0000000000000000000000000000000000000000000000' + |
|||
'0000000000000000000000000000000000000000000000000000000000000005'}); |
|||
test({ types: ['int', 'bytes32'], expected: [new bn(5), '0x6761766f66796f726b0000000000000000000000000000000000000000000000'], |
|||
values: '0000000000000000000000000000000000000000000000000000000000000005' + |
|||
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); |
|||
test({ types: ['int', 'string', 'int', 'int', 'int', 'int[]'], expected: [new bn(1), 'gavofyork', new bn(2), new bn(3), new bn(4), |
|||
[new bn(5), new bn(6), new bn(7)]], |
|||
values: '0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'00000000000000000000000000000000000000000000000000000000000000c0' + |
|||
'0000000000000000000000000000000000000000000000000000000000000002' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003' + |
|||
'0000000000000000000000000000000000000000000000000000000000000004' + |
|||
'0000000000000000000000000000000000000000000000000000000000000100' + |
|||
'0000000000000000000000000000000000000000000000000000000000000009' + |
|||
'6761766f66796f726b0000000000000000000000000000000000000000000000' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003' + |
|||
'0000000000000000000000000000000000000000000000000000000000000005' + |
|||
'0000000000000000000000000000000000000000000000000000000000000006' + |
|||
'0000000000000000000000000000000000000000000000000000000000000007'}); |
|||
test({ types: ['int', 'bytes', 'int', 'bytes'], expected: [ |
|||
new bn(5), |
|||
'0x131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', |
|||
new bn(3), |
|||
'0x331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'431a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', |
|||
], |
|||
values: '0000000000000000000000000000000000000000000000000000000000000005' + |
|||
'0000000000000000000000000000000000000000000000000000000000000080' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003' + |
|||
'00000000000000000000000000000000000000000000000000000000000000e0' + |
|||
'0000000000000000000000000000000000000000000000000000000000000040' + |
|||
'131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'0000000000000000000000000000000000000000000000000000000000000040' + |
|||
'331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'431a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); |
|||
}); |
|||
}); |
|||
|
@ -1,210 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var coder = require('../lib/solidity/coder'); |
|||
|
|||
|
|||
describe('lib/solidity/coder', function () { |
|||
describe('encodeParam', function () { |
|||
var test = function (t) { |
|||
it('should turn ' + t.value + ' to ' + t.expected, function () { |
|||
assert.equal(coder.encodeParam(t.type, t.value), t.expected); |
|||
}); |
|||
}; |
|||
|
|||
|
|||
test({ type: 'int', value: 1, expected: '0000000000000000000000000000000000000000000000000000000000000001'}); |
|||
test({ type: 'int', value: 16, expected: '0000000000000000000000000000000000000000000000000000000000000010'}); |
|||
test({ type: 'int', value: -1, expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); |
|||
test({ type: 'int', value: 0.1, expected: '0000000000000000000000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'int', value: 3.9, expected: '0000000000000000000000000000000000000000000000000000000000000003'}); |
|||
test({ type: 'int256', value: 1, expected: '0000000000000000000000000000000000000000000000000000000000000001'}); |
|||
test({ type: 'int256', value: 16, expected: '0000000000000000000000000000000000000000000000000000000000000010'}); |
|||
test({ type: 'int256', value: -1, expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); |
|||
test({ type: 'bytes32', value: '0x6761766f66796f726b', |
|||
expected: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'bytes32', value: '0x731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', |
|||
expected: '731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); |
|||
test({ type: 'bytes32', value: '0x02838654a83c213dae3698391eabbd54a5b6e1fb3452bc7fa4ea0dd5c8ce7e29', |
|||
expected: '02838654a83c213dae3698391eabbd54a5b6e1fb3452bc7fa4ea0dd5c8ce7e29'}); |
|||
test({ type: 'bytes', value: '0x6761766f66796f726b', |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000009' + |
|||
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'bytes', value: '0x731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); |
|||
test({ type: 'string', value: 'gavofyork', expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000009' + |
|||
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'bytes', value: '0xc3a40000c3a4', |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000006' + |
|||
'c3a40000c3a40000000000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'bytes32', value: '0xc3a40000c3a4', |
|||
expected: 'c3a40000c3a40000000000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'string', value: '\xc3\xa4\x00\x00\xc3\xa4', |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000006' + |
|||
'c3a40000c3a40000000000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'string', value: '\xc3', |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'c300000000000000000000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'int[]', value: [], expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'int[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003'}); |
|||
test({ type: 'int256[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003'}); |
|||
test({ type: 'int[]', value: [1,2,3], expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000002' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003'}); |
|||
test({ type: 'bool', value: true, expected: '0000000000000000000000000000000000000000000000000000000000000001'}); |
|||
test({ type: 'bool', value: false, expected: '0000000000000000000000000000000000000000000000000000000000000000'}); |
|||
test({ type: 'address', value: '0x407d73d8a49eeb85d32cf465507dd71d507100c1', |
|||
expected: '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1'}); |
|||
test({ type: 'real', value: 1, expected: '0000000000000000000000000000000100000000000000000000000000000000'}); |
|||
test({ type: 'real', value: 2.125, expected: '0000000000000000000000000000000220000000000000000000000000000000'}); |
|||
test({ type: 'real', value: 8.5, expected: '0000000000000000000000000000000880000000000000000000000000000000'}); |
|||
test({ type: 'real', value: -1, expected: 'ffffffffffffffffffffffffffffffff00000000000000000000000000000000'}); |
|||
test({ type: 'ureal', value: 1, expected: '0000000000000000000000000000000100000000000000000000000000000000'}); |
|||
test({ type: 'ureal', value: 2.125, expected: '0000000000000000000000000000000220000000000000000000000000000000'}); |
|||
test({ type: 'ureal', value: 8.5, expected: '0000000000000000000000000000000880000000000000000000000000000000'}); |
|||
test({ type: 'bytes', value: '0x131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000040' + |
|||
'131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); |
|||
test({ type: 'bytes', value: '0x131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000060' + |
|||
'131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); |
|||
test({ type: 'string', value: 'welcome to ethereum. welcome to ethereum. welcome to ethereum.', |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'000000000000000000000000000000000000000000000000000000000000003e' + |
|||
'77656c636f6d6520746f20657468657265756d2e2077656c636f6d6520746f20' + |
|||
'657468657265756d2e2077656c636f6d6520746f20657468657265756d2e0000'}); |
|||
}); |
|||
}); |
|||
|
|||
|
|||
describe('lib/solidity/coder', function () { |
|||
describe('encodeParams', function () { |
|||
var test = function (t) { |
|||
it('should turn ' + t.values + ' to ' + t.expected, function () { |
|||
assert.equal(coder.encodeParams(t.types, t.values), t.expected); |
|||
}); |
|||
}; |
|||
|
|||
|
|||
test({ types: ['int'], values: [1], expected: '0000000000000000000000000000000000000000000000000000000000000001'}); |
|||
test({ types: ['int'], values: [16], expected: '0000000000000000000000000000000000000000000000000000000000000010'}); |
|||
test({ types: ['int'], values: [-1], expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); |
|||
test({ types: ['int256'], values: [1], expected: '0000000000000000000000000000000000000000000000000000000000000001'}); |
|||
test({ types: ['int256'], values: [16], expected: '0000000000000000000000000000000000000000000000000000000000000010'}); |
|||
test({ types: ['int256'], values: [-1], expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); |
|||
test({ types: ['bytes32'], values: ['0x6761766f66796f726b'], |
|||
expected: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); |
|||
test({ types: ['string'], values: ['gavofyork'], expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000009' + |
|||
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); |
|||
test({ types: ['int[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003'}); |
|||
test({ types: ['int256[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003'}); |
|||
test({ types: ['int256[]'], values: [[1,2,3]], expected: '0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000002' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003'}); |
|||
test({ types: ['int[]', 'int[]'], values: [[1,2], [3,4]], |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000040' + |
|||
'00000000000000000000000000000000000000000000000000000000000000a0' + |
|||
'0000000000000000000000000000000000000000000000000000000000000002' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000002' + |
|||
'0000000000000000000000000000000000000000000000000000000000000002' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003' + |
|||
'0000000000000000000000000000000000000000000000000000000000000004'}); |
|||
test({ types: ['bytes32', 'int'], values: ['0x6761766f66796f726b', 5], |
|||
expected: '6761766f66796f726b0000000000000000000000000000000000000000000000' + |
|||
'0000000000000000000000000000000000000000000000000000000000000005'}); |
|||
test({ types: ['int', 'bytes32'], values: [5, '0x6761766f66796f726b'], |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000005' + |
|||
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); |
|||
test({ types: ['string', 'int'], values: ['gavofyork', 5], |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000040' + |
|||
'0000000000000000000000000000000000000000000000000000000000000005' + |
|||
'0000000000000000000000000000000000000000000000000000000000000009' + |
|||
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); |
|||
test({ types: ['string', 'bool', 'int[]'], values: ['gavofyork', true, [1, 2, 3]], |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000060' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'00000000000000000000000000000000000000000000000000000000000000a0' + |
|||
'0000000000000000000000000000000000000000000000000000000000000009' + |
|||
'6761766f66796f726b0000000000000000000000000000000000000000000000' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000002' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003'}); |
|||
test({ types: ['string', 'int[]'], values: ['gavofyork', [1, 2, 3]], |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000040' + |
|||
'0000000000000000000000000000000000000000000000000000000000000080' + |
|||
'0000000000000000000000000000000000000000000000000000000000000009' + |
|||
'6761766f66796f726b0000000000000000000000000000000000000000000000' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000002' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003'}); |
|||
test({ types: ['int', 'string'], values: [5, 'gavofyork'], |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000005' + |
|||
'0000000000000000000000000000000000000000000000000000000000000040' + |
|||
'0000000000000000000000000000000000000000000000000000000000000009' + |
|||
'6761766f66796f726b0000000000000000000000000000000000000000000000'}); |
|||
test({ types: ['int', 'string', 'int', 'int', 'int', 'int[]'], values: [1, 'gavofyork', 2, 3, 4, [5, 6, 7]], |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'00000000000000000000000000000000000000000000000000000000000000c0' + |
|||
'0000000000000000000000000000000000000000000000000000000000000002' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003' + |
|||
'0000000000000000000000000000000000000000000000000000000000000004' + |
|||
'0000000000000000000000000000000000000000000000000000000000000100' + |
|||
'0000000000000000000000000000000000000000000000000000000000000009' + |
|||
'6761766f66796f726b0000000000000000000000000000000000000000000000' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003' + |
|||
'0000000000000000000000000000000000000000000000000000000000000005' + |
|||
'0000000000000000000000000000000000000000000000000000000000000006' + |
|||
'0000000000000000000000000000000000000000000000000000000000000007'}); |
|||
test({ types: ['int', 'bytes', 'int', 'bytes'], values: [ |
|||
5, |
|||
'0x131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', |
|||
3, |
|||
'0x331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'431a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', |
|||
], |
|||
expected: '0000000000000000000000000000000000000000000000000000000000000005' + |
|||
'0000000000000000000000000000000000000000000000000000000000000080' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003' + |
|||
'00000000000000000000000000000000000000000000000000000000000000e0' + |
|||
'0000000000000000000000000000000000000000000000000000000000000040' + |
|||
'131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'0000000000000000000000000000000000000000000000000000000000000040' + |
|||
'331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + |
|||
'431a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); |
|||
}); |
|||
}); |
|||
|
|||
|
@ -1,569 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var web3 = require('../index'); |
|||
var FakeHttpProvider = require('./helpers/FakeHttpProvider'); |
|||
var FakeHttpProvider2 = require('./helpers/FakeHttpProvider2'); |
|||
var utils = require('../lib/utils/utils'); |
|||
var BigNumber = require('bignumber.js'); |
|||
var sha3 = require('../lib/utils/sha3'); |
|||
|
|||
var desc = [{ |
|||
"name": "balance(address)", |
|||
"type": "function", |
|||
"inputs": [{ |
|||
"name": "who", |
|||
"type": "address" |
|||
}], |
|||
"constant": true, |
|||
"outputs": [{ |
|||
"name": "value", |
|||
"type": "uint256" |
|||
}] |
|||
}, { |
|||
"name": "send(address,uint256)", |
|||
"type": "function", |
|||
"inputs": [{ |
|||
"name": "to", |
|||
"type": "address" |
|||
}, { |
|||
"name": "value", |
|||
"type": "uint256" |
|||
}], |
|||
"outputs": [] |
|||
}, { |
|||
"name": "testArr(int[])", |
|||
"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} |
|||
], |
|||
}]; |
|||
|
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
|
|||
describe('web3.eth.contract', function () { |
|||
describe('event', function () { |
|||
it('should create event filter', function (done) { |
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); // reset different polls
|
|||
var signature = 'Changed(address,uint256,uint256,uint256)'; |
|||
var step = 0; |
|||
provider.injectValidation(function (payload) { |
|||
if (step === 0) { |
|||
step = 1; |
|||
provider.injectResult('0x3'); |
|||
assert.equal(payload.jsonrpc, '2.0'); |
|||
assert.equal(payload.method, 'eth_newFilter'); |
|||
assert.deepEqual(payload.params[0], { |
|||
topics: [ |
|||
'0x' + sha3(signature), |
|||
'0x0000000000000000000000001234567890123456789012345678901234567890', |
|||
null |
|||
], |
|||
address: '0x1234567890123456789012345678901234567890' |
|||
}); |
|||
} else if (step === 1) { |
|||
step = 2; |
|||
provider.injectResult([{ |
|||
address: address, |
|||
topics: [ |
|||
'0x' + sha3(signature), |
|||
'0x0000000000000000000000001234567890123456789012345678901234567890', |
|||
'0x0000000000000000000000000000000000000000000000000000000000000001' |
|||
], |
|||
number: 2, |
|||
data: '0x0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000008' |
|||
}]); |
|||
assert.equal(payload.jsonrpc, '2.0'); |
|||
assert.equal(payload.method, 'eth_getFilterLogs'); |
|||
} else if (step === 2 && utils.isArray(payload)) { |
|||
provider.injectBatchResults([[{ |
|||
address: address, |
|||
topics: [ |
|||
'0x' + sha3(signature), |
|||
'0x0000000000000000000000001234567890123456789012345678901234567890', |
|||
'0x0000000000000000000000000000000000000000000000000000000000000001' |
|||
], |
|||
number: 2, |
|||
data: '0x0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000008' |
|||
}]]); |
|||
var r = payload.filter(function (p) { |
|||
return p.jsonrpc === '2.0' && p.method === 'eth_getFilterChanges' && p.params[0] === '0x3'; |
|||
}); |
|||
assert.equal(r.length > 0, true); |
|||
} |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
|
|||
var res = 0; |
|||
var event = contract.Changed({from: address}); |
|||
event.watch(function(err, result) { |
|||
assert.equal(result.args.from, address); |
|||
assert.equal(result.args.amount, 1); |
|||
assert.equal(result.args.t1, 1); |
|||
assert.equal(result.args.t2, 8); |
|||
res++; |
|||
if (res === 2) { |
|||
done(); |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
it('should create event filter and watch immediately', function (done) { |
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); // reset different polls
|
|||
var signature = 'Changed(address,uint256,uint256,uint256)'; |
|||
var step = 0; |
|||
provider.injectValidation(function (payload) { |
|||
if (step === 0) { |
|||
step = 1; |
|||
provider.injectResult('0x3'); |
|||
assert.equal(payload.jsonrpc, '2.0'); |
|||
assert.equal(payload.method, 'eth_newFilter'); |
|||
assert.deepEqual(payload.params[0], { |
|||
topics: [ |
|||
'0x' + sha3(signature), |
|||
'0x0000000000000000000000001234567890123456789012345678901234567890', |
|||
null |
|||
], |
|||
address: '0x1234567890123456789012345678901234567890' |
|||
}); |
|||
} else if (step === 1) { |
|||
step = 2; |
|||
provider.injectResult([{ |
|||
address: address, |
|||
topics: [ |
|||
'0x' + sha3(signature), |
|||
'0x0000000000000000000000001234567890123456789012345678901234567890', |
|||
'0x0000000000000000000000000000000000000000000000000000000000000001' |
|||
], |
|||
number: 2, |
|||
data: '0x0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000008' |
|||
}]); |
|||
assert.equal(payload.jsonrpc, '2.0'); |
|||
assert.equal(payload.method, 'eth_getFilterLogs'); |
|||
} else if (step === 2 && utils.isArray(payload)) { |
|||
provider.injectBatchResults([[{ |
|||
address: address, |
|||
topics: [ |
|||
'0x' + sha3(signature), |
|||
'0x0000000000000000000000001234567890123456789012345678901234567890', |
|||
'0x0000000000000000000000000000000000000000000000000000000000000001' |
|||
], |
|||
number: 2, |
|||
data: '0x0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000008' |
|||
}]]); |
|||
var r = payload.filter(function (p) { |
|||
return p.jsonrpc === '2.0' && p.method === 'eth_getFilterChanges' && p.params[0] === '0x3'; |
|||
}); |
|||
assert.equal(r.length > 0, true); |
|||
} |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
|
|||
var res = 0; |
|||
var event = contract.Changed({from: address}, function(err, result) { |
|||
assert.equal(result.args.from, address); |
|||
assert.equal(result.args.amount, 1); |
|||
assert.equal(result.args.t1, 1); |
|||
assert.equal(result.args.t2, 8); |
|||
res++; |
|||
if (res === 2) { |
|||
done(); |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
it('should create all event filter', function (done) { |
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); // reset different polls
|
|||
var signature = 'Changed(address,uint256,uint256,uint256)'; |
|||
var step = 0; |
|||
provider.injectValidation(function (payload) { |
|||
if (step === 0) { |
|||
step = 1; |
|||
provider.injectResult('0x3'); |
|||
assert.equal(payload.jsonrpc, '2.0'); |
|||
assert.equal(payload.method, 'eth_newFilter'); |
|||
assert.deepEqual(payload.params[0], { |
|||
topics: [], |
|||
address: '0x1234567890123456789012345678901234567890' |
|||
}); |
|||
} else if (step === 1) { |
|||
step = 2; |
|||
provider.injectResult([{ |
|||
address: address, |
|||
topics: [ |
|||
'0x' + sha3(signature), |
|||
'0x0000000000000000000000001234567890123456789012345678901234567890', |
|||
'0x0000000000000000000000000000000000000000000000000000000000000001' |
|||
], |
|||
number: 2, |
|||
data: '0x0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000008' |
|||
}]); |
|||
assert.equal(payload.jsonrpc, '2.0'); |
|||
assert.equal(payload.method, 'eth_getFilterLogs'); |
|||
} else if (step === 2 && utils.isArray(payload)) { |
|||
provider.injectBatchResults([[{ |
|||
address: address, |
|||
topics: [ |
|||
'0x' + sha3(signature), |
|||
'0x0000000000000000000000001234567890123456789012345678901234567890', |
|||
'0x0000000000000000000000000000000000000000000000000000000000000001' |
|||
], |
|||
number: 2, |
|||
data: '0x0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000008' |
|||
}]]); |
|||
var r = payload.filter(function (p) { |
|||
return p.jsonrpc === '2.0' && p.method === 'eth_getFilterChanges' && p.params[0] === '0x3'; |
|||
}); |
|||
assert.equal(r.length > 0, true); |
|||
} |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
|
|||
var res = 0; |
|||
var event = contract.allEvents(); |
|||
event.watch(function(err, result) { |
|||
assert.equal(result.args.from, address); |
|||
assert.equal(result.args.amount, 1); |
|||
assert.equal(result.args.t1, 1); |
|||
assert.equal(result.args.t2, 8); |
|||
res++; |
|||
if (res === 2) { |
|||
done(); |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
it('should call constant function', function () { |
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
provider.injectResult('0x0000000000000000000000000000000000000000000000000000000000000032'); |
|||
var signature = 'balance(address)' |
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
|
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.method, 'eth_call'); |
|||
assert.deepEqual(payload.params, [{ |
|||
data: '0x' + sha3(signature).slice(0, 8) + '0000000000000000000000001234567890123456789012345678901234567890', |
|||
to: address |
|||
}, 'latest']); |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
|
|||
var r = contract.balance(address); |
|||
assert.deepEqual(new BigNumber(0x32), r); |
|||
}); |
|||
|
|||
it('should call constant function with default block', function () { |
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
provider.injectResult('0x0000000000000000000000000000000000000000000000000000000000000032'); |
|||
var signature = 'balance(address)' |
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
|
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.method, 'eth_call'); |
|||
assert.deepEqual(payload.params, [{ |
|||
data: '0x' + sha3(signature).slice(0, 8) + '0000000000000000000000001234567890123456789012345678901234567890', |
|||
to: address |
|||
}, '0xb']); |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
|
|||
var r = contract.balance(address, 11); |
|||
assert.deepEqual(new BigNumber(0x32), r); |
|||
}); |
|||
|
|||
it('should sendTransaction to contract function', function () { |
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
var signature = 'send(address,uint256)'; |
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.method, 'eth_sendTransaction'); |
|||
assert.deepEqual(payload.params, [{ |
|||
data: '0x' + sha3(signature).slice(0, 8) + |
|||
'0000000000000000000000001234567890123456789012345678901234567890' + |
|||
'0000000000000000000000000000000000000000000000000000000000000011' , |
|||
to: address |
|||
}]); |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
|
|||
contract.send(address, 17); |
|||
}); |
|||
|
|||
it('should make a call with optional params', function () { |
|||
|
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
provider.injectResult('0x0000000000000000000000000000000000000000000000000000000000000032'); |
|||
var signature = 'balance(address)'; |
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.method, 'eth_call'); |
|||
assert.deepEqual(payload.params, [{ |
|||
data: '0x' + sha3(signature).slice(0, 8) + '0000000000000000000000001234567890123456789012345678901234567890', |
|||
to: address, |
|||
from: address, |
|||
gas: '0xc350' |
|||
}, 'latest']); |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
|
|||
var r = contract.balance(address, {from: address, gas: 50000}); |
|||
assert.deepEqual(new BigNumber(0x32), r); |
|||
|
|||
}); |
|||
|
|||
it('should explicitly make a call with optional params', function () { |
|||
|
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
provider.injectResult('0x0000000000000000000000000000000000000000000000000000000000000032'); |
|||
var signature = 'balance(address)'; |
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.method, 'eth_call'); |
|||
assert.deepEqual(payload.params, [{ |
|||
data: '0x' + sha3(signature).slice(0, 8) + '0000000000000000000000001234567890123456789012345678901234567890', |
|||
to: address, |
|||
from: address, |
|||
gas: '0xc350' |
|||
}, 'latest']); |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
|
|||
var r = contract.balance.call(address, {from: address, gas: 50000}); |
|||
assert.deepEqual(new BigNumber(0x32), r); |
|||
|
|||
}); |
|||
|
|||
it('should explicitly make a call with optional params and defaultBlock', function () { |
|||
|
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
provider.injectResult('0x0000000000000000000000000000000000000000000000000000000000000032'); |
|||
var signature = 'balance(address)'; |
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.method, 'eth_call'); |
|||
assert.deepEqual(payload.params, [{ |
|||
data: '0x' + sha3(signature).slice(0, 8) + '0000000000000000000000001234567890123456789012345678901234567890', |
|||
to: address, |
|||
from: address, |
|||
gas: '0xc350' |
|||
}, '0xb']); |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
|
|||
var r = contract.balance.call(address, {from: address, gas: 50000}, 11); |
|||
assert.deepEqual(new BigNumber(0x32), r); |
|||
|
|||
}); |
|||
|
|||
it('should sendTransaction with optional params', function () { |
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
var signature = 'send(address,uint256)'; |
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.method, 'eth_sendTransaction'); |
|||
assert.deepEqual(payload.params, [{ |
|||
data: '0x' + sha3(signature).slice(0, 8) + |
|||
'0000000000000000000000001234567890123456789012345678901234567890' + |
|||
'0000000000000000000000000000000000000000000000000000000000000011' , |
|||
to: address, |
|||
from: address, |
|||
gas: '0xc350', |
|||
gasPrice: '0xbb8', |
|||
value: '0x2710' |
|||
}]); |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
|
|||
contract.send(address, 17, {from: address, gas: 50000, gasPrice: 3000, value: 10000}); |
|||
}); |
|||
|
|||
it('should explicitly sendTransaction with optional params', function () { |
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
var signature = 'send(address,uint256)'; |
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.method, 'eth_sendTransaction'); |
|||
assert.deepEqual(payload.params, [{ |
|||
data: '0x' + sha3(signature).slice(0, 8) + |
|||
'0000000000000000000000001234567890123456789012345678901234567890' + |
|||
'0000000000000000000000000000000000000000000000000000000000000011' , |
|||
to: address, |
|||
from: address, |
|||
gas: '0xc350', |
|||
gasPrice: '0xbb8', |
|||
value: '0x2710' |
|||
}]); |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
|
|||
contract.send.sendTransaction(address, 17, {from: address, gas: 50000, gasPrice: 3000, value: 10000}); |
|||
}); |
|||
|
|||
it('should explicitly sendTransaction with optional params and call callback without error', function (done) { |
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
var signature = 'send(address,uint256)'; |
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.method, 'eth_sendTransaction'); |
|||
assert.deepEqual(payload.params, [{ |
|||
data: '0x' + sha3(signature).slice(0, 8) + |
|||
'0000000000000000000000001234567890123456789012345678901234567890' + |
|||
'0000000000000000000000000000000000000000000000000000000000000011' , |
|||
to: address, |
|||
from: address, |
|||
gas: '0xc350', |
|||
gasPrice: '0xbb8', |
|||
value: '0x2710' |
|||
}]); |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
|
|||
contract.send.sendTransaction(address, 17, {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(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
var signature = 'send(address,uint256)'; |
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.method, 'eth_estimateGas'); |
|||
assert.deepEqual(payload.params, [{ |
|||
data: '0x' + sha3(signature).slice(0, 8) + |
|||
'0000000000000000000000001234567890123456789012345678901234567890' + |
|||
'0000000000000000000000000000000000000000000000000000000000000011' , |
|||
to: address, |
|||
from: address, |
|||
gas: '0xc350', |
|||
gasPrice: '0xbb8', |
|||
value: '0x2710' |
|||
}]); |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
|
|||
contract.send.estimateGas(address, 17, {from: address, gas: 50000, gasPrice: 3000, value: 10000}); |
|||
}); |
|||
|
|||
it('should call testArr method and properly parse result', function () { |
|||
var provider = new FakeHttpProvider2(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
var signature = 'testArr(int[])'; |
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
provider.injectResultList([{ |
|||
result: '0x0000000000000000000000000000000000000000000000000000000000000005' |
|||
}]); |
|||
|
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.method, 'eth_call'); |
|||
assert.deepEqual(payload.params, [{ |
|||
data: '0x' + sha3(signature).slice(0, 8) + |
|||
'0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003', |
|||
to: address |
|||
}, |
|||
'latest' |
|||
]); |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
var result = contract.testArr([3]); |
|||
|
|||
assert.deepEqual(new BigNumber(5), result); |
|||
}); |
|||
|
|||
it('should call testArr method, properly parse result and return the result async', function (done) { |
|||
var provider = new FakeHttpProvider2(); |
|||
web3.setProvider(provider); |
|||
web3.reset(); |
|||
var signature = 'testArr(int[])'; |
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
provider.injectResultList([{ |
|||
result: '0x0000000000000000000000000000000000000000000000000000000000000005' |
|||
}]); |
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.method, 'eth_call'); |
|||
assert.deepEqual(payload.params, [{ |
|||
data: '0x' + sha3(signature).slice(0, 8) + |
|||
'0000000000000000000000000000000000000000000000000000000000000020' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000003', |
|||
to: address |
|||
}, |
|||
'latest' |
|||
]); |
|||
}); |
|||
|
|||
var contract = web3.eth.contract(desc).at(address); |
|||
|
|||
contract.testArr([3], function (err, result) { |
|||
assert.deepEqual(new BigNumber(5), result); |
|||
done(); |
|||
}); |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
@ -1,17 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var errors = require('../lib/web3/errors'); |
|||
|
|||
describe('lib/web3/method', function () { |
|||
describe('getCall', function () { |
|||
|
|||
for(var key in errors) { |
|||
it('should return and error', function () { |
|||
|
|||
assert.instanceOf(errors[key](), Error); |
|||
}); |
|||
} |
|||
|
|||
}); |
|||
}); |
|||
|
@ -1,180 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var BigNumber = require('bignumber.js'); |
|||
var SolidityEvent = require('../lib/web3/event'); |
|||
|
|||
var name = 'event1'; |
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
|
|||
var tests = [{ |
|||
abi: { |
|||
name: name, |
|||
inputs: [] |
|||
}, |
|||
data: { |
|||
logIndex: '0x1', |
|||
transactionIndex: '0x10', |
|||
transactionHash: '0x1234567890', |
|||
address: address, |
|||
blockHash: '0x1234567890', |
|||
blockNumber: '0x1' |
|||
}, |
|||
expected: { |
|||
event: name, |
|||
args: {}, |
|||
logIndex: 1, |
|||
transactionIndex: 16, |
|||
transactionHash: '0x1234567890', |
|||
address: address, |
|||
blockHash: '0x1234567890', |
|||
blockNumber: 1 |
|||
} |
|||
}, { |
|||
abi: { |
|||
name: name, |
|||
inputs: [{ |
|||
name: 'a', |
|||
type: 'int', |
|||
indexed: false |
|||
}] |
|||
}, |
|||
data: { |
|||
logIndex: '0x1', |
|||
transactionIndex: '0x10', |
|||
transactionHash: '0x1234567890', |
|||
address: address, |
|||
blockHash: '0x1234567890', |
|||
blockNumber: '0x1', |
|||
data: '0x0000000000000000000000000000000000000000000000000000000000000001' |
|||
}, |
|||
expected: { |
|||
event: name, |
|||
args: { |
|||
a: new BigNumber(1) |
|||
}, |
|||
logIndex: 1, |
|||
transactionIndex: 16, |
|||
transactionHash: '0x1234567890', |
|||
address: address, |
|||
blockHash: '0x1234567890', |
|||
blockNumber: 1 |
|||
} |
|||
}, { |
|||
abi: { |
|||
name: name, |
|||
inputs: [{ |
|||
name: 'a', |
|||
type: 'int', |
|||
indexed: false |
|||
}, { |
|||
name: 'b', |
|||
type: 'int', |
|||
indexed: true |
|||
}, { |
|||
name: 'c', |
|||
type: 'int', |
|||
indexed: false |
|||
}, { |
|||
name: 'd', |
|||
type: 'int', |
|||
indexed: true |
|||
}] |
|||
}, |
|||
data: { |
|||
logIndex: '0x1', |
|||
transactionIndex: '0x10', |
|||
transactionHash: '0x1234567890', |
|||
address: address, |
|||
blockHash: '0x1234567890', |
|||
blockNumber: '0x1', |
|||
data: '0x' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000004', |
|||
topics: [ |
|||
address, |
|||
'0x000000000000000000000000000000000000000000000000000000000000000a', |
|||
'0x0000000000000000000000000000000000000000000000000000000000000010' |
|||
] |
|||
}, |
|||
expected: { |
|||
event: name, |
|||
args: { |
|||
a: new BigNumber(1), |
|||
b: new BigNumber(10), |
|||
c: new BigNumber(4), |
|||
d: new BigNumber(16) |
|||
}, |
|||
logIndex: 1, |
|||
transactionIndex: 16, |
|||
transactionHash: '0x1234567890', |
|||
address: address, |
|||
blockHash: '0x1234567890', |
|||
blockNumber: 1 |
|||
} |
|||
}, { |
|||
abi: { |
|||
name: name, |
|||
anonymous: true, |
|||
inputs: [{ |
|||
name: 'a', |
|||
type: 'int', |
|||
indexed: false |
|||
}, { |
|||
name: 'b', |
|||
type: 'int', |
|||
indexed: true |
|||
}, { |
|||
name: 'c', |
|||
type: 'int', |
|||
indexed: false |
|||
}, { |
|||
name: 'd', |
|||
type: 'int', |
|||
indexed: true |
|||
}] |
|||
}, |
|||
data: { |
|||
logIndex: '0x1', |
|||
transactionIndex: '0x10', |
|||
transactionHash: '0x1234567890', |
|||
address: address, |
|||
blockHash: '0x1234567890', |
|||
blockNumber: '0x1', |
|||
data: '0x' + |
|||
'0000000000000000000000000000000000000000000000000000000000000001' + |
|||
'0000000000000000000000000000000000000000000000000000000000000004', |
|||
topics: [ |
|||
'0x000000000000000000000000000000000000000000000000000000000000000a', |
|||
'0x0000000000000000000000000000000000000000000000000000000000000010' |
|||
] |
|||
}, |
|||
expected: { |
|||
event: name, |
|||
args: { |
|||
a: new BigNumber(1), |
|||
b: new BigNumber(10), |
|||
c: new BigNumber(4), |
|||
d: new BigNumber(16) |
|||
}, |
|||
logIndex: 1, |
|||
transactionIndex: 16, |
|||
transactionHash: '0x1234567890', |
|||
address: address, |
|||
blockHash: '0x1234567890', |
|||
blockNumber: 1 |
|||
} |
|||
}]; |
|||
|
|||
describe('lib/web3/event', function () { |
|||
describe('decode', function () { |
|||
tests.forEach(function (test, index) { |
|||
it('test no: ' + index, function () { |
|||
var event = new SolidityEvent(test.abi, address); |
|||
|
|||
var result = event.decode(test.data); |
|||
assert.deepEqual(result, test.expected); |
|||
}); |
|||
}); |
|||
}); |
|||
}); |
|||
|
@ -1,234 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var SolidityEvent = require('../lib/web3/event'); |
|||
|
|||
var address = '0x1234567890123456789012345678901234567890'; |
|||
var signature = '0xffff'; |
|||
|
|||
var tests = [{ |
|||
abi: { |
|||
name: 'event1', |
|||
inputs: [] |
|||
}, |
|||
indexed: {}, |
|||
options: {}, |
|||
expected: { |
|||
address: address, |
|||
topics: [ |
|||
signature |
|||
] |
|||
} |
|||
}, { |
|||
abi: { |
|||
name: 'event1', |
|||
inputs: [{ |
|||
type: 'int', |
|||
name: 'a', |
|||
indexed: true |
|||
}] |
|||
}, |
|||
indexed: { |
|||
a: 16 |
|||
}, |
|||
options: {}, |
|||
expected: { |
|||
address: address, |
|||
topics: [ |
|||
signature, |
|||
'0x0000000000000000000000000000000000000000000000000000000000000010' |
|||
] |
|||
} |
|||
},{ |
|||
abi: { |
|||
name: 'event1', |
|||
inputs: [{ |
|||
type: 'int', |
|||
name: 'a', |
|||
indexed: true |
|||
}, { |
|||
type: 'int', |
|||
name: 'b', |
|||
indexed: true |
|||
}, { |
|||
type: 'int', |
|||
name: 'c', |
|||
indexed: false |
|||
}, { |
|||
type: 'int', |
|||
name: 'd', |
|||
indexed: true |
|||
}] |
|||
}, |
|||
indexed: { |
|||
b: 4 |
|||
}, |
|||
options: {}, |
|||
expected: { |
|||
address: address, |
|||
topics: [ |
|||
signature, // signature
|
|||
null, // a
|
|||
'0x0000000000000000000000000000000000000000000000000000000000000004', // b
|
|||
null // d
|
|||
] |
|||
} |
|||
}, { |
|||
abi: { |
|||
name: 'event1', |
|||
inputs: [{ |
|||
type: 'int', |
|||
name: 'a', |
|||
indexed: true |
|||
}, { |
|||
type: 'int', |
|||
name: 'b', |
|||
indexed: true |
|||
}] |
|||
}, |
|||
indexed: { |
|||
a: [16, 1], |
|||
b: 2 |
|||
}, |
|||
options: {}, |
|||
expected: { |
|||
address: address, |
|||
topics: [ |
|||
signature, |
|||
['0x0000000000000000000000000000000000000000000000000000000000000010', '0x0000000000000000000000000000000000000000000000000000000000000001'], |
|||
'0x0000000000000000000000000000000000000000000000000000000000000002' |
|||
] |
|||
} |
|||
}, { |
|||
abi: { |
|||
name: 'event1', |
|||
inputs: [{ |
|||
type: 'int', |
|||
name: 'a', |
|||
indexed: true |
|||
}] |
|||
}, |
|||
indexed: { |
|||
a: null |
|||
}, |
|||
options: {}, |
|||
expected: { |
|||
address: address, |
|||
topics: [ |
|||
signature, |
|||
null |
|||
] |
|||
} |
|||
}, { |
|||
abi: { |
|||
name: 'event1', |
|||
inputs: [{ |
|||
type: 'int', |
|||
name: 'a', |
|||
indexed: true |
|||
}] |
|||
}, |
|||
indexed: { |
|||
a: 1 |
|||
}, |
|||
options: { |
|||
fromBlock: 'latest', |
|||
toBlock: 'pending' |
|||
}, |
|||
expected: { |
|||
address: address, |
|||
fromBlock: 'latest', |
|||
toBlock: 'pending', |
|||
topics: [ |
|||
signature, |
|||
'0x0000000000000000000000000000000000000000000000000000000000000001' |
|||
] |
|||
} |
|||
}, |
|||
{ |
|||
abi: { |
|||
name: 'event1', |
|||
inputs: [{ |
|||
type: 'int', |
|||
name: 'a', |
|||
indexed: true |
|||
}] |
|||
}, |
|||
indexed: { |
|||
a: 1 |
|||
}, |
|||
options: { |
|||
fromBlock: 4, |
|||
toBlock: 10 |
|||
}, |
|||
expected: { |
|||
address: address, |
|||
fromBlock: '0x4', |
|||
toBlock: '0xa', |
|||
topics: [ |
|||
signature, |
|||
'0x0000000000000000000000000000000000000000000000000000000000000001' |
|||
] |
|||
} |
|||
}, { |
|||
abi: { |
|||
name: 'event1', |
|||
inputs: [{ |
|||
type: 'int', |
|||
name: 'a', |
|||
indexed: true |
|||
}], |
|||
anonymous: true |
|||
}, |
|||
indexed: { |
|||
a: 1 |
|||
}, |
|||
options: {}, |
|||
expected: { |
|||
address: address, |
|||
topics: [ |
|||
'0x0000000000000000000000000000000000000000000000000000000000000001' |
|||
] |
|||
} |
|||
}, { |
|||
abi: { |
|||
name: 'event1', |
|||
inputs: [{ |
|||
type: 'int', |
|||
name: 'a', |
|||
indexed: true |
|||
}, { |
|||
type: 'int', |
|||
name: 'b', |
|||
indexed: true |
|||
}], |
|||
anonymous: true |
|||
}, |
|||
indexed: { |
|||
b: 1 |
|||
}, |
|||
options: {}, |
|||
expected: { |
|||
address: address, |
|||
topics: [ |
|||
null, |
|||
'0x0000000000000000000000000000000000000000000000000000000000000001' |
|||
] |
|||
} |
|||
}]; |
|||
|
|||
describe('lib/web3/event', function () { |
|||
describe('encode', function () { |
|||
tests.forEach(function (test, index) { |
|||
it('test no: ' + index, function () { |
|||
var event = new SolidityEvent(test.abi, address); |
|||
event.signature = function () { // inject signature
|
|||
return signature.slice(2); |
|||
}; |
|||
|
|||
var result = event.encode(test.indexed, test.options); |
|||
assert.deepEqual(result, test.expected); |
|||
}); |
|||
}); |
|||
}); |
|||
}); |
|||
|
@ -1,24 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var formatters = require('../lib/web3/formatters'); |
|||
|
|||
var tests = [ |
|||
{ value: 'latest', expected: 'latest' }, |
|||
{ value: 'pending', expected: 'pending' }, |
|||
{ value: 'earliest', expected: 'earliest' }, |
|||
{ value: 1, expected: '0x1' }, |
|||
{ value: '0x1', expected: '0x1' } |
|||
]; |
|||
|
|||
describe('lib/web3/formatters', function () { |
|||
describe('inputDefaultBlockNumberFormatter', function () { |
|||
tests.forEach(function (test) { |
|||
it('should turn ' + test.value + ' to ' + test.expected, function () { |
|||
assert.strictEqual(formatters.inputDefaultBlockNumberFormatter(test.value), test.expected); |
|||
}); |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
|
|||
|
@ -1,30 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var formatters = require('../lib/web3/formatters.js'); |
|||
|
|||
describe('formatters', function () { |
|||
describe('inputPostFormatter', function () { |
|||
it('should return the correct value', function () { |
|||
|
|||
// input as strings and numbers
|
|||
assert.deepEqual(formatters.inputPostFormatter({ |
|||
from: '0x00000', |
|||
to: '0x00000', |
|||
payload: {test: 'test'}, |
|||
ttl: 200, |
|||
priority: 1000, |
|||
topics: ['hello','mytopics'] |
|||
}), { |
|||
from: '0x00000', |
|||
to: '0x00000', |
|||
payload: '0x7b2274657374223a2274657374227d', |
|||
ttl: '0xc8', |
|||
priority: '0x3e8', |
|||
topics: ['0x68656c6c6f','0x6d79746f70696373'], |
|||
workToProve: '0x0' |
|||
}); |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
@ -1,65 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var formatters = require('../lib/web3/formatters.js'); |
|||
var BigNumber = require('bignumber.js'); |
|||
|
|||
var tests = [{ |
|||
input: { |
|||
data: '0x34234bf23bf4234', |
|||
value: new BigNumber(100), |
|||
from: '0x00000', |
|||
to: '0x00000', |
|||
nonce: 1000, |
|||
gas: 1000, |
|||
gasPrice: new BigNumber(1000) |
|||
}, |
|||
result: { |
|||
data: '0x34234bf23bf4234', |
|||
value: '0x64', |
|||
from: '0x00000', |
|||
to: '0x00000', |
|||
nonce: '0x3e8', |
|||
gas: '0x3e8', |
|||
gasPrice: '0x3e8' |
|||
} |
|||
},{ |
|||
input: { |
|||
data: '0x34234bf23bf4234', |
|||
value: new BigNumber(100), |
|||
from: '0x00000', |
|||
to: '0x00000', |
|||
}, |
|||
result: { |
|||
data: '0x34234bf23bf4234', |
|||
value: '0x64', |
|||
from: '0x00000', |
|||
to: '0x00000', |
|||
} |
|||
},{ |
|||
input: { |
|||
data: '0x34234bf23bf4234', |
|||
value: new BigNumber(100), |
|||
from: '0x00000', |
|||
to: '0x00000', |
|||
gas: '1000', |
|||
gasPrice: new BigNumber(1000) |
|||
}, |
|||
result: { |
|||
data: '0x34234bf23bf4234', |
|||
value: '0x64', |
|||
from: '0x00000', |
|||
to: '0x00000', |
|||
gas: '0x3e8', |
|||
gasPrice: '0x3e8' |
|||
} |
|||
}]; |
|||
|
|||
describe('formatters', function () { |
|||
describe('inputTransactionFormatter', function () { |
|||
tests.forEach(function(test){ |
|||
it('should return the correct value', function () { |
|||
assert.deepEqual(formatters.inputTransactionFormatter(test.input), test.result); |
|||
}); |
|||
}); |
|||
}); |
|||
}); |
@ -1,81 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var formatters = require('../lib/web3/formatters.js'); |
|||
var BigNumber = require('bignumber.js'); |
|||
|
|||
describe('formatters', function () { |
|||
describe('outputBlockFormatter', function () { |
|||
it('should return the correct value', function () { |
|||
|
|||
assert.deepEqual(formatters.outputBlockFormatter({ |
|||
hash: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
parentHash: '0x83ffb245cfced97ccc5c75253d6960376d6c6dea93647397a543a72fdaea5265', |
|||
miner: '0xdcc6960376d6c6dea93647383ffb245cfced97cf', |
|||
stateRoot: '0x54dda68af07643f68739a6e9612ad157a26ae7e2ce81f77842bb5835fbcde583', |
|||
sha3Uncles: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', |
|||
bloom: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
difficulty: '0x3e8', |
|||
totalDifficulty: '0x3e8', |
|||
number: '0x3e8', |
|||
gasLimit: '0x3e8', |
|||
gasUsed: '0x3e8', |
|||
timestamp: '0x3e8', |
|||
extraData: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
nonce: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
size: '0x3e8' |
|||
}), { |
|||
hash: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
parentHash: '0x83ffb245cfced97ccc5c75253d6960376d6c6dea93647397a543a72fdaea5265', |
|||
miner: '0xdcc6960376d6c6dea93647383ffb245cfced97cf', |
|||
stateRoot: '0x54dda68af07643f68739a6e9612ad157a26ae7e2ce81f77842bb5835fbcde583', |
|||
sha3Uncles: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', |
|||
bloom: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
difficulty: new BigNumber(1000), |
|||
totalDifficulty: new BigNumber(1000), |
|||
number: 1000, |
|||
gasLimit: 1000, |
|||
gasUsed: 1000, |
|||
timestamp: 1000, |
|||
extraData: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
nonce: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
size: 1000 |
|||
}); |
|||
}); |
|||
it('should return the correct value, when null values are present', function () { |
|||
|
|||
assert.deepEqual(formatters.outputBlockFormatter({ |
|||
hash: null, |
|||
parentHash: '0x83ffb245cfced97ccc5c75253d6960376d6c6dea93647397a543a72fdaea5265', |
|||
miner: null, |
|||
stateRoot: '0x54dda68af07643f68739a6e9612ad157a26ae7e2ce81f77842bb5835fbcde583', |
|||
sha3Uncles: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', |
|||
bloom: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
difficulty: '0x3e8', |
|||
totalDifficulty: '0x3e8', |
|||
number: null, |
|||
gasLimit: '0x3e8', |
|||
gasUsed: '0x3e8', |
|||
timestamp: '0x3e8', |
|||
extraData: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
nonce: null, |
|||
size: '0x3e8' |
|||
}), { |
|||
hash: null, |
|||
parentHash: '0x83ffb245cfced97ccc5c75253d6960376d6c6dea93647397a543a72fdaea5265', |
|||
miner: null, |
|||
stateRoot: '0x54dda68af07643f68739a6e9612ad157a26ae7e2ce81f77842bb5835fbcde583', |
|||
sha3Uncles: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', |
|||
bloom: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
difficulty: new BigNumber(1000), |
|||
totalDifficulty: new BigNumber(1000), |
|||
number: null, |
|||
gasLimit: 1000, |
|||
gasUsed: 1000, |
|||
timestamp: 1000, |
|||
extraData: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
nonce: null, |
|||
size: 1000 |
|||
}); |
|||
}); |
|||
}); |
|||
}); |
@ -1,47 +0,0 @@ |
|||
var assert = require('assert'); |
|||
var formatters = require('../lib/web3/formatters.js'); |
|||
|
|||
describe('formatters', function () { |
|||
describe('outputLogFormatter', function () { |
|||
it('should return the correct value', function () { |
|||
|
|||
assert.deepEqual(formatters.outputLogFormatter({ |
|||
transactionIndex: '0x3e8', |
|||
logIndex: '0x3e8', |
|||
blockNumber: '0x3e8', |
|||
transactionHash: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
blockHash: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
data: '0x7b2274657374223a2274657374227', |
|||
topics: ['0x68656c6c6f','0x6d79746f70696373'] |
|||
}), { |
|||
transactionIndex: 1000, |
|||
logIndex: 1000, |
|||
blockNumber: 1000, |
|||
transactionHash: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
blockHash: '0xd6960376d6c6dea93647383ffb245cfced97ccc5c7525397a543a72fdaea5265', |
|||
data: '0x7b2274657374223a2274657374227', |
|||
topics: ['0x68656c6c6f','0x6d79746f70696373'] |
|||
}); |
|||
}); |
|||
it('should return the correct value, when null values are present', function () { |
|||
|
|||
assert.deepEqual(formatters.outputLogFormatter({ |
|||
transactionIndex: null, |
|||
logIndex: null, |
|||
blockNumber: null, |
|||
transactionHash: null, |
|||
blockHash: null, |
|||
data: '0x7b2274657374223a2274657374227', |
|||
topics: ['0x68656c6c6f','0x6d79746f70696373'] |
|||
}), { |
|||
transactionIndex: null, |
|||
logIndex: null, |
|||
blockNumber: null, |
|||
transactionHash: null, |
|||
blockHash: null, |
|||
data: '0x7b2274657374223a2274657374227', |
|||
topics: ['0x68656c6c6f','0x6d79746f70696373'] |
|||
}); |
|||
}); |
|||
}); |
|||
}); |
@ -1,26 +0,0 @@ |
|||
var assert = require('assert'); |
|||
var formatters = require('../lib/web3/formatters.js'); |
|||
|
|||
describe('formatters', function () { |
|||
describe('outputPostFormatter', function () { |
|||
it('should return the correct value', function () { |
|||
|
|||
assert.deepEqual(formatters.outputPostFormatter({ |
|||
expiry: '0x3e8', |
|||
sent: '0x3e8', |
|||
ttl: '0x3e8', |
|||
workProved: '0x3e8', |
|||
payload: '0x7b2274657374223a2274657374227d', |
|||
topics: ['0x68656c6c6f','0x6d79746f70696373'] |
|||
}), { |
|||
expiry: 1000, |
|||
sent: 1000, |
|||
ttl: 1000, |
|||
workProved: 1000, |
|||
payload: {test: 'test'}, |
|||
payloadRaw: '0x7b2274657374223a2274657374227d', |
|||
topics: ['hello','mytopics'] |
|||
}); |
|||
}); |
|||
}); |
|||
}); |
@ -1,61 +0,0 @@ |
|||
var assert = require('assert'); |
|||
var formatters = require('../lib/web3/formatters.js'); |
|||
var BigNumber = require('bignumber.js'); |
|||
|
|||
describe('formatters', function () { |
|||
describe('outputTransactionFormatter', function () { |
|||
it('should return the correct value', function () { |
|||
|
|||
assert.deepEqual(formatters.outputTransactionFormatter({ |
|||
input: '0x3454645634534', |
|||
from: '0x00000', |
|||
to: '0x00000', |
|||
value: '0x3e8', |
|||
gas: '0x3e8', |
|||
gasPrice: '0x3e8', |
|||
nonce: '0xb', |
|||
transactionIndex: '0x1', |
|||
blockNumber: '0x3e8', |
|||
blockHash: '0xc9b9cdc2092a9d6589d96662b1fd6949611163fb3910cf8a173cd060f17702f9' |
|||
}), { |
|||
input: '0x3454645634534', |
|||
from: '0x00000', |
|||
to: '0x00000', |
|||
value: new BigNumber(1000), |
|||
gas: 1000, |
|||
gasPrice: new BigNumber(1000), |
|||
nonce: 11, |
|||
blockNumber: 1000, |
|||
blockHash: '0xc9b9cdc2092a9d6589d96662b1fd6949611163fb3910cf8a173cd060f17702f9', |
|||
transactionIndex: 1 |
|||
}); |
|||
}); |
|||
|
|||
it('should return the correct value, when null values are present', function () { |
|||
|
|||
assert.deepEqual(formatters.outputTransactionFormatter({ |
|||
input: '0x3454645634534', |
|||
from: '0x00000', |
|||
to: null, |
|||
value: '0x3e8', |
|||
gas: '0x3e8', |
|||
gasPrice: '0x3e8', |
|||
nonce: '0xb', |
|||
transactionIndex: null, |
|||
blockNumber: null, |
|||
blockHash: null |
|||
}), { |
|||
input: '0x3454645634534', |
|||
from: '0x00000', |
|||
to: null, |
|||
value: new BigNumber(1000), |
|||
gas: 1000, |
|||
gasPrice: new BigNumber(1000), |
|||
nonce: 11, |
|||
blockNumber: null, |
|||
blockHash: null, |
|||
transactionIndex: null |
|||
}); |
|||
}); |
|||
}); |
|||
}); |
@ -1,88 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = require('assert'); |
|||
var utils = require('../../lib/utils/utils'); |
|||
|
|||
var getResponseStub = function () { |
|||
return { |
|||
jsonrpc: '2.0', |
|||
id: 1, |
|||
result: 0 |
|||
}; |
|||
}; |
|||
|
|||
var getErrorStub = function () { |
|||
return { |
|||
jsonrpc: '2.0', |
|||
id: 1, |
|||
error: { |
|||
code: 1234, |
|||
message: '' |
|||
} |
|||
}; |
|||
}; |
|||
|
|||
var FakeHttpProvider = function () { |
|||
this.response = getResponseStub(); |
|||
this.error = null; |
|||
this.validation = null; |
|||
}; |
|||
|
|||
FakeHttpProvider.prototype.send = function (payload) { |
|||
assert.equal(utils.isArray(payload) || utils.isObject(payload), true); |
|||
// TODO: validate jsonrpc request
|
|||
if (this.error) { |
|||
throw this.error; |
|||
} |
|||
if (this.validation) { |
|||
// imitate plain json object
|
|||
this.validation(JSON.parse(JSON.stringify(payload))); |
|||
} |
|||
return this.getResponse(); |
|||
}; |
|||
|
|||
FakeHttpProvider.prototype.sendAsync = function (payload, callback) { |
|||
assert.equal(utils.isArray(payload) || utils.isObject(payload), true); |
|||
assert.equal(utils.isFunction(callback), true); |
|||
if (this.validation) { |
|||
// imitate plain json object
|
|||
this.validation(JSON.parse(JSON.stringify(payload)), callback); |
|||
} |
|||
callback(this.error, this.getResponse()); |
|||
}; |
|||
|
|||
FakeHttpProvider.prototype.injectResponse = function (response) { |
|||
this.response = response; |
|||
}; |
|||
|
|||
FakeHttpProvider.prototype.injectResult = function (result) { |
|||
this.response = getResponseStub(); |
|||
this.response.result = result; |
|||
}; |
|||
|
|||
FakeHttpProvider.prototype.injectBatchResults = function (results, error) { |
|||
this.response = results.map(function (r) { |
|||
if(error) { |
|||
var response = getErrorStub(); |
|||
response.error.message = r; |
|||
} else { |
|||
var response = getResponseStub(); |
|||
response.result = r; |
|||
} |
|||
return response; |
|||
}); |
|||
}; |
|||
|
|||
FakeHttpProvider.prototype.getResponse = function () { |
|||
return this.response; |
|||
}; |
|||
|
|||
FakeHttpProvider.prototype.injectError = function (error) { |
|||
this.error = error; |
|||
}; |
|||
|
|||
FakeHttpProvider.prototype.injectValidation = function (callback) { |
|||
this.validation = callback; |
|||
}; |
|||
|
|||
module.exports = FakeHttpProvider; |
|||
|
@ -1,37 +0,0 @@ |
|||
var FakeHttpProvider = require('./FakeHttpProvider'); |
|||
|
|||
var FakeHttpProvider2 = function () { |
|||
this.counter = 0; |
|||
this.resultList = []; |
|||
}; |
|||
|
|||
FakeHttpProvider2.prototype = new FakeHttpProvider(); |
|||
FakeHttpProvider2.prototype.constructor = FakeHttpProvider2; |
|||
|
|||
FakeHttpProvider2.prototype.injectResultList = function (list) { |
|||
this.resultList = list; |
|||
}; |
|||
|
|||
FakeHttpProvider2.prototype.getResponse = function () { |
|||
var result = this.resultList[this.counter]; |
|||
this.counter++; |
|||
|
|||
// add fallback result value
|
|||
if(!result) |
|||
result = { |
|||
result: undefined |
|||
}; |
|||
|
|||
if (result.type === 'batch') { |
|||
this.injectBatchResults(result.result); |
|||
} else { |
|||
this.injectResult(result.result); |
|||
} |
|||
|
|||
this.counter = 0; |
|||
|
|||
return this.response; |
|||
}; |
|||
|
|||
module.exports = FakeHttpProvider2; |
|||
|
@ -1,41 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
|
|||
var FakeIpcRequest = function () { |
|||
this._handle = {fd: {}}; |
|||
this.callbacks = []; |
|||
|
|||
return this |
|||
}; |
|||
|
|||
FakeIpcRequest.prototype.connect = function (path) { |
|||
assert.notEqual(path, undefined); |
|||
|
|||
return this; |
|||
}; |
|||
|
|||
FakeIpcRequest.prototype.on = function(name, callback) { |
|||
if(name === 'data'){ |
|||
this.callbacks.push(callback); |
|||
} |
|||
}; |
|||
|
|||
FakeIpcRequest.prototype.writeSync = function (payload) { |
|||
assert.equal(typeof payload, 'string'); |
|||
|
|||
return payload; |
|||
}; |
|||
|
|||
FakeIpcRequest.prototype.write = function (payload) { |
|||
assert.equal(typeof payload, 'string'); |
|||
|
|||
this.callbacks.forEach(function(cb){ |
|||
setTimeout(function(){ |
|||
cb(payload); |
|||
}, 100); |
|||
}); |
|||
|
|||
}; |
|||
|
|||
module.exports = new FakeIpcRequest(); |
|||
|
@ -1,11 +0,0 @@ |
|||
|
|||
var navigator = { |
|||
qt: { |
|||
callMethod: function (payload) { |
|||
return "{}"; |
|||
} |
|||
} |
|||
}; |
|||
|
|||
module.exports = navigator; |
|||
|
@ -1,38 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
|
|||
var FakeXMLHttpRequest = function () { |
|||
this.responseText = "{}"; |
|||
this.readyState = 4; |
|||
this.onreadystatechange = null; |
|||
this.async = false; |
|||
this.headers = { |
|||
'Content-Type': 'text/plain' |
|||
}; |
|||
}; |
|||
|
|||
FakeXMLHttpRequest.prototype.open = function (method, host, async) { |
|||
assert.equal(method, 'POST'); |
|||
assert.notEqual(host, null); |
|||
assert.equal(async === false || async === true, true); |
|||
this.async = async; |
|||
}; |
|||
|
|||
FakeXMLHttpRequest.prototype.setRequestHeader = function(name, value) { |
|||
this.headers[name] = value; |
|||
}; |
|||
|
|||
FakeXMLHttpRequest.prototype.send = function (payload) { |
|||
assert.equal(typeof payload, 'string'); |
|||
if (this.async) { |
|||
assert.equal(typeof this.onreadystatechange, 'function'); |
|||
this.onreadystatechange(); |
|||
return; |
|||
} |
|||
return this.responseText; |
|||
}; |
|||
|
|||
module.exports = { |
|||
XMLHttpRequest: FakeXMLHttpRequest |
|||
}; |
|||
|
@ -1,79 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var web3 = require('../../index'); |
|||
var FakeHttpProvider = require('./FakeHttpProvider'); |
|||
var clone = function (object) { return JSON.parse(JSON.stringify(object)); }; |
|||
|
|||
var runTests = function (obj, method, tests) { |
|||
|
|||
var testName = obj ? 'web3.' + obj : 'web'; |
|||
|
|||
describe(testName, function () { |
|||
describe(method, function () { |
|||
tests.forEach(function (test, index) { |
|||
it('sync test: ' + index, function () { |
|||
|
|||
// given
|
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
provider.injectResult(test.result); |
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.jsonrpc, '2.0'); |
|||
assert.equal(payload.method, test.call); |
|||
assert.deepEqual(payload.params, test.formattedArgs); |
|||
}); |
|||
|
|||
var args = clone(test.args) |
|||
|
|||
// when
|
|||
if (obj) { |
|||
var result = web3[obj][method].apply(null, args); |
|||
} else { |
|||
var result = web3[method].apply(null, args); |
|||
} |
|||
// when
|
|||
//var result = (obj)
|
|||
//? web3[obj][method].apply(null, test.args.slice(0))
|
|||
//: web3[method].apply(null, test.args.slice(0));
|
|||
|
|||
// then
|
|||
assert.deepEqual(test.formattedResult, result); |
|||
}); |
|||
|
|||
it('async test: ' + index, function (done) { |
|||
|
|||
// given
|
|||
var provider = new FakeHttpProvider(); |
|||
web3.setProvider(provider); |
|||
provider.injectResult(test.result); |
|||
provider.injectValidation(function (payload) { |
|||
assert.equal(payload.jsonrpc, '2.0'); |
|||
assert.equal(payload.method, test.call); |
|||
assert.deepEqual(payload.params, test.formattedArgs); |
|||
}); |
|||
|
|||
var args = clone(test.args); |
|||
|
|||
// add callback
|
|||
args.push(function (err, result) { |
|||
assert.deepEqual(test.formattedResult, result); |
|||
done(); |
|||
}); |
|||
|
|||
// when
|
|||
if (obj) { |
|||
web3[obj][method].apply(null, args); |
|||
} else { |
|||
web3[method].apply(null, args); |
|||
} |
|||
}); |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
}; |
|||
|
|||
module.exports = { |
|||
runTests: runTests |
|||
} |
|||
|
@ -1,26 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var web3 = require('../../index'); |
|||
|
|||
var FakeHttpProvider = require('./FakeHttpProvider'); |
|||
|
|||
var methodExists = function (object, method) { |
|||
it('should have method ' + method + ' implemented', function() { |
|||
web3.setProvider(null); |
|||
assert.equal('function', typeof object[method], 'method ' + method + ' is not implemented'); |
|||
}); |
|||
}; |
|||
|
|||
var propertyExists = function (object, property) { |
|||
it('should have property ' + property + ' implemented', function() { |
|||
// set dummy providor, to prevent error
|
|||
web3.setProvider(new FakeHttpProvider()); |
|||
assert.notEqual('undefined', typeof object[property], 'property ' + property + ' is not implemented'); |
|||
}); |
|||
}; |
|||
|
|||
module.exports = { |
|||
methodExists: methodExists, |
|||
propertyExists: propertyExists |
|||
}; |
|||
|
@ -1,41 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var SandboxedModule = require('sandboxed-module'); |
|||
|
|||
SandboxedModule.registerBuiltInSourceTransformer('istanbul'); |
|||
var HttpProvider = SandboxedModule.require('../lib/web3/httpprovider', { |
|||
requires: { |
|||
'xmlhttprequest': require('./helpers/FakeXMLHttpRequest') |
|||
} |
|||
}); |
|||
|
|||
describe('lib/web3/httpprovider', function () { |
|||
describe('send', function () { |
|||
it('should send basic request', function () { |
|||
var provider = new HttpProvider(); |
|||
var result = provider.send({}); |
|||
|
|||
assert.equal(typeof result, 'object'); |
|||
}); |
|||
}); |
|||
|
|||
describe('sendAsync', function () { |
|||
it('should send basic async request', function (done) { |
|||
var provider = new HttpProvider(); |
|||
|
|||
provider.sendAsync({}, function (err, result) { |
|||
assert.equal(typeof result, 'object'); |
|||
done(); |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
describe('isConnected', function () { |
|||
it('should return a boolean', function () { |
|||
var provider = new HttpProvider(); |
|||
|
|||
assert.isBoolean(provider.isConnected()); |
|||
}); |
|||
}); |
|||
}); |
|||
|
@ -1,58 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var SandboxedModule = require('sandboxed-module'); |
|||
|
|||
SandboxedModule.registerBuiltInSourceTransformer('istanbul'); |
|||
var IpcProvider = SandboxedModule.require('../lib/web3/ipcprovider', { |
|||
requires: { |
|||
'bignumber.js': require('bignumber.js'), |
|||
'net': require('./helpers/FakeIpcRequest') |
|||
} |
|||
}); |
|||
|
|||
describe('lib/web3/ipcprovider', function () { |
|||
describe('send', function () { |
|||
it('should send basic request', function () { |
|||
var provider = new IpcProvider(); |
|||
var result = provider.send({id: 1, method: 'eth_test'}); |
|||
|
|||
assert.isObject(result); |
|||
}); |
|||
}); |
|||
|
|||
describe('sendAsync', function () { |
|||
it('should send basic async request', function (done) { |
|||
var provider = new IpcProvider(); |
|||
|
|||
provider.sendAsync({id: 1, method: 'eth_test'}, function (err, result) { |
|||
assert.isObject(result); |
|||
done(); |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
describe('isConnected', function () { |
|||
it('should return a boolean', function () { |
|||
var provider = new IpcProvider(); |
|||
|
|||
assert.isBoolean(provider.isConnected()); |
|||
}); |
|||
|
|||
it('should return false', function () { |
|||
var provider = new IpcProvider(); |
|||
|
|||
provider.connection.writable = false; |
|||
|
|||
assert.isFalse(provider.isConnected()); |
|||
}); |
|||
|
|||
it('should return true, when a net handle is set', function () { |
|||
var provider = new IpcProvider(); |
|||
|
|||
provider.connection.writable = true; |
|||
|
|||
assert.isTrue(provider.isConnected()); |
|||
}); |
|||
}); |
|||
}); |
|||
|
@ -1,23 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var Jsonrpc = require('../lib/web3/jsonrpc'); |
|||
|
|||
describe('lib/web3/jsonrpc', function () { |
|||
describe('id', function () { |
|||
it('should increment the id', function () { |
|||
|
|||
// given
|
|||
var a = Jsonrpc.getInstance(); |
|||
var b = Jsonrpc.getInstance(); |
|||
var method = 'm'; |
|||
|
|||
// when
|
|||
var p1 = a.toPayload(method); |
|||
var p2 = b.toPayload(method); |
|||
|
|||
// then
|
|||
assert.equal(p2.id, p1.id + 1); |
|||
}); |
|||
}); |
|||
}); |
|||
|
@ -1,144 +0,0 @@ |
|||
var assert = require('assert'); |
|||
var jsonrpc = require('../lib/web3/jsonrpc'); |
|||
jsonrpc = new jsonrpc(); |
|||
|
|||
describe('jsonrpc', function () { |
|||
describe('isValidResponse', function () { |
|||
it('should validate basic jsonrpc response', function () { |
|||
|
|||
// given
|
|||
var response = { |
|||
jsonrpc: '2.0', |
|||
id: 1, |
|||
result: [] |
|||
}; |
|||
|
|||
// when
|
|||
var valid = jsonrpc.isValidResponse(response); |
|||
|
|||
// then
|
|||
assert.equal(valid, true); |
|||
}); |
|||
|
|||
it('should validate basic undefined response', function () { |
|||
|
|||
// given
|
|||
var response = undefined; |
|||
|
|||
// when
|
|||
var valid = jsonrpc.isValidResponse(response); |
|||
|
|||
// then
|
|||
assert.equal(valid, false); |
|||
}); |
|||
|
|||
it('should validate jsonrpc response without jsonrpc field', function () { |
|||
|
|||
// given
|
|||
var response = { |
|||
id: 1, |
|||
result: [] |
|||
}; |
|||
|
|||
// when
|
|||
var valid = jsonrpc.isValidResponse(response); |
|||
|
|||
// then
|
|||
assert.equal(valid, false); |
|||
}); |
|||
|
|||
it('should validate jsonrpc response with wrong jsonrpc version', function () { |
|||
|
|||
// given
|
|||
var response = { |
|||
jsonrpc: '1.0', |
|||
id: 1, |
|||
result: [] |
|||
}; |
|||
|
|||
// when
|
|||
var valid = jsonrpc.isValidResponse(response); |
|||
|
|||
// then
|
|||
assert.equal(valid, false); |
|||
}); |
|||
|
|||
it('should validate jsonrpc response without id number', function () { |
|||
|
|||
// given
|
|||
var response = { |
|||
jsonrpc: '2.0', |
|||
result: [] |
|||
}; |
|||
|
|||
// when
|
|||
var valid = jsonrpc.isValidResponse(response); |
|||
|
|||
// then
|
|||
assert.equal(valid, false); |
|||
}); |
|||
|
|||
it('should validate jsonrpc response with wrong id field', function () { |
|||
|
|||
// given
|
|||
var response = { |
|||
jsonrpc: '2.0', |
|||
id: 'x', |
|||
result: [] |
|||
}; |
|||
|
|||
// when
|
|||
var valid = jsonrpc.isValidResponse(response); |
|||
|
|||
// then
|
|||
assert.equal(valid, false); |
|||
}); |
|||
|
|||
it('should validate jsonrpc response without result field', function () { |
|||
|
|||
// given
|
|||
var response = { |
|||
jsonrpc: '2.0', |
|||
id: 1 |
|||
}; |
|||
|
|||
// when
|
|||
var valid = jsonrpc.isValidResponse(response); |
|||
|
|||
// then
|
|||
assert.equal(valid, false); |
|||
}); |
|||
|
|||
it('should validate jsonrpc response with result field === false', function () { |
|||
|
|||
// given
|
|||
var response = { |
|||
jsonrpc: '2.0', |
|||
id: 1, |
|||
result: false |
|||
}; |
|||
|
|||
// when
|
|||
var valid = jsonrpc.isValidResponse(response); |
|||
|
|||
// then
|
|||
assert.equal(valid, true); |
|||
}); |
|||
|
|||
it('should validate jsonrpc response with result field === 0', function () { |
|||
|
|||
// given
|
|||
var response = { |
|||
jsonrpc: '2.0', |
|||
id: 1, |
|||
result: 0 |
|||
}; |
|||
|
|||
// when
|
|||
var valid = jsonrpc.isValidResponse(response); |
|||
|
|||
// then
|
|||
assert.equal(valid, true); |
|||
}); |
|||
}); |
|||
}); |
@ -1,48 +0,0 @@ |
|||
var assert = require('assert'); |
|||
var jsonrpc = require('../lib/web3/jsonrpc'); |
|||
jsonrpc = new jsonrpc(); |
|||
|
|||
describe('jsonrpc', function () { |
|||
describe('toBatchPayload', function () { |
|||
it('should create basic batch payload', function () { |
|||
|
|||
// given
|
|||
var messages = [{ |
|||
method: 'helloworld' |
|||
}, { |
|||
method: 'test2', |
|||
params: [1] |
|||
}]; |
|||
|
|||
// when
|
|||
var payload = jsonrpc.toBatchPayload(messages); |
|||
|
|||
// then
|
|||
assert.equal(payload instanceof Array, true); |
|||
assert.equal(payload.length, 2); |
|||
assert.equal(payload[0].jsonrpc, '2.0'); |
|||
assert.equal(payload[1].jsonrpc, '2.0'); |
|||
assert.equal(payload[0].method, 'helloworld'); |
|||
assert.equal(payload[1].method, 'test2'); |
|||
assert.equal(payload[0].params instanceof Array, true); |
|||
assert.equal(payload[1].params.length, 1); |
|||
assert.equal(payload[1].params[0], 1); |
|||
assert.equal(typeof payload[0].id, 'number'); |
|||
assert.equal(typeof payload[1].id, 'number'); |
|||
assert.equal(payload[0].id + 1, payload[1].id); |
|||
}); |
|||
|
|||
it('should create batch payload for empty input array', function () { |
|||
|
|||
// given
|
|||
var messages = []; |
|||
|
|||
// when
|
|||
var payload = jsonrpc.toBatchPayload(messages); |
|||
|
|||
// then
|
|||
assert.equal(payload instanceof Array, true); |
|||
assert.equal(payload.length, 0); |
|||
}); |
|||
}); |
|||
}); |
@ -1,42 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var jsonrpc = require('../lib/web3/jsonrpc'); |
|||
jsonrpc = new jsonrpc(); |
|||
|
|||
describe('jsonrpc', function () { |
|||
describe('toPayload', function () { |
|||
it('should create basic payload', function () { |
|||
|
|||
// given
|
|||
var method = 'helloworld'; |
|||
|
|||
// when
|
|||
var payload = jsonrpc.toPayload(method); |
|||
|
|||
// then
|
|||
assert.equal(payload.jsonrpc, '2.0'); |
|||
assert.equal(payload.method, method); |
|||
assert.equal(payload.params instanceof Array, true); |
|||
assert.equal(payload.params.length, 0); |
|||
assert.equal(typeof payload.id, 'number'); |
|||
}); |
|||
|
|||
it('should create payload with params', function () { |
|||
|
|||
// given
|
|||
var method = 'helloworld1'; |
|||
var params = [123, 'test']; |
|||
|
|||
// when
|
|||
var payload = jsonrpc.toPayload(method, params); |
|||
|
|||
// then
|
|||
assert.equal(payload.jsonrpc, '2.0'); |
|||
assert.equal(payload.method, method); |
|||
assert.equal(payload.params.length, 2); |
|||
assert.equal(payload.params[0], params[0]); |
|||
assert.equal(payload.params[1], params[1]); |
|||
assert.equal(typeof payload.id, 'number'); |
|||
}); |
|||
}); |
|||
}); |
@ -1,44 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var Method = require('../lib/web3/method'); |
|||
var utils = require('../lib/utils/utils'); |
|||
|
|||
describe('lib/web3/method', function () { |
|||
describe('attachToObject', function () { |
|||
//it('attach simple function to an object', function () {
|
|||
|
|||
//// given
|
|||
//var method = new Method({
|
|||
//name: 'hello'
|
|||
//});
|
|||
//var object = {};
|
|||
//var func = function () { return 1; };
|
|||
|
|||
//// when
|
|||
//method.attachToObject(object, func);
|
|||
|
|||
//// then
|
|||
//assert.equal(utils.isFunction(object.hello), true);
|
|||
//assert.equal(object.hello(), 1);
|
|||
//});
|
|||
|
|||
//it('attach nested function to an object', function () {
|
|||
|
|||
//// given
|
|||
//var method = new Method({
|
|||
//name: 'hello.world'
|
|||
//});
|
|||
//var object = {};
|
|||
//var func = function () { return 1; };
|
|||
|
|||
//// when
|
|||
//method.attachToObject(object, func);
|
|||
|
|||
//// then
|
|||
//assert.equal(utils.isObject(object.hello), true);
|
|||
//assert.equal(utils.isFunction(object.hello.world), true);
|
|||
//assert.equal(object.hello.world(), 1);
|
|||
//});
|
|||
}); |
|||
}); |
|||
|
@ -1,52 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var Method = require('../lib/web3/method'); |
|||
|
|||
describe('lib/web3/method', function () { |
|||
describe('extractCallback', function () { |
|||
it('should extract callback', function () { |
|||
|
|||
// given
|
|||
var method = new Method({}); |
|||
var callback = function () { }; |
|||
var args = [1, callback] |
|||
|
|||
// when
|
|||
var result = method.extractCallback(args); |
|||
|
|||
// then
|
|||
assert.equal(args.length, 1); |
|||
assert.equal(callback, result); |
|||
}); |
|||
|
|||
it('should extract callback created using newFunction', function () { |
|||
|
|||
// given
|
|||
var method = new Method({}); |
|||
var callback = new Function (); |
|||
var args = [1, callback] |
|||
|
|||
// when
|
|||
var result = method.extractCallback(args); |
|||
|
|||
// then
|
|||
assert.equal(args.length, 1); |
|||
assert.equal(callback, result); |
|||
}); |
|||
|
|||
it('should not extract the callback', function () { |
|||
|
|||
// given
|
|||
var method = new Method({}); |
|||
var args = [1, 2] |
|||
|
|||
// when
|
|||
var result = method.extractCallback(args); |
|||
|
|||
// then
|
|||
assert.equal(args.length, 2); |
|||
assert.equal(result, null); |
|||
}); |
|||
}); |
|||
}); |
|||
|
@ -1,41 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var Method = require('../lib/web3/method'); |
|||
|
|||
describe('lib/web3/method', function () { |
|||
describe('formatInput', function () { |
|||
it('should format plain input', function () { |
|||
|
|||
// given
|
|||
var star = function (arg) { |
|||
return arg + '*'; |
|||
}; |
|||
|
|||
var method = new Method({ |
|||
inputFormatter: [star, star, star] |
|||
}); |
|||
var args = ['1','2','3']; |
|||
var expectedArgs = ['1*', '2*', '3*']; |
|||
|
|||
// when
|
|||
var result = method.formatInput(args); |
|||
|
|||
// then
|
|||
assert.deepEqual(result, expectedArgs); |
|||
}); |
|||
|
|||
it('should do nothing if there is no formatter', function () { |
|||
|
|||
// given
|
|||
var method = new Method({}); |
|||
var args = [1,2,3]; |
|||
|
|||
// when
|
|||
var result = method.formatInput(args); |
|||
|
|||
// then
|
|||
assert.deepEqual(result, args); |
|||
}); |
|||
}); |
|||
}); |
|||
|
@ -1,43 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var Method = require('../lib/web3/method'); |
|||
|
|||
describe('lib/web3/method', function () { |
|||
describe('formatOutput', function () { |
|||
it('should format plain output', function () { |
|||
|
|||
// given
|
|||
var formatter = function (args) { |
|||
return args.map(function (arg) { |
|||
return arg + '*'; |
|||
}); |
|||
}; |
|||
|
|||
var method = new Method({ |
|||
outputFormatter: formatter |
|||
}); |
|||
var args = ['1','2','3']; |
|||
var expectedArgs = ['1*', '2*', '3*']; |
|||
|
|||
// when
|
|||
var result = method.formatOutput(args); |
|||
|
|||
// then
|
|||
assert.deepEqual(result, expectedArgs); |
|||
}); |
|||
|
|||
it('should do nothing if there is no formatter', function () { |
|||
|
|||
// given
|
|||
var method = new Method({}); |
|||
var args = [1,2,3]; |
|||
|
|||
// when
|
|||
var result = method.formatOutput(args); |
|||
|
|||
// then
|
|||
assert.deepEqual(result, args); |
|||
}); |
|||
}); |
|||
}); |
|||
|
@ -1,46 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var Method = require('../lib/web3/method'); |
|||
|
|||
describe('lib/web3/method', function () { |
|||
describe('getCall', function () { |
|||
it('should return call name', function () { |
|||
|
|||
// given
|
|||
var call = 'hello_call_world'; |
|||
var method = new Method({ |
|||
call: call |
|||
}); |
|||
|
|||
// when
|
|||
var result = method.getCall(); |
|||
|
|||
// then
|
|||
assert.equal(call, result); |
|||
}); |
|||
|
|||
it('should return call based on args', function () { |
|||
|
|||
// given
|
|||
var call = function (args) { |
|||
return args ? args.length.toString() : '0'; |
|||
}; |
|||
|
|||
var method = new Method({ |
|||
call: call |
|||
}); |
|||
|
|||
// when
|
|||
var r0 = method.getCall(); |
|||
var r1 = method.getCall([1]); |
|||
var r2 = method.getCall([1, 2]); |
|||
|
|||
// then
|
|||
assert.equal(r0, '0'); |
|||
assert.equal(r1, '1'); |
|||
assert.equal(r2, '2'); |
|||
|
|||
}); |
|||
}); |
|||
}); |
|||
|
@ -1,23 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var web3 = require('../index'); |
|||
|
|||
describe('lib/web3/method', function () { |
|||
describe('request', function () { |
|||
it('should create proper request', function () { |
|||
|
|||
var callback = function (err, result) {}; |
|||
var expected = { |
|||
method: 'eth_getBalance', |
|||
callback: callback, |
|||
params: ['0x0000000000000000000000000000000000000000', 'latest'], |
|||
}; |
|||
|
|||
var request = web3.eth.getBalance.request('0x0000000000000000000000000000000000000000', 'latest', callback); |
|||
|
|||
expected.format = request.format; |
|||
assert.deepEqual(request, expected); |
|||
}); |
|||
}); |
|||
}); |
|||
|
@ -1,47 +0,0 @@ |
|||
var chai = require('chai'); |
|||
var assert = chai.assert; |
|||
var Method = require('../lib/web3/method'); |
|||
var errors = require('../lib/web3/errors'); |
|||
|
|||
describe('lib/web3/method', function () { |
|||
describe('validateArgs', function () { |
|||
it('should pass', function () { |
|||
|
|||
// given
|
|||
var method = new Method({ |
|||
params: 1 |
|||
}); |
|||
|
|||
var args = [1]; |
|||
var args2 = ['heloas']; |
|||
|
|||
// when
|
|||
var test = function () { method.validateArgs(args); }; |
|||
var test2 = function () { method.validateArgs(args2); }; |
|||
|
|||
// then
|
|||
assert.doesNotThrow(test); |
|||
assert.doesNotThrow(test2); |
|||
}); |
|||
|
|||
it('should return call based on args', function () { |
|||
|
|||
// given
|
|||
var method = new Method({ |
|||
params: 2 |
|||
}); |
|||
|
|||
var args = [1]; |
|||
var args2 = ['heloas', '12', 3]; |
|||
|
|||
// when
|
|||
var test = function () { method.validateArgs(args); }; |
|||
var test2 = function () { method.validateArgs(args2); }; |
|||
|
|||
// then
|
|||
assert.throws(test, errors.InvalidNumberOfParams().message); |
|||
assert.throws(test2, errors.InvalidNumberOfParams().message); |
|||
}); |
|||
}); |
|||
}); |
|||
|
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue