From 34d98c9ea3f5697bacfa72dbae6bd166d98e6a05 Mon Sep 17 00:00:00 2001 From: Yaroslav Dmytrotsa Date: Fri, 12 Jun 2015 19:19:42 +0300 Subject: [PATCH] first 22 methods. they have a lot "questionable" points (marked in files). So please not push then in public git till I not clean up them with Roman (after implement all methods). --- .../android/jsonrpc/JsonRpcServer.java | 22 +++- .../android/jsonrpc/JsonRpcServerMethod.java | 77 +++++++++++++ .../android/jsonrpc/method/eth_accounts.java | 29 +++++ .../jsonrpc/method/eth_blockNumber.java | 25 ++++ .../android/jsonrpc/method/eth_coinbase.java | 34 +++--- .../android/jsonrpc/method/eth_gasPrice.java | 22 ++++ .../jsonrpc/method/eth_getBalance.java | 55 +++++++++ .../eth_getBlockTransactionCountByHash.java | 29 +++++ .../eth_getBlockTransactionCountByNumber.java | 40 +++++++ .../android/jsonrpc/method/eth_getCode.java | 48 ++++++++ .../jsonrpc/method/eth_getStorageAt.java | 49 ++++++++ .../method/eth_getTransactionCount.java | 66 +++++++++++ .../method/eth_getUncleCountByBlockHash.java | 29 +++++ .../eth_getUncleCountByBlockNumber.java | 44 +++++++ .../android/jsonrpc/method/eth_hashrate.java | 24 ++++ .../android/jsonrpc/method/eth_mining.java | 24 ++++ .../jsonrpc/method/eth_protocolVersion.java | 22 ++++ .../jsonrpc/method/eth_sendTransaction.java | 108 ++++++++++++++++++ .../android/jsonrpc/method/eth_sign.java | 53 +++++++++ .../android/jsonrpc/method/net_listening.java | 24 ++++ .../android/jsonrpc/method/net_peerCount.java | 31 +++++ .../android/jsonrpc/method/net_version.java | 23 ++++ .../jsonrpc/method/web3_clientVersion.java | 23 ++++ .../android/jsonrpc/method/web3_sha3.java | 32 ++++++ 24 files changed, 916 insertions(+), 17 deletions(-) create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServerMethod.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_accounts.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_blockNumber.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_gasPrice.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBalance.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockTransactionCountByHash.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockTransactionCountByNumber.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getCode.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getStorageAt.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionCount.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleCountByBlockHash.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleCountByBlockNumber.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_hashrate.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_mining.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_protocolVersion.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_sendTransaction.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_sign.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/net_listening.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/net_peerCount.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/net_version.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/web3_clientVersion.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/web3_sha3.java diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServer.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServer.java index 0c3cbceb..1d9dd968 100644 --- a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServer.java +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServer.java @@ -48,11 +48,31 @@ 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)); + this.dispatcher.register(new eth_hashrate(this.ethereum)); + this.dispatcher.register(new eth_gasPrice(this.ethereum)); + this.dispatcher.register(new eth_accounts(this.ethereum)); + this.dispatcher.register(new eth_blockNumber(this.ethereum)); + this.dispatcher.register(new eth_getBalance(this.ethereum)); + this.dispatcher.register(new eth_getStorageAt(this.ethereum)); + this.dispatcher.register(new eth_getTransactionCount(this.ethereum)); + this.dispatcher.register(new eth_getBlockTransactionCountByHash(this.ethereum)); + this.dispatcher.register(new eth_getBlockTransactionCountByNumber(this.ethereum)); + this.dispatcher.register(new eth_getUncleCountByBlockHash(this.ethereum)); + this.dispatcher.register(new eth_getUncleCountByBlockNumber(this.ethereum)); + this.dispatcher.register(new eth_getCode(this.ethereum)); + this.dispatcher.register(new eth_sign(this.ethereum)); + this.dispatcher.register(new eth_sendTransaction(this.ethereum)); } public void start() throws Exception { - EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServerMethod.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServerMethod.java new file mode 100644 index 00000000..d6e801cb --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServerMethod.java @@ -0,0 +1,77 @@ +package org.ethereum.android.jsonrpc; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; + +import org.ethereum.android.jsonrpc.JsonRpcServer; +import org.ethereum.core.Account; +import org.ethereum.core.AccountState; +import org.ethereum.core.Transaction; +import org.ethereum.facade.Ethereum; +import org.ethereum.vm.DataWord; +import org.spongycastle.util.encoders.Hex; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.List; + +public abstract class JsonRpcServerMethod implements RequestHandler { + + private String name = ""; + protected Ethereum ethereum; + + public JsonRpcServerMethod(Ethereum ethereum) { + this.ethereum = ethereum; + name = this.getClass().getSimpleName(); + } + + public String[] handledRequests() { + return new String[]{name}; + } + + public JSONRPC2Response process(JSONRPC2Request req, MessageContext ctx) { + if (req.getMethod().equals(name)) { + return worker(req, ctx); + } else { + return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); + } + } + + protected abstract JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx); + + protected long getBlockNumber(String height) { + long blockNumber = 0; + switch (height) { + case "earliest": + blockNumber = 0; + break; + case "latest": + blockNumber = -1; + break; + case "pending": + blockNumber = -2; + break; + default: + blockNumber = jsToLong(height); + } + if (blockNumber >= 0) + blockNumber = -1; + return blockNumber; + } + + protected byte[] jsToAddress(String data) { + return Hex.decode(data.substring(2)); + } + + protected int jsToInt(String data) { + return Integer.parseInt(data.substring(2), 16); + } + + protected long jsToLong(String data) { + return Long.parseLong(data.substring(2), 16); + } + + protected BigInteger jsToBigInteger(String data) { + return new BigInteger(data.substring(2), 16); + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_accounts.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_accounts.java new file mode 100644 index 00000000..c6676f25 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_accounts.java @@ -0,0 +1,29 @@ +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.core.*; +import org.spongycastle.util.encoders.Hex; +import java.util.ArrayList; +import java.util.Collection; + +public class eth_accounts extends JsonRpcServerMethod { + + public eth_accounts (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + Collection accounts = ethereum.getWallet().getAccountCollection(); + ArrayList tmp = new ArrayList(); + for (Account ac : accounts) { + tmp.add("0x" + Hex.toHexString(ac.getEcKey().getAddress())); + } + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_blockNumber.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_blockNumber.java new file mode 100644 index 00000000..9e1e0ca3 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_blockNumber.java @@ -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.facade.Ethereum; + +/* +No matter how long I wait on synchronization - all time got best block number = 0 +TODO: check this after Adrian finish db implementation. +*/ +public class eth_blockNumber extends JsonRpcServerMethod { + + public eth_blockNumber (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + String tmp = "0x" + Long.toHexString(ethereum.getBlockchain().getBestBlock().getNumber()); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_coinbase.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_coinbase.java index d1cea209..599bd821 100644 --- a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_coinbase.java +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_coinbase.java @@ -2,28 +2,30 @@ 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.core.*; +import org.spongycastle.util.encoders.Hex; -public class eth_coinbase implements RequestHandler { +/* +Present big issue - current ethereumj-core not have coinbase "functionality". +On each app start - it create 2 addresses: "cow", coinbase.secret ("monkey") --- WorldManager.java -> init +Also because not present mining functionality - no wat to identify what address will be coinbase (mining success payment place to) +TODO: change this after fix in ethereumj-core +*/ - private String name = ""; - private Ethereum ethereum; +public class eth_coinbase extends JsonRpcServerMethod { - public eth_coinbase(Ethereum ethereum) { - this.ethereum = ethereum; - name = this.getClass().getSimpleName(); + public eth_coinbase (Ethereum ethereum) { + super(ethereum); } - public String[] handledRequests() { - return new String[]{name}; - } + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + Wallet w = ethereum.getWallet(); + String tmp = "0x" + Hex.toHexString(((Account) w.getAccountCollection().toArray()[1]).getEcKey().getAddress()); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; - public JSONRPC2Response process(JSONRPC2Request req, MessageContext ctx) { - if (req.getMethod().equals(name)) { - //TODO: place business logic here - return null; - } else { - return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); - } } } \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_gasPrice.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_gasPrice.java new file mode 100644 index 00000000..c1dd481e --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_gasPrice.java @@ -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 static org.ethereum.core.Denomination.SZABO; + +public class eth_gasPrice extends JsonRpcServerMethod { + + public eth_gasPrice (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + String tmp = "0x" + Long.toHexString(10 * SZABO.longValue()); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBalance.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBalance.java new file mode 100644 index 00000000..a0359cfc --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBalance.java @@ -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.spongycastle.util.encoders.Hex; +import java.math.BigInteger; +import java.util.List; + +/* +TODO: ask roman advice for this method. +*/ +public class eth_getBalance extends JsonRpcServerMethod { + + public eth_getBalance (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 2) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] address = jsToAddress((String) params.get(0)); + 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()); + } + + BigInteger balance = ethereum.getRepository().getBalance(address); + + if (blockNumber == -2) { + BigInteger tmpB = ethereum.getWallet().getBalance(address); + balance = tmpB != BigInteger.ZERO ? tmpB : balance; + } + + if (blockNumber >= 0) { + ethereum.getRepository().syncToRoot(root); + } + + String tmp = "0x" + balance.toString(16); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockTransactionCountByHash.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockTransactionCountByHash.java new file mode 100644 index 00000000..a29dbcdd --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockTransactionCountByHash.java @@ -0,0 +1,29 @@ +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.spongycastle.util.encoders.Hex; +import java.util.List; + +public class eth_getBlockTransactionCountByHash extends JsonRpcServerMethod { + + public eth_getBlockTransactionCountByHash (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] hash = jsToAddress((String)params.get(0)); + String tmp = "0x" + Integer.toHexString(ethereum.getBlockchain().getBlockByHash(hash).getTransactionsList().size()); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockTransactionCountByNumber.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockTransactionCountByNumber.java new file mode 100644 index 00000000..30817e0e --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockTransactionCountByNumber.java @@ -0,0 +1,40 @@ +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; + +public class eth_getBlockTransactionCountByNumber extends JsonRpcServerMethod { + + public eth_getBlockTransactionCountByNumber (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + String height = (String)params.get(0); + + long blockNumber = getBlockNumber(height); + if (blockNumber == -1) + blockNumber = ethereum.getBlockchain().getBestBlock().getNumber(); + + int count = 0; + if (blockNumber == -2) { + count = ethereum.getBlockchain().getPendingTransactions().size(); + } else { + count = ethereum.getBlockchain().getBlockByNumber(blockNumber).getTransactionsList().size(); + } + + String tmp = "0x" + Integer.toHexString(count); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getCode.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getCode.java new file mode 100644 index 00000000..d6135e46 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getCode.java @@ -0,0 +1,48 @@ +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.spongycastle.util.encoders.Hex; +import java.util.List; + +/* +Not sure if pending can have code. Also code by itself related to repository not very clear for me. +TODO: ask Roman advice for this method. +*/ +public class eth_getCode extends JsonRpcServerMethod { + + public eth_getCode (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 2) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] address = jsToAddress((String)params.get(0)); + 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()); + } + + String tmp = "0x" + Hex.toHexString(ethereum.getRepository().getCode(address)); + + if (blockNumber >= 0) { + ethereum.getRepository().syncToRoot(root); + } + + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getStorageAt.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getStorageAt.java new file mode 100644 index 00000000..dc45f462 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getStorageAt.java @@ -0,0 +1,49 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServer; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.facade.Ethereum; +import org.ethereum.vm.DataWord; +import org.spongycastle.util.encoders.Hex; +import java.util.List; + +/* +As I see getStorageValue not check Pending Transactions. +TODO: ask roman advice for this method. +*/ +public class eth_getStorageAt extends JsonRpcServerMethod { + + public eth_getStorageAt(Ethereum ethereum) { super(ethereum); } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 3) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] address = jsToAddress((String)params.get(0)); + long key = jsToLong((String) params.get(1)); + String height = (String)params.get(2); + + long blockNumber = getBlockNumber(height); + + byte[] root = ethereum.getBlockchain().getBestBlock().getStateRoot(); + + if (blockNumber >= 0) { + ethereum.getRepository().syncToRoot(ethereum.getBlockchain().getBlockByNumber(blockNumber).getStateRoot()); + } + + String tmp = "0x" + Hex.toHexString(ethereum.getRepository().getStorageValue(address, new DataWord(key)).getData()); + + if (blockNumber >= 0) { + ethereum.getRepository().syncToRoot(root); + } + + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionCount.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionCount.java new file mode 100644 index 00000000..e9e1c11a --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionCount.java @@ -0,0 +1,66 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServer; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.core.AccountState; +import org.ethereum.core.Transaction; +import org.ethereum.facade.Ethereum; +import org.spongycastle.util.encoders.Hex; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.List; + +/* +Can't find correct way to get contracts' state for specified block number. Right now method return correct value only for "latest" parameter +TODO: ask roman advice for this method. +*/ +public class eth_getTransactionCount extends JsonRpcServerMethod { + + public eth_getTransactionCount(Ethereum ethereum) { super(ethereum); } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 2) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] address = jsToAddress((String) params.get(0)); + 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()); + } + + BigInteger nonce = BigInteger.ZERO; + + AccountState accountState = ethereum.getRepository().getAccountState(address); + if (accountState != null) + nonce = accountState.getNonce(); + + if (blockNumber == -1) { + synchronized (ethereum.getBlockchain().getPendingTransactions()) { + for (Transaction tx : ethereum.getBlockchain().getPendingTransactions()) { + if (Arrays.equals(address, tx.getSender())) { + nonce.add(BigInteger.ONE); + } + } + } + } + + if (blockNumber >= 0) { + ethereum.getRepository().syncToRoot(root); + } + + String tmp = "0x" + nonce.toString(16); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleCountByBlockHash.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleCountByBlockHash.java new file mode 100644 index 00000000..894e3154 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleCountByBlockHash.java @@ -0,0 +1,29 @@ +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.spongycastle.util.encoders.Hex; +import java.util.List; + +public class eth_getUncleCountByBlockHash extends JsonRpcServerMethod { + + public eth_getUncleCountByBlockHash (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] hash = jsToAddress((String)params.get(0)); + String tmp = "0x" + Integer.toHexString(ethereum.getBlockchain().getBlockByHash(hash).getUncleList().size()); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleCountByBlockNumber.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleCountByBlockNumber.java new file mode 100644 index 00000000..d91fff91 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleCountByBlockNumber.java @@ -0,0 +1,44 @@ +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; + +/* +Not sure if pending transactions can have uncle. +TODO: ask Roman about this +*/ +public class eth_getUncleCountByBlockNumber extends JsonRpcServerMethod { + + public eth_getUncleCountByBlockNumber (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + String height = (String)params.get(1); + + long blockNumber = getBlockNumber(height); + if (blockNumber == -1) + blockNumber = ethereum.getBlockchain().getBestBlock().getNumber(); + + int count = 0; + if (blockNumber == -2) { + count = 0; + } else { + count = ethereum.getBlockchain().getBlockByNumber(blockNumber).getUncleList().size(); + } + + String tmp = "0x" + Integer.toHexString(count); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_hashrate.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_hashrate.java new file mode 100644 index 00000000..6c461b66 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_hashrate.java @@ -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.facade.Ethereum; + +/* +TODO: right now -core not have "finished" mining architecture so not have hashrate +*/ +public class eth_hashrate extends JsonRpcServerMethod { + + public eth_hashrate (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + String tmp = "0x" + Integer.toHexString(0); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_mining.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_mining.java new file mode 100644 index 00000000..e49686b0 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_mining.java @@ -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.facade.Ethereum; + +/* +TODO: right now -core not auto start mining and also not have marker to identify if it's happening +*/ +public class eth_mining extends JsonRpcServerMethod { + + public eth_mining (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + Boolean tmp = false; + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_protocolVersion.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_protocolVersion.java new file mode 100644 index 00000000..19a5d9e5 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_protocolVersion.java @@ -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.eth.EthHandler; + +public class eth_protocolVersion extends JsonRpcServerMethod { + + public eth_protocolVersion (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + String tmp = Byte.toString(EthHandler.VERSION); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_sendTransaction.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_sendTransaction.java new file mode 100644 index 00000000..4b1a5f00 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_sendTransaction.java @@ -0,0 +1,108 @@ +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.Account; +import org.ethereum.core.Transaction; +import org.ethereum.facade.Ethereum; +import org.spongycastle.util.encoders.Hex; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import static org.ethereum.core.Denomination.SZABO; +import static org.ethereum.config.SystemProperties.CONFIG; + +/* +Not sure if we must call submitTransaction from here but logically to do it. Also not clear how created transaction added to pending and to "from" account pending (in test - it didn't) +TODO: get advice from Roman. By spec if created transaction (empty data param) - result must be 20 bytes hash, but I got 32 bytes for both contract and transaction create. +*/ +public class eth_sendTransaction extends JsonRpcServerMethod { + + public eth_sendTransaction (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + 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"))) { + 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) { + return new JSONRPC2Response(JSONRPC2Error.INTERNAL_ERROR, req.getID()); + } + + String tmp = "0x" + Hex.toHexString(tx.getHash()); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_sign.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_sign.java new file mode 100644 index 00000000..c554745a --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_sign.java @@ -0,0 +1,53 @@ +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.Account; +import org.ethereum.crypto.ECKey; +import org.ethereum.facade.Ethereum; +import org.spongycastle.util.encoders.Hex; +import java.util.Arrays; +import java.util.List; +import static org.ethereum.util.ByteUtil.bigIntegerToBytes; + + +public class eth_sign extends JsonRpcServerMethod { + + public eth_sign (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 2) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] address = jsToAddress((String) params.get(0)); + byte[] data = jsToAddress((String) params.get(1)); + String out = null; + + for (Account ac : ethereum.getWallet().getAccountCollection()) { + if (Arrays.equals(ac.getAddress(), address)) { + ECKey.ECDSASignature sig = ac.getEcKey().doSign(data); + byte[] sigData = new byte[65]; + sigData[0] = sig.v; + System.arraycopy(bigIntegerToBytes(sig.r, 32), 0, sigData, 1, 32); + System.arraycopy(bigIntegerToBytes(sig.s, 32), 0, sigData, 33, 32); + out = Hex.toHexString(sigData); + break; + } + } + + if (out == null) { + return new JSONRPC2Response(JSONRPC2Error.INTERNAL_ERROR, req.getID()); + } + + String tmp = "0x" + out; + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/net_listening.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/net_listening.java new file mode 100644 index 00000000..67f5abaf --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/net_listening.java @@ -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.facade.Ethereum; + +/* +TODO: right now -core not mark fact of start listening, it do it automatically and only send Listening trace "string" message. +*/ +public class net_listening extends JsonRpcServerMethod { + + public net_listening (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + Boolean tmp = true; + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/net_peerCount.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/net_peerCount.java new file mode 100644 index 00000000..b5cb30c1 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/net_peerCount.java @@ -0,0 +1,31 @@ +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.peerdiscovery.PeerInfo; +import java.util.Set; + +public class net_peerCount extends JsonRpcServerMethod { + + public net_peerCount (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + int pc = 0; + final Set peers = ethereum.getPeers(); + synchronized (peers) { + for (PeerInfo peer : peers) { + if (peer.isOnline()) + pc++; + } + } + String tmp = "0x" + Integer.toHexString(pc); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/net_version.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/net_version.java new file mode 100644 index 00000000..5154f760 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/net_version.java @@ -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: request go version how this must be identified. Cpp version just return "". +*/ +public class net_version extends JsonRpcServerMethod { + + public net_version (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + String tmp = ""; + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/web3_clientVersion.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/web3_clientVersion.java new file mode 100644 index 00000000..529dcc0f --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/web3_clientVersion.java @@ -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.config.SystemProperties; +import org.ethereum.facade.Ethereum; +import org.ethereum.util.Utils; + +public class web3_clientVersion extends JsonRpcServerMethod { + + public web3_clientVersion (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + String tmp = "ethereumj/v" + SystemProperties.CONFIG.projectVersion() + "/android/java" + Utils.JAVA_VERSION; + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/web3_sha3.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/web3_sha3.java new file mode 100644 index 00000000..8ac1ba21 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/web3_sha3.java @@ -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.crypto.SHA3Helper; +import org.ethereum.facade.Ethereum; +import org.spongycastle.util.encoders.Hex; + +import java.util.List; + + +public class web3_sha3 extends JsonRpcServerMethod { + + public web3_sha3 (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] data = jsToAddress((String)params.get(0)); + String tmp = "0x" + Hex.toHexString(SHA3Helper.sha3(data)); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file