add JOSN-RPC methods.
many of them have questions to Roman, shh_ method must wait till Roman finish create whisper protocol. Will try to schedule online meeting with Roman today to get answers / advice.
This commit is contained in:
parent
34d98c9ea3
commit
40b0749304
|
@ -28,6 +28,7 @@ import io.netty.util.CharsetUtil;
|
|||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
|
@ -48,11 +49,14 @@ public final class JsonRpcServer {
|
|||
this.ethereum = ethereum;
|
||||
|
||||
this.dispatcher = new Dispatcher();
|
||||
|
||||
this.dispatcher.register(new web3_clientVersion(this.ethereum));
|
||||
this.dispatcher.register(new web3_sha3(this.ethereum));
|
||||
|
||||
this.dispatcher.register(new net_version(this.ethereum));
|
||||
this.dispatcher.register(new net_listening(this.ethereum));
|
||||
this.dispatcher.register(new net_peerCount(this.ethereum));
|
||||
|
||||
this.dispatcher.register(new eth_protocolVersion(this.ethereum));
|
||||
this.dispatcher.register(new eth_coinbase(this.ethereum));
|
||||
this.dispatcher.register(new eth_mining(this.ethereum));
|
||||
|
@ -70,6 +74,47 @@ public final class JsonRpcServer {
|
|||
this.dispatcher.register(new eth_getCode(this.ethereum));
|
||||
this.dispatcher.register(new eth_sign(this.ethereum));
|
||||
this.dispatcher.register(new eth_sendTransaction(this.ethereum));
|
||||
this.dispatcher.register(new eth_call(this.ethereum));
|
||||
this.dispatcher.register(new eth_estimateGas(this.ethereum));
|
||||
this.dispatcher.register(new eth_getBlockByHash(this.ethereum));
|
||||
this.dispatcher.register(new eth_getBlockByNumber(this.ethereum));
|
||||
this.dispatcher.register(new eth_getTransactionByHash(this.ethereum));
|
||||
this.dispatcher.register(new eth_getTransactionByBlockHashAndIndex(this.ethereum));
|
||||
this.dispatcher.register(new eth_getTransactionByBlockNumberAndIndex(this.ethereum));
|
||||
this.dispatcher.register(new eth_getUncleByBlockHashAndIndex(this.ethereum));
|
||||
this.dispatcher.register(new eth_getUncleByBlockNumberAndIndex(this.ethereum));
|
||||
this.dispatcher.register(new eth_getCompilers(this.ethereum));
|
||||
this.dispatcher.register(new eth_compileSolidity(this.ethereum));
|
||||
this.dispatcher.register(new eth_compileLLL(this.ethereum));
|
||||
this.dispatcher.register(new eth_compileSerpent(this.ethereum));
|
||||
this.dispatcher.register(new eth_newFilter(this.ethereum));
|
||||
this.dispatcher.register(new eth_newBlockFilter(this.ethereum));
|
||||
this.dispatcher.register(new eth_newPendingTransactionFilter(this.ethereum));
|
||||
this.dispatcher.register(new eth_uninstallFilter(this.ethereum));
|
||||
this.dispatcher.register(new eth_getFilterChanges(this.ethereum));
|
||||
this.dispatcher.register(new eth_getFilterLogs(this.ethereum));
|
||||
this.dispatcher.register(new eth_getLogs(this.ethereum));
|
||||
this.dispatcher.register(new eth_getWork(this.ethereum));
|
||||
this.dispatcher.register(new eth_submitWork(this.ethereum));
|
||||
|
||||
this.dispatcher.register(new db_putString(this.ethereum));
|
||||
this.dispatcher.register(new db_getString(this.ethereum));
|
||||
this.dispatcher.register(new db_putHex(this.ethereum));
|
||||
this.dispatcher.register(new db_getHex(this.ethereum));
|
||||
|
||||
this.dispatcher.register(new shh_version(this.ethereum));
|
||||
this.dispatcher.register(new shh_post(this.ethereum));
|
||||
this.dispatcher.register(new shh_newIdentity(this.ethereum));
|
||||
this.dispatcher.register(new shh_hasIdentity(this.ethereum));
|
||||
this.dispatcher.register(new shh_newGroup(this.ethereum));
|
||||
this.dispatcher.register(new shh_addToGroup(this.ethereum));
|
||||
this.dispatcher.register(new shh_newFilter(this.ethereum));
|
||||
this.dispatcher.register(new shh_uninstallFilter(this.ethereum));
|
||||
this.dispatcher.register(new shh_getFilterChanges(this.ethereum));
|
||||
this.dispatcher.register(new shh_getMessages(this.ethereum));
|
||||
|
||||
FilterManager.getInstance();
|
||||
org.ethereum.android.jsonrpc.whisper.FilterManager.getInstance();
|
||||
}
|
||||
|
||||
public void start() throws Exception {
|
||||
|
|
|
@ -3,11 +3,18 @@ package org.ethereum.android.jsonrpc;
|
|||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
import net.minidev.json.JSONObject;
|
||||
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServer;
|
||||
import org.ethereum.core.Account;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.core.BlockHeader;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.util.RLP;
|
||||
import org.ethereum.vm.DataWord;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
|
@ -15,6 +22,8 @@ import java.math.BigInteger;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.ethereum.core.Denomination.SZABO;
|
||||
|
||||
public abstract class JsonRpcServerMethod implements RequestHandler {
|
||||
|
||||
private String name = "";
|
||||
|
@ -74,4 +83,175 @@ public abstract class JsonRpcServerMethod implements RequestHandler {
|
|||
protected BigInteger jsToBigInteger(String data) {
|
||||
return new BigInteger(data.substring(2), 16);
|
||||
}
|
||||
|
||||
protected Transaction jsToTransaction(JSONObject obj) throws Exception {
|
||||
if ((!obj.containsKey("to") || ((String)obj.get("to")).equals("")) && (!obj.containsKey("data") || ((String)obj.get("data")).equals(""))) {
|
||||
throw new Exception("");
|
||||
}
|
||||
|
||||
byte[] from = ((Account) ethereum.getWallet().getAccountCollection().toArray()[1]).getEcKey().getAddress();
|
||||
if (obj.containsKey("from") && !((String)obj.get("from")).equals("")) {
|
||||
from = jsToAddress((String) obj.get("from"));
|
||||
}
|
||||
Account acc = null;
|
||||
for (Account ac : ethereum.getWallet().getAccountCollection()) {
|
||||
if (Arrays.equals(ac.getAddress(), from)) {
|
||||
acc = ac;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (acc == null) {
|
||||
throw new Exception("");
|
||||
}
|
||||
|
||||
byte[] senderPrivKey = acc.getEcKey().getPrivKeyBytes();
|
||||
|
||||
// default - from ethereumj-studio
|
||||
byte[] to = null;
|
||||
if (obj.containsKey("to") && !((String)obj.get("to")).equals("")) {
|
||||
to = jsToAddress((String) obj.get("to"));
|
||||
}
|
||||
|
||||
// default - from ethereumj-studio
|
||||
BigInteger gasPrice = SZABO.value().multiply(BigInteger.TEN);
|
||||
if (obj.containsKey("gasPrice") && !((String)obj.get("gasPrice")).equals("")) {
|
||||
gasPrice = jsToBigInteger((String) obj.get("gasPrice"));
|
||||
}
|
||||
|
||||
// default - from cpp-ethereum
|
||||
BigInteger gas = acc.getBalance().divide(gasPrice);
|
||||
BigInteger gasBBRemaining = new BigInteger(Long.toString((ethereum.getBlockchain().getBestBlock().getGasLimit() - ethereum.getBlockchain().getBestBlock().getGasUsed()) / 5));
|
||||
if (gasBBRemaining.compareTo(gas) < 0)
|
||||
gas = gasBBRemaining;
|
||||
if (obj.containsKey("gas") && !((String)obj.get("gas")).equals("")) {
|
||||
gas = jsToBigInteger((String) obj.get("gas"));
|
||||
}
|
||||
|
||||
// default - from ethereumj-studio
|
||||
BigInteger value = new BigInteger("1000");
|
||||
if (obj.containsKey("value") && !((String)obj.get("value")).equals("")) {
|
||||
value = jsToBigInteger((String) obj.get("value"));
|
||||
}
|
||||
|
||||
// default - from ethereumj-studio
|
||||
BigInteger nonce = ethereum.getRepository().getNonce(acc.getAddress());
|
||||
if (obj.containsKey("nonce") && !((String)obj.get("nonce")).equals("")) {
|
||||
nonce = jsToBigInteger((String) obj.get("nonce"));
|
||||
}
|
||||
|
||||
// default - from ethereumj-studio
|
||||
byte[] data = new byte[]{};
|
||||
if (obj.containsKey("data") && !((String)obj.get("data")).equals("")) {
|
||||
data = jsToAddress((String) obj.get("data"));
|
||||
}
|
||||
|
||||
Transaction tx = ethereum.createTransaction(nonce, gasPrice, gas, to, value, data);
|
||||
|
||||
tx.sign(senderPrivKey);
|
||||
|
||||
return tx;
|
||||
}
|
||||
|
||||
protected JSONObject blockToJS (Block block, Boolean detailed) {
|
||||
JSONObject res = new JSONObject();
|
||||
if (block == null)
|
||||
return null;
|
||||
|
||||
res.put("number", "0x" + Long.toHexString(block.getNumber()));
|
||||
|
||||
res.put("hash", "0x" + Hex.toHexString(block.getHash()));
|
||||
|
||||
res.put("parentHash", "0x" + Hex.toHexString(block.getParentHash()));
|
||||
|
||||
res.put("nonce", "0x" + Hex.toHexString(block.getNonce()));
|
||||
|
||||
res.put("sha3Uncles", "0x" + Hex.toHexString(block.getUnclesHash()));
|
||||
|
||||
res.put("logsBloom", "0x" + Hex.toHexString(block.getLogBloom()));
|
||||
|
||||
res.put("transactionsRoot", "0x" + Hex.toHexString(block.getHeader().getTxTrieRoot()));
|
||||
|
||||
res.put("stateRoot", "0x" + Hex.toHexString(block.getStateRoot()));
|
||||
|
||||
res.put("miner", "0x" + Hex.toHexString(block.getCoinbase()));
|
||||
|
||||
res.put("difficulty", "0x" + block.getDifficultyBI().toString(16));
|
||||
|
||||
res.put("totalDifficulty", "0x" + block.getCumulativeDifficulty().toString(16));
|
||||
|
||||
res.put("extraData", "0x" + Hex.toHexString(block.getExtraData()));
|
||||
|
||||
// No way to get size of block in bytes, so I try calculate it using formula from getEncoded
|
||||
byte[] header = block.getHeader().getEncoded();
|
||||
byte[] transactions = RLP.encodeList();
|
||||
byte[][] unclesEncoded = new byte[block.getUncleList().size()][];
|
||||
int i = 0;
|
||||
for (BlockHeader uncle : block.getUncleList()) {
|
||||
unclesEncoded[i] = uncle.getEncoded();
|
||||
++i;
|
||||
}
|
||||
byte[] uncles = RLP.encodeList(unclesEncoded);
|
||||
byte[] rlpEncoded = RLP.encodeList(header, transactions, uncles);
|
||||
res.put("size", "0x" + Integer.toHexString(rlpEncoded.length));
|
||||
|
||||
res.put("gasLimit", "0x" + Long.toHexString(block.getGasLimit()));
|
||||
|
||||
res.put("gasUsed", "0x" + Long.toHexString(block.getGasUsed()));
|
||||
|
||||
res.put("timestamp", "0x" + Long.toHexString(block.getTimestamp()));
|
||||
|
||||
JSONArray transactionsJA = new JSONArray();
|
||||
i = 0;
|
||||
for (Transaction transaction : block.getTransactionsList()) {
|
||||
if (detailed) {
|
||||
JSONObject tx = transactionToJS(transaction);
|
||||
tx.put("transactionIndex", "0x" + Integer.toHexString(i));
|
||||
tx.put("blockHash", "0x" + Hex.toHexString(block.getHash()));
|
||||
tx.put("blockNumber", "0x" + Long.toHexString(block.getNumber()));
|
||||
transactionsJA.add(tx);
|
||||
} else {
|
||||
transactionsJA.add("0x" + Hex.toHexString(transaction.getHash()));
|
||||
}
|
||||
++i;
|
||||
}
|
||||
res.put("transactions", transactionsJA);
|
||||
|
||||
//TODO: ask if I correctly get uncle's hash (takes form -core right now)
|
||||
JSONArray unclesJA = new JSONArray();
|
||||
for (BlockHeader uncle : block.getUncleList()) {
|
||||
unclesJA.add("0x" + Hex.toHexString(HashUtil.sha3(uncle.getEncoded())));
|
||||
}
|
||||
res.put("uncles", unclesJA);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
protected JSONObject transactionToJS (Transaction transaction) {
|
||||
JSONObject res = new JSONObject();
|
||||
|
||||
res.put("hash", "0x" + Hex.toHexString(transaction.getHash()));
|
||||
|
||||
res.put("nonce", "0x" + Hex.toHexString(transaction.getNonce()));
|
||||
|
||||
res.put("from", "0x" + Hex.toHexString(transaction.getSender()));
|
||||
|
||||
res.put("to", "0x" + Hex.toHexString(transaction.getReceiveAddress()));
|
||||
|
||||
res.put("value", "0x" + Hex.toHexString(transaction.getValue()));
|
||||
|
||||
res.put("gasPrice", "0x" + Hex.toHexString(transaction.getGasPrice()));
|
||||
|
||||
res.put("gas", "0x" + Hex.toHexString(transaction.getGasLimit()));
|
||||
|
||||
res.put("input", "0x" + Hex.toHexString(transaction.getData()));
|
||||
|
||||
/*
|
||||
No way to get this data from inside of transaction.
|
||||
TODO: Ask roman to include it into transaction class.
|
||||
res.put("transactionIndex", "0x" + "");
|
||||
res.put("blockHash", "0x" + "");
|
||||
res.put("blockNumber", "0x" + "");
|
||||
*/
|
||||
return res;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package org.ethereum.android.jsonrpc.filter;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
public abstract class FilterBase {
|
||||
protected int id;
|
||||
protected long lastRequest = System.currentTimeMillis();
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public long getLastRequestTime() {
|
||||
return lastRequest;
|
||||
}
|
||||
|
||||
protected void updateLastRequest() {
|
||||
lastRequest = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public abstract void processEvent(Object data);
|
||||
public abstract JSONArray toJS();
|
||||
public abstract JSONArray toJS(Ethereum ethereum);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package org.ethereum.android.jsonrpc.filter;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class FilterBlock extends FilterBase {
|
||||
|
||||
private ArrayList<String> blocks = new ArrayList<String>();
|
||||
|
||||
public void processEvent(Object data) {
|
||||
if (data instanceof Block) {
|
||||
synchronized (blocks) {
|
||||
blocks.add("0x" + Hex.toHexString(((Block) data).getHash()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JSONArray toJS() {
|
||||
updateLastRequest();
|
||||
JSONArray res = new JSONArray();
|
||||
synchronized (blocks) {
|
||||
for(String item : blocks) {
|
||||
res.add(item);
|
||||
}
|
||||
blocks.clear();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public JSONArray toJS(Ethereum ethereum) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
package org.ethereum.android.jsonrpc.filter;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
import net.minidev.json.JSONObject;
|
||||
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.core.TransactionReceipt;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.vm.DataWord;
|
||||
import org.ethereum.vm.LogInfo;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
/*
|
||||
Right now LogInfo not contains information about Transaction and Transaction not have information about block.
|
||||
TODO: talk to Roman about create links between LogInfo and Transaction and between Transaction and Block.
|
||||
*/
|
||||
public class FilterLog extends FilterBase {
|
||||
|
||||
private ArrayList<LogInfo> logs = new ArrayList<LogInfo>();
|
||||
|
||||
long blockFrom;
|
||||
long blockTo;
|
||||
ArrayList<byte[]> addresses = new ArrayList<>();
|
||||
ArrayList<byte[]> topics = new ArrayList<>();
|
||||
|
||||
public FilterLog (Ethereum ethereum, JSONObject data) {
|
||||
blockFrom = ethereum.getBlockchain().getBestBlock().getNumber();
|
||||
if (data.containsKey("fromBlock") && !((String)data.get("fromBlock")).equals("")) {
|
||||
String fromS = (String)data.get("fromBlock");
|
||||
if (fromS.equals("latest")) {
|
||||
} else if (fromS.equals("pending") || fromS.equals("earliest")) {
|
||||
blockFrom = -1;
|
||||
} else {
|
||||
blockFrom = Long.parseLong(fromS.substring(2), 16);
|
||||
}
|
||||
}
|
||||
|
||||
blockTo = ethereum.getBlockchain().getBestBlock().getNumber();
|
||||
if (data.containsKey("toBlock") && !((String)data.get("toBlock")).equals("")) {
|
||||
String fromS = (String)data.get("toBlock");
|
||||
if (fromS.equals("latest")) {
|
||||
} else if (fromS.equals("pending") || fromS.equals("earliest")) {
|
||||
blockTo = -1;
|
||||
} else {
|
||||
blockTo = Long.parseLong(fromS.substring(2), 16);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.containsKey("address")) {
|
||||
if (data.get("address") instanceof String) {
|
||||
addresses.add(Hex.decode(((String) data.get("address")).substring(2)));
|
||||
} else if (data.get("address") instanceof JSONArray){
|
||||
for (Object item : (JSONArray)data.get("address")) {
|
||||
if (item instanceof String) {
|
||||
addresses.add(Hex.decode(((String) item).substring(2)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data.containsKey("topics")) {
|
||||
if (data.get("topics") instanceof String) {
|
||||
topics.add(Hex.decode(((String) data.get("topics")).substring(2)));
|
||||
} else if (data.get("topics") instanceof JSONArray){
|
||||
for (Object item : (JSONArray)data.get("topics")) {
|
||||
if (item instanceof String) {
|
||||
topics.add(Hex.decode(((String) item).substring(2)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: Right now Bloom from -core can be used only to check total mach of 2 same class objects. Will be nice to have possibility to check contains.
|
||||
*/
|
||||
public void processEvent(Object data) {
|
||||
if (data instanceof LogInfo) {
|
||||
synchronized (logs) {
|
||||
LogInfo li = (LogInfo)data;
|
||||
//TODO: check if li inside blockFrom - blockTo
|
||||
|
||||
if (checkLogInfo(li))
|
||||
logs.add(li);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JSONArray toJS() {
|
||||
updateLastRequest();
|
||||
JSONArray res = new JSONArray();
|
||||
synchronized (logs) {
|
||||
for(LogInfo item : logs) {
|
||||
res.add(logInfoToJS(item));
|
||||
}
|
||||
logs.clear();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public JSONArray toJS(Ethereum ethereum) {
|
||||
JSONArray res = new JSONArray();
|
||||
|
||||
// Process mined blocks
|
||||
if (blockFrom >= 0) {
|
||||
long i = blockFrom;
|
||||
while (true) {
|
||||
Block block = ethereum.getBlockchain().getBlockByNumber(i);
|
||||
if (block == null)
|
||||
break;
|
||||
for (Transaction tx : block.getTransactionsList()) {
|
||||
TransactionReceipt txr = ethereum.getBlockchain().getTransactionReceiptByHash(tx.getHash());
|
||||
if (txr != null) {
|
||||
for (LogInfo li : txr.getLogInfoList()) {
|
||||
if (checkLogInfo(li))
|
||||
res.add(logInfoToJS(li));
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Process pending transactions. But not sure if BlockChain can return TransactionReceipt for pending transaction.
|
||||
*/
|
||||
if (blockFrom < 0 || blockTo < 0) {
|
||||
for (Transaction tx : ethereum.getPendingTransactions()) {
|
||||
TransactionReceipt txr = ethereum.getBlockchain().getTransactionReceiptByHash(tx.getHash());
|
||||
if (txr != null) {
|
||||
for (LogInfo li : txr.getLogInfoList()) {
|
||||
if (checkLogInfo(li))
|
||||
res.add(logInfoToJS(li));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
private boolean checkLogInfo(LogInfo li) {
|
||||
boolean found = false;
|
||||
for (byte[] address : addresses) {
|
||||
if (Arrays.equals(address, li.getAddress())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
return false;
|
||||
|
||||
found = false;
|
||||
for (byte[] topic : topics) {
|
||||
for (DataWord litopic : li.getTopics()) {
|
||||
if (Arrays.equals(topic, litopic.getData())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private JSONObject logInfoToJS(LogInfo li) {
|
||||
JSONObject res = new JSONObject();
|
||||
|
||||
/*
|
||||
TODO: check here if log's transaction / block mined or pending.
|
||||
*/
|
||||
res.put("type", "pending");
|
||||
res.put("logIndex", null);
|
||||
res.put("transactionIndex", null);
|
||||
res.put("transactionHash", null);
|
||||
res.put("blockHash", null);
|
||||
res.put("blockNumber", null);
|
||||
|
||||
res.put("address", Hex.toHexString(li.getAddress()));
|
||||
|
||||
res.put("data", Hex.toHexString(li.getData()));
|
||||
|
||||
JSONArray topics = new JSONArray();
|
||||
for (DataWord topic : li.getTopics()) {
|
||||
topics.add(Hex.toHexString(topic.getData()));
|
||||
}
|
||||
res.put("topics", topics);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package org.ethereum.android.jsonrpc.filter;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/*
|
||||
This class must receive notification from -core about new log, Block, Transaction. Right now I not see the way todo that.
|
||||
TODO: ask advice from Roman about how to send notification to this class.
|
||||
*/
|
||||
public class FilterManager {
|
||||
|
||||
protected static FilterManager instance = null;
|
||||
|
||||
public static FilterManager getInstance() {
|
||||
if (instance == null)
|
||||
instance = new FilterManager();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private Timer timer = null;
|
||||
private long filterAutoUninstall = TimeUnit.MINUTES.toMillis(5);
|
||||
|
||||
protected Hashtable<Integer, FilterBase> filters;
|
||||
protected int last_id = 0;
|
||||
|
||||
private FilterManager() {
|
||||
filters = new Hashtable<Integer, FilterBase>();
|
||||
|
||||
timer = new Timer();
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
long now = System.currentTimeMillis();
|
||||
synchronized (filters) {
|
||||
for (Map.Entry<Integer, FilterBase> item : filters.entrySet()) {
|
||||
if (now - item.getValue().getLastRequestTime() >= filterAutoUninstall) {
|
||||
filters.remove(item.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, TimeUnit.MINUTES.toMillis(1));
|
||||
}
|
||||
|
||||
public void processEvent(Object data) {
|
||||
synchronized (filters) {
|
||||
for (Map.Entry<Integer, FilterBase> item : filters.entrySet()) {
|
||||
item.getValue().processEvent(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int addFilter(FilterBase filter) {
|
||||
filter.setId(++last_id);
|
||||
filters.put(filter.getId(), filter);
|
||||
return filter.getId();
|
||||
}
|
||||
|
||||
public FilterBase getFilter(int id) {
|
||||
if (filters.containsKey(id)) {
|
||||
return filters.get(id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean uninstallFilter(int id) {
|
||||
synchronized (filters) {
|
||||
if (!filters.containsKey(id))
|
||||
return false;
|
||||
filters.remove(id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public JSONArray toJS(int id) {
|
||||
synchronized (filters) {
|
||||
if (!filters.containsKey(id))
|
||||
return null;
|
||||
return filters.get(id).toJS();
|
||||
}
|
||||
}
|
||||
|
||||
public JSONArray toJS(int id, Ethereum ethereum) {
|
||||
synchronized (filters) {
|
||||
if (!filters.containsKey(id))
|
||||
return null;
|
||||
return filters.get(id).toJS(ethereum);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package org.ethereum.android.jsonrpc.filter;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class FilterTransaction extends FilterBase {
|
||||
|
||||
private ArrayList<String> transactions = new ArrayList<String>();
|
||||
|
||||
public void processEvent(Object data) {
|
||||
if (data instanceof Transaction) {
|
||||
synchronized (transactions) {
|
||||
transactions.add("0x" + Hex.toHexString(((Transaction) data).getHash()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JSONArray toJS() {
|
||||
updateLastRequest();
|
||||
JSONArray res = new JSONArray();
|
||||
synchronized (transactions) {
|
||||
for(String item : transactions) {
|
||||
res.add(item);
|
||||
}
|
||||
transactions.clear();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public JSONArray toJS(Ethereum ethereum) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
||||
Deprecated
|
||||
*/
|
||||
public class db_getHex extends JsonRpcServerMethod {
|
||||
|
||||
public db_getHex (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
return res;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
||||
Deprecated
|
||||
*/
|
||||
public class db_getString extends JsonRpcServerMethod {
|
||||
|
||||
public db_getString (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
return res;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
||||
Deprecated
|
||||
*/
|
||||
public class db_putHex extends JsonRpcServerMethod {
|
||||
|
||||
public db_putHex (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
return res;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
||||
Deprecated
|
||||
*/
|
||||
public class db_putString extends JsonRpcServerMethod {
|
||||
|
||||
public db_putString (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
return res;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.vm.Program;
|
||||
import org.ethereum.vm.VM;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
It's magic here, not sure if -core have this possibility at all. I found this in test and studio. But not sure that getHReturn it's what specification mean.
|
||||
TODO: get advice from Roman
|
||||
*/
|
||||
public class eth_call extends JsonRpcServerMethod {
|
||||
|
||||
public eth_call (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 2) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
JSONObject obj = (JSONObject)params.get(0);
|
||||
Transaction tx;
|
||||
try {
|
||||
tx = jsToTransaction(obj);
|
||||
} catch (Exception e) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
}
|
||||
|
||||
String height = (String)params.get(1);
|
||||
long blockNumber = getBlockNumber(height);
|
||||
byte[] root = ethereum.getBlockchain().getBestBlock().getStateRoot();
|
||||
|
||||
if (blockNumber >= 0) {
|
||||
ethereum.getRepository().syncToRoot(ethereum.getBlockchain().getBlockByNumber(blockNumber).getStateRoot());
|
||||
}
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(tx.getData(), null);
|
||||
vm.play(program);
|
||||
byte[] result = program.getResult().getHReturn();
|
||||
|
||||
if (blockNumber >= 0) {
|
||||
ethereum.getRepository().syncToRoot(root);
|
||||
}
|
||||
|
||||
String tmp = "0x" + Hex.toHexString(result);
|
||||
JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: -core not have lll compiler
|
||||
*/
|
||||
public class eth_compileLLL extends JsonRpcServerMethod {
|
||||
|
||||
public eth_compileLLL (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
String code = (String)params.get(0);
|
||||
|
||||
return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.serpent.SerpentCompiler;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/*
|
||||
Example taken from -studio. Not sure if we must call encodeMachineCodeForVMRun in end
|
||||
TODO: get advice from Roman about encodeMachineCodeForVMRun
|
||||
*/
|
||||
public class eth_compileSerpent extends JsonRpcServerMethod {
|
||||
|
||||
public eth_compileSerpent (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
String code = (String)params.get(0);
|
||||
String asmResult = "";
|
||||
byte[] machineCode = null;
|
||||
|
||||
try {
|
||||
Pattern pattern = Pattern.compile("(.*?)init:(.*?)code:(.*?)", Pattern.DOTALL);
|
||||
Matcher matcher = pattern.matcher(code);
|
||||
if (matcher.find()) {
|
||||
asmResult = SerpentCompiler.compileFullNotion(code);
|
||||
machineCode = SerpentCompiler.compileFullNotionAssemblyToMachine(asmResult);
|
||||
} else {
|
||||
asmResult = SerpentCompiler.compile(code);
|
||||
machineCode = SerpentCompiler.compileAssemblyToMachine(asmResult);
|
||||
// machineCode = SerpentCompiler.encodeMachineCodeForVMRun(machineCode, null);
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INTERNAL_ERROR, req.getID());
|
||||
}
|
||||
|
||||
|
||||
return new JSONRPC2Response("0x" + Hex.toHexString(machineCode), req.getID());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: -core not have solidity compiler
|
||||
*/
|
||||
public class eth_compileSolidity extends JsonRpcServerMethod {
|
||||
|
||||
public eth_compileSolidity (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
String code = (String)params.get(0);
|
||||
|
||||
return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.vm.Program;
|
||||
import org.ethereum.vm.VM;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
It's magic here, not sure if -core have this possibility at all. I found this in test and studio. But not sure that getHReturn it's what specification mean.
|
||||
TODO: get advice from Roman
|
||||
*/
|
||||
public class eth_estimateGas extends JsonRpcServerMethod {
|
||||
|
||||
public eth_estimateGas (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 2) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
JSONObject obj = (JSONObject)params.get(0);
|
||||
Transaction tx;
|
||||
try {
|
||||
tx = jsToTransaction(obj);
|
||||
} catch (Exception e) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
}
|
||||
|
||||
String height = (String)params.get(1);
|
||||
long blockNumber = getBlockNumber(height);
|
||||
byte[] root = ethereum.getBlockchain().getBestBlock().getStateRoot();
|
||||
|
||||
if (blockNumber >= 0) {
|
||||
ethereum.getRepository().syncToRoot(ethereum.getBlockchain().getBlockByNumber(blockNumber).getStateRoot());
|
||||
}
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(tx.getData(), null);
|
||||
vm.play(program);
|
||||
long result = program.getResult().getGasUsed();
|
||||
|
||||
if (blockNumber >= 0) {
|
||||
ethereum.getRepository().syncToRoot(root);
|
||||
}
|
||||
|
||||
String tmp = "0x" + Long.toHexString(result);
|
||||
JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
By specification this method can receive hash of pending block but from -core it's not possible.
|
||||
TODO: get advice from Roman about pending block
|
||||
*/
|
||||
public class eth_getBlockByHash extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getBlockByHash (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 2) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
byte[] address = jsToAddress((String) params.get(0));
|
||||
Boolean detailed = (Boolean)params.get(1);
|
||||
|
||||
Block block = ethereum.getBlockchain().getBlockByHash(address);
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(blockToJS(block, detailed), req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
By specification this method can receive number of pending block but from -core it's not possible.
|
||||
TODO: get advice from Roman about pending block
|
||||
*/
|
||||
public class eth_getBlockByNumber extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getBlockByNumber (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 2) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
String height = (String)params.get(0);
|
||||
long blockNumber = getBlockNumber(height);
|
||||
Boolean detailed = (Boolean)params.get(1);
|
||||
|
||||
if (blockNumber == -1) {
|
||||
blockNumber = ethereum.getBlockchain().getBestBlock().getNumber();
|
||||
}
|
||||
// TODO: here we must load pending block but -core not "group" it.
|
||||
if (blockNumber == -2) {
|
||||
}
|
||||
|
||||
Block block = ethereum.getBlockchain().getBlockByNumber(blockNumber);
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(blockToJS(block, detailed), req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/*
|
||||
As I see right now -core have only serpent compiler
|
||||
*/
|
||||
public class eth_getCompilers extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getCompilers (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
ArrayList<String> tmp = new ArrayList<String>();
|
||||
tmp.add("serpent");
|
||||
//TODO: add lll and solidity when they will be implemented in -core
|
||||
JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID());
|
||||
return res;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterBase;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
||||
public class eth_getFilterChanges extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getFilterChanges (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
int id = jsToInt((String) params.get(0));
|
||||
JSONRPC2Response res = new JSONRPC2Response(FilterManager.getInstance().toJS(id), req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterBase;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
||||
public class eth_getFilterLogs extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getFilterLogs (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
int id = jsToInt((String) params.get(0));
|
||||
JSONRPC2Response res = new JSONRPC2Response(FilterManager.getInstance().toJS(id, ethereum), req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
||||
public class eth_getLogs extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getLogs (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
JSONObject obj = (JSONObject)params.get(0);
|
||||
JSONRPC2Response res = new JSONRPC2Response((new FilterLog(ethereum, obj)).toJS(ethereum), req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
|
||||
import net.minidev.json.JSONObject;
|
||||
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
public class eth_getTransactionByBlockHashAndIndex extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getTransactionByBlockHashAndIndex (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 2) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
byte[] address = jsToAddress((String) params.get(0));
|
||||
int index = jsToInt((String) params.get(1));
|
||||
|
||||
Block block = ethereum.getBlockchain().getBlockByHash(address);
|
||||
|
||||
if (block == null)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
if (block.getTransactionsList().size() <= index)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
JSONObject tx = transactionToJS(block.getTransactionsList().get(index));
|
||||
tx.put("transactionIndex", "0x" + Integer.toHexString(index));
|
||||
tx.put("blockHash", "0x" + Hex.toHexString(block.getHash()));
|
||||
tx.put("blockNumber", "0x" + Long.toHexString(block.getNumber()));
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(tx, req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
|
||||
import net.minidev.json.JSONObject;
|
||||
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
public class eth_getTransactionByBlockNumberAndIndex extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getTransactionByBlockNumberAndIndex (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 2) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
String height = (String)params.get(0);
|
||||
long blockNumber = getBlockNumber(height);
|
||||
int index = jsToInt((String) params.get(1));
|
||||
|
||||
if (blockNumber == -1) {
|
||||
blockNumber = ethereum.getBlockchain().getBestBlock().getNumber();
|
||||
}
|
||||
// TODO: here we must load pending block but -core not "group" it.
|
||||
if (blockNumber == -2) {
|
||||
}
|
||||
|
||||
Block block = ethereum.getBlockchain().getBlockByNumber(blockNumber);
|
||||
|
||||
if (block == null)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
if (block.getTransactionsList().size() <= index)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
JSONObject tx = transactionToJS(block.getTransactionsList().get(index));
|
||||
tx.put("transactionIndex", "0x" + Integer.toHexString(index));
|
||||
tx.put("blockHash", "0x" + Hex.toHexString(block.getHash()));
|
||||
tx.put("blockNumber", "0x" + Long.toHexString(block.getNumber()));
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(tx, req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.core.TransactionReceipt;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: get advice from Roman about get block from transaction.
|
||||
*/
|
||||
public class eth_getTransactionByHash extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getTransactionByHash (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
byte[] address = jsToAddress((String) params.get(0));
|
||||
|
||||
TransactionReceipt transaction = ethereum.getBlockchain().getTransactionReceiptByHash(address);
|
||||
|
||||
if (transaction == null)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(transactionToJS(transaction.getTransaction()), req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
||||
public class eth_getUncleByBlockHashAndIndex extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getUncleByBlockHashAndIndex (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 2) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
byte[] address = jsToAddress((String) params.get(0));
|
||||
int index = jsToInt((String) params.get(1));
|
||||
|
||||
Block block = ethereum.getBlockchain().getBlockByHash(address);
|
||||
|
||||
if (block == null)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
if (block.getUncleList().size() <= index)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
Block uncle = ethereum.getBlockchain().getBlockByHash(HashUtil.sha3(block.getUncleList().get(index).getEncoded()));
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(blockToJS(uncle, false), req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
||||
public class eth_getUncleByBlockNumberAndIndex extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getUncleByBlockNumberAndIndex (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 2) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
String height = (String)params.get(0);
|
||||
long blockNumber = getBlockNumber(height);
|
||||
int index = jsToInt((String) params.get(1));
|
||||
|
||||
if (blockNumber == -1) {
|
||||
blockNumber = ethereum.getBlockchain().getBestBlock().getNumber();
|
||||
}
|
||||
// TODO: here we must load pending block but -core not "group" it.
|
||||
if (blockNumber == -2) {
|
||||
}
|
||||
|
||||
Block block = ethereum.getBlockchain().getBlockByNumber(blockNumber);
|
||||
|
||||
if (block == null)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
if (block.getUncleList().size() <= index)
|
||||
return new JSONRPC2Response(null, req.getID());
|
||||
|
||||
Block uncle = ethereum.getBlockchain().getBlockByHash(HashUtil.sha3(block.getUncleList().get(index).getEncoded()));
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(blockToJS(uncle, false), req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ public class eth_getUncleCountByBlockNumber extends JsonRpcServerMethod {
|
|||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
String height = (String)params.get(1);
|
||||
String height = (String)params.get(0);
|
||||
|
||||
long blockNumber = getBlockNumber(height);
|
||||
if (blockNumber == -1)
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
||||
TODO: right now -core not auto start mining so no way to get information about state
|
||||
*/
|
||||
public class eth_getWork extends JsonRpcServerMethod {
|
||||
|
||||
public eth_getWork (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
return res;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterBlock;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
public class eth_newBlockFilter extends JsonRpcServerMethod {
|
||||
|
||||
public eth_newBlockFilter (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
int id = FilterManager.getInstance().addFilter(new FilterBlock());
|
||||
String tmp = "0x" + Integer.toHexString(id);
|
||||
JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID());
|
||||
return res;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
||||
public class eth_newFilter extends JsonRpcServerMethod {
|
||||
|
||||
public eth_newFilter (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
JSONObject obj = (JSONObject)params.get(0);
|
||||
int id = FilterManager.getInstance().addFilter(new FilterLog(ethereum, obj));
|
||||
String tmp = "0x" + Integer.toHexString(id);
|
||||
JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterBlock;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterTransaction;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
public class eth_newPendingTransactionFilter extends JsonRpcServerMethod {
|
||||
|
||||
public eth_newPendingTransactionFilter (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
int id = FilterManager.getInstance().addFilter(new FilterTransaction());
|
||||
String tmp = "0x" + Integer.toHexString(id);
|
||||
JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID());
|
||||
return res;
|
||||
|
||||
}
|
||||
}
|
|
@ -32,67 +32,13 @@ public class eth_sendTransaction extends JsonRpcServerMethod {
|
|||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
JSONObject obj = (JSONObject)params.get(0);
|
||||
if (!obj.containsKey("from") || (!obj.containsKey("to") && !obj.containsKey("data"))) {
|
||||
Transaction tx;
|
||||
try {
|
||||
tx = jsToTransaction(obj);
|
||||
} catch (Exception e) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
}
|
||||
|
||||
byte[] from = jsToAddress((String)obj.get("from"));
|
||||
Account acc = null;
|
||||
for (Account ac : ethereum.getWallet().getAccountCollection()) {
|
||||
if (Arrays.equals(ac.getAddress(), from)) {
|
||||
acc = ac;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (acc == null) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INTERNAL_ERROR, req.getID());
|
||||
}
|
||||
|
||||
byte[] senderPrivKey = acc.getEcKey().getPrivKeyBytes();
|
||||
|
||||
// default - from ethereumj-studio
|
||||
byte[] to = null;
|
||||
if (obj.containsKey("to") && !((String)obj.get("to")).equals("")) {
|
||||
to = jsToAddress((String) obj.get("to"));
|
||||
}
|
||||
|
||||
// default - from ethereumj-studio
|
||||
BigInteger gasPrice = SZABO.value().multiply(BigInteger.TEN);
|
||||
if (obj.containsKey("gasPrice") && !((String)obj.get("gasPrice")).equals("")) {
|
||||
gasPrice = jsToBigInteger((String) obj.get("gasPrice"));
|
||||
}
|
||||
|
||||
// default - from cpp-ethereum
|
||||
BigInteger gas = acc.getBalance().divide(gasPrice);
|
||||
BigInteger gasBBLimit = new BigInteger(Long.toString(ethereum.getBlockchain().getBestBlock().getGasLimit() / 5));
|
||||
if (gasBBLimit.compareTo(gas) < 0)
|
||||
gas = gasBBLimit;
|
||||
if (obj.containsKey("gas") && !((String)obj.get("gas")).equals("")) {
|
||||
gas = jsToBigInteger((String) obj.get("gas"));
|
||||
}
|
||||
|
||||
// default - from ethereumj-studio
|
||||
BigInteger value = new BigInteger("1000");
|
||||
if (obj.containsKey("value") && !((String)obj.get("value")).equals("")) {
|
||||
value = jsToBigInteger((String) obj.get("value"));
|
||||
}
|
||||
|
||||
// default - from ethereumj-studio
|
||||
BigInteger nonce = ethereum.getRepository().getNonce(acc.getAddress());
|
||||
if (obj.containsKey("nonce") && !((String)obj.get("nonce")).equals("")) {
|
||||
nonce = jsToBigInteger((String) obj.get("nonce"));
|
||||
}
|
||||
|
||||
// default - from ethereumj-studio
|
||||
byte[] data = new byte[]{};
|
||||
if (obj.containsKey("data") && !((String)obj.get("data")).equals("")) {
|
||||
data = jsToAddress((String) obj.get("data"));
|
||||
}
|
||||
|
||||
Transaction tx = ethereum.createTransaction(nonce, gasPrice, gas, to, value, data);
|
||||
|
||||
tx.sign(senderPrivKey);
|
||||
|
||||
try {
|
||||
ethereum.submitTransaction(tx).get(CONFIG.transactionApproveTimeout(), TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: right now -core not auto start mining so no way to get information about state
|
||||
*/
|
||||
public class eth_submitWork extends JsonRpcServerMethod {
|
||||
|
||||
public eth_submitWork (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 3) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
byte[] nonce = jsToAddress((String) params.get(0));
|
||||
byte[] powHash = jsToAddress((String) params.get(1));
|
||||
byte[] mixDigest = jsToAddress((String) params.get(2));
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import net.minidev.json.JSONObject;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterBase;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterLog;
|
||||
import org.ethereum.android.jsonrpc.filter.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import java.util.List;
|
||||
|
||||
public class eth_uninstallFilter extends JsonRpcServerMethod {
|
||||
|
||||
public eth_uninstallFilter (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
int id = jsToInt((String) params.get(0));
|
||||
JSONRPC2Response res = new JSONRPC2Response(FilterManager.getInstance().uninstallFilter(id), req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: not present clear specification for this method, also cpp and go version not provide it.
|
||||
*/
|
||||
public class shh_addToGroup extends JsonRpcServerMethod {
|
||||
|
||||
public shh_addToGroup(Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
byte[] identity = jsToAddress((String)params.get(0));
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.whisper.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: done it when shh will be ready in -core
|
||||
*/
|
||||
public class shh_getFilterChanges extends JsonRpcServerMethod {
|
||||
|
||||
public shh_getFilterChanges(Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
int id = jsToInt((String)params.get(0));
|
||||
JSONRPC2Response res = new JSONRPC2Response(FilterManager.getInstance().toJS(id), req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.whisper.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: done it when shh will be ready in -core
|
||||
*/
|
||||
public class shh_getMessages extends JsonRpcServerMethod {
|
||||
|
||||
public shh_getMessages(Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
int id = jsToInt((String)params.get(0));
|
||||
JSONRPC2Response res = new JSONRPC2Response(FilterManager.getInstance().toJSAll(id), req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: done it when shh will be ready in -core
|
||||
*/
|
||||
public class shh_hasIdentity extends JsonRpcServerMethod {
|
||||
|
||||
public shh_hasIdentity(Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
byte[] identity = jsToAddress((String)params.get(0));
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
|
||||
import net.minidev.json.JSONObject;
|
||||
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.whisper.Filter;
|
||||
import org.ethereum.android.jsonrpc.whisper.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: done it when shh will be ready in -core
|
||||
*/
|
||||
public class shh_newFilter extends JsonRpcServerMethod {
|
||||
|
||||
public shh_newFilter(Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
JSONObject obj = (JSONObject)params.get(0);
|
||||
int id = FilterManager.getInstance().addFilter(new Filter(obj));
|
||||
String tmp = "0x" + Integer.toHexString(id);
|
||||
JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
||||
TODO: not present clear specification for this method, also cpp and go version not provide it.
|
||||
*/
|
||||
public class shh_newGroup extends JsonRpcServerMethod {
|
||||
|
||||
public shh_newGroup(Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
return res;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
/*
|
||||
TODO: done it when shh will be ready in -core
|
||||
*/
|
||||
public class shh_newIdentity extends JsonRpcServerMethod {
|
||||
|
||||
public shh_newIdentity(Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
return res;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
import net.minidev.json.JSONObject;
|
||||
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: done it when shh will be ready in -core
|
||||
*/
|
||||
public class shh_post extends JsonRpcServerMethod {
|
||||
|
||||
public shh_post (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
JSONObject obj = (JSONObject)params.get(0);
|
||||
|
||||
byte[] from = null;
|
||||
if (obj.containsKey("from"))
|
||||
from = jsToAddress((String)obj.get("from"));
|
||||
|
||||
byte[] to = null;
|
||||
if (obj.containsKey("to"))
|
||||
to = jsToAddress((String)obj.get("to"));
|
||||
|
||||
ArrayList<byte[]> topics = new ArrayList<>();
|
||||
for (Object item : (JSONArray)obj.get("topics")) {
|
||||
if (item instanceof String) {
|
||||
topics.add(jsToAddress((String)item));
|
||||
}
|
||||
}
|
||||
|
||||
byte[] payload = jsToAddress((String)obj.get("payload"));
|
||||
|
||||
int priority = jsToInt((String) obj.get("priority"));
|
||||
|
||||
int ttl = jsToInt((String)obj.get("ttl"));
|
||||
|
||||
//TODO:
|
||||
|
||||
JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID());
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.android.jsonrpc.whisper.FilterManager;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
TODO: done it when shh will be ready in -core
|
||||
*/
|
||||
public class shh_uninstallFilter extends JsonRpcServerMethod {
|
||||
|
||||
public shh_uninstallFilter(Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
List<Object> params = req.getPositionalParams();
|
||||
if (params.size() != 1) {
|
||||
return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID());
|
||||
} else {
|
||||
int id = jsToInt((String)params.get(0));
|
||||
JSONRPC2Response res = new JSONRPC2Response(FilterManager.getInstance().uninstallFilter(id), req.getID());
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.ethereum.android.jsonrpc.method;
|
||||
|
||||
import com.thetransactioncompany.jsonrpc2.*;
|
||||
import com.thetransactioncompany.jsonrpc2.server.*;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServerMethod;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.net.shh.ShhHandler;
|
||||
|
||||
public class shh_version extends JsonRpcServerMethod {
|
||||
|
||||
public shh_version (Ethereum ethereum) {
|
||||
super(ethereum);
|
||||
}
|
||||
|
||||
protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) {
|
||||
|
||||
String tmp = "" + ShhHandler.VERSION;
|
||||
JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID());
|
||||
return res;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package org.ethereum.android.jsonrpc.whisper;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
import net.minidev.json.JSONObject;
|
||||
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.net.shh.ShhMessage;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/*
|
||||
TODO: replace ShhMessage with real class when Roman finish Shh.
|
||||
*/
|
||||
public class Filter {
|
||||
protected int id;
|
||||
protected ArrayList<ShhMessage> messages;
|
||||
byte[] to = null;
|
||||
boolean isWildcard = false;
|
||||
ArrayList<ArrayList<byte[]>> or;
|
||||
ArrayList<byte[]> and;
|
||||
int sendID = 0;
|
||||
|
||||
public Filter (JSONObject data) {
|
||||
messages = new ArrayList<ShhMessage>();
|
||||
if (data.containsKey("to")) {
|
||||
to = Hex.decode(((String)data.get("to")).substring(2));
|
||||
}
|
||||
JSONArray topics = (JSONArray)data.get("topics");
|
||||
for (Object item : topics) {
|
||||
if (item == null) {
|
||||
isWildcard = true;
|
||||
}
|
||||
else if (item instanceof JSONArray) {
|
||||
ArrayList<byte[]> tmp = new ArrayList<byte[]>();
|
||||
for (Object ori : (JSONArray)item) {
|
||||
if (ori instanceof String) {
|
||||
tmp.add(Hex.decode(((String)ori).substring(2)));
|
||||
}
|
||||
}
|
||||
or.add(tmp);
|
||||
} else if (item instanceof String) {
|
||||
and.add(Hex.decode(((String)item).substring(2)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void processEvent(Object data) {
|
||||
//TODO: parse incomming data when we will know what comes.
|
||||
}
|
||||
|
||||
public JSONArray toJS() {
|
||||
JSONArray res = new JSONArray();
|
||||
synchronized (messages) {
|
||||
for (int i = sendID; i < messages.size(); i++) {
|
||||
res.add(toJS(messages.get(i)));
|
||||
}
|
||||
sendID = messages.size();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public JSONArray toJSAll() {
|
||||
JSONArray res = new JSONArray();
|
||||
synchronized (messages) {
|
||||
for (int i = 0; i < messages.size(); i++) {
|
||||
res.add(toJS(messages.get(i)));
|
||||
}
|
||||
sendID = messages.size();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private JSONObject toJS (ShhMessage data) {
|
||||
JSONObject res = new JSONObject();
|
||||
return res;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package org.ethereum.android.jsonrpc.whisper;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
|
||||
import org.ethereum.facade.Ethereum;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/*
|
||||
This class must receive notification from -core about new whisper message. Right now I not see the way todo that.
|
||||
TODO: ask advice from Roman about how to send notification to this class.
|
||||
*/
|
||||
public class FilterManager {
|
||||
|
||||
protected static FilterManager instance = null;
|
||||
|
||||
public static FilterManager getInstance() {
|
||||
if (instance == null)
|
||||
instance = new FilterManager();
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected Hashtable<Integer, Filter> filters;
|
||||
protected int last_id = 0;
|
||||
|
||||
private FilterManager() {
|
||||
filters = new Hashtable<Integer, Filter>();
|
||||
}
|
||||
|
||||
public void processEvent(Object data) {
|
||||
synchronized (filters) {
|
||||
for (Map.Entry<Integer, Filter> item : filters.entrySet()) {
|
||||
item.getValue().processEvent(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int addFilter(Filter filter) {
|
||||
filter.setId(++last_id);
|
||||
filters.put(filter.getId(), filter);
|
||||
return filter.getId();
|
||||
}
|
||||
|
||||
public Filter getFilter(int id) {
|
||||
if (filters.containsKey(id)) {
|
||||
return filters.get(id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean uninstallFilter(int id) {
|
||||
synchronized (filters) {
|
||||
if (!filters.containsKey(id))
|
||||
return false;
|
||||
filters.remove(id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public JSONArray toJS(int id) {
|
||||
synchronized (filters) {
|
||||
if (!filters.containsKey(id))
|
||||
return null;
|
||||
return filters.get(id).toJS();
|
||||
}
|
||||
}
|
||||
|
||||
public JSONArray toJSAll(int id) {
|
||||
synchronized (filters) {
|
||||
if (!filters.containsKey(id))
|
||||
return null;
|
||||
return filters.get(id).toJSAll();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue