Skip to content

Commit

Permalink
Merge pull request #10 from web3j/android
Browse files Browse the repository at this point in the history
1. Added Transfer class for simplifying Ether transactions in line wi…
  • Loading branch information
conor10 authored Nov 8, 2016
2 parents 2a4113b + fb7f721 commit adc5ecc
Show file tree
Hide file tree
Showing 16 changed files with 569 additions and 109 deletions.
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ Maven
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>1.0.1</version>
<version>1.0.2</version>
</dependency>
Gradle
------

.. code-block:: groovy
compile ('org.web3j:core:1.0.1')
compile ('org.web3j:core:1.0.2')
Start a client
Expand Down
7 changes: 5 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ buildscript {
mavenCentral()
}
dependencies {
classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.5.3"
classpath 'io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.5.3'
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.4'
}
}

Expand All @@ -21,9 +22,10 @@ apply plugin: 'maven'
apply plugin: 'signing'
apply plugin: 'idea'
apply plugin: 'io.codearte.nexus-staging'
apply plugin: 'com.github.johnrengelman.shadow'

group 'org.web3j'
version '1.0.1'
version '1.0.2'

sourceCompatibility = 1.8

Expand Down Expand Up @@ -59,6 +61,7 @@ ext {

repositories {
mavenCentral()
jcenter()
}

// See https://www.petrikainulainen.net/programming/gradle/getting-started-with-gradle-integration-testing/
Expand Down
4 changes: 2 additions & 2 deletions docs/source/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ Maven
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>1.0.1</version>
<version>1.0.2</version>
</dependency>
Gradle
------

.. code-block:: groovy
compile ('org.web3j:core:1.0.1')
compile ('org.web3j:core:1.0.2')
Start a client
Expand Down
49 changes: 49 additions & 0 deletions src/integration-test/java/org/web3j/generated/Greeter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.web3j.generated;

import java.lang.String;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.Future;
import org.web3j.abi.Contract;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Utf8String;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.TransactionReceipt;

/**
* <p>Auto generated code.<br>
* <strong>Do not modifiy!</strong><br>
* Please use {@link org.web3j.codegen.SolidityFunctionWrapperGenerator} to update.</p>
*/
public final class Greeter extends Contract {
private static final String BINARY = "606060405260405161026938038061026983398101604052805101600080546c0100000000000000000000000033810204600160a060020a03199091161790558060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1060b357805160ff19168380011785555b5060a29291505b8082111560e057600081556001016090565b505050610185806100e46000396000f35b828001600101855582156089579182015b82811115608957825182600050559160200191906001019060c4565b509056606060405260e060020a600035046341c0e1b58114610029578063cfae321714610070575b610002565b34610002576100de6000543373ffffffffffffffffffffffffffffffffffffffff9081169116141561014e5760005473ffffffffffffffffffffffffffffffffffffffff16ff5b3461000257604080516020808201835260008252600180548451600282841615610100026000190190921691909104601f81018490048402820184019095528481526100e094909283018282801561017b5780601f106101505761010080835404028352916020019161017b565b005b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156101405780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b565b820191906000526020600020905b81548152906001019060200180831161015e57829003601f168201915b505050505090509056";

private Greeter(String contractAddress, Web3j web3j, Credentials credentials) {
super(contractAddress, web3j, credentials);
}

public Future<TransactionReceipt> kill() {
Function function = new Function<>("kill", Arrays.asList(), Collections.emptyList());
return executeTransactionAsync(function);
}

public Future<Utf8String> greet() {
Function function = new Function<>("greet",
Arrays.asList(),
Arrays.asList(new TypeReference<Utf8String>() {}));
return executeCallSingleValueReturnAsync(function);
}

public static Future<Greeter> deploy(Web3j web3j, Credentials credentials, BigInteger initialValue, Utf8String _greeting) {
String encodedConstructor = FunctionEncoder.encodeConstructor(Arrays.asList(_greeting));
return deployAsync(Greeter.class, web3j, credentials, BINARY, encodedConstructor, initialValue);
}

public static Greeter load(String contractAddress, Web3j web3j, Credentials credentials) {
return new Greeter(contractAddress, web3j, credentials);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package org.web3j.protocol.scenarios;

import java.math.BigDecimal;
import java.math.BigInteger;

import org.junit.Test;

import org.web3j.abi.Transfer;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
Expand All @@ -17,6 +19,7 @@
* Simple integration test to demonstrate sending of Ether between parties.
*/
public class SendEtherIT extends Scenario {

@Test
public void testTransferEther() throws Exception {
unlockAccount();
Expand All @@ -38,4 +41,31 @@ public void testTransferEther() throws Exception {

assertThat(transactionReceipt.getTransactionHash(), is(transactionHash));
}

/*
Valid transaction reciept:
"{"jsonrpc":"2.0",
"id":1,
"result":{
"blockHash":"0x35a865cf2ba4efc3642b17a651f9e896dfebcdea39bfd0741b6f629e1be31a27",
"blockNumber":"0x1c155f",
"contractAddress":null,
"cumulativeGasUsed":"0x5208",
"from":"0x19e03255f667bdfd50a32722df860b1eeaf4d635",
"gasUsed":"0x5208",
"logs":[
],
"root":"327e1e81c85cb710fe81cb8c0f824e9e49c3bf200e5e1149f589140145df10e3",
"to":"0x9c98e381edc5fe1ac514935f3cc3edaa764cf004",
"transactionHash":"0x16e41aa9d97d1c3374a4cb9599febdb24d4d5648b607c99e01a8e79e3eab2c34",
"transactionIndex":"0x0"
}
*/
@Test
public void testTransfer() throws Exception {
TransactionReceipt transactionReceipt = Transfer.sendFunds(
parity, ALICE, BOB.getAddress(), BigDecimal.valueOf(0.2), Convert.Unit.ETHER);
assertFalse(transactionReceipt.getBlockHash().isEmpty());
}
}
68 changes: 2 additions & 66 deletions src/main/java/org/web3j/abi/Contract.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,27 @@
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.request.RawTransaction;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.*;
import org.web3j.protocol.exceptions.TransactionTimeoutException;
import org.web3j.utils.Numeric;


/**
* Solidity contract type abstraction for interacting with smart contracts via native Java types.
*/
public abstract class Contract {
public abstract class Contract extends ManagedTransaction {

private static final BigInteger GAS_PRICE = BigInteger.valueOf(50_000_000_000L);
private static final BigInteger GAS_LIMIT = BigInteger.valueOf(2_000_000);

private static final int SLEEP_DURATION = 15000;
private static final int ATTEMPTS = 40;

private String contractAddress;
private Web3j web3j;
private Credentials credentials;

protected Contract(String contractAddress, Web3j web3j, Credentials credentials) {
super(web3j, credentials);
this.contractAddress = contractAddress;
this.web3j = web3j;
this.credentials = credentials;
}

public String getContractAddress() {
Expand Down Expand Up @@ -138,21 +130,6 @@ protected TransactionReceipt executeTransaction(
return signAndSend(rawTransaction);
}

private TransactionReceipt signAndSend(RawTransaction rawTransaction)
throws InterruptedException, ExecutionException, TransactionTimeoutException{
byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
String hexValue = Numeric.toHexString(signedMessage);

// This might be a good candidate for using functional composition with CompletableFutures
EthSendTransaction transactionResponse = web3j.ethSendRawTransaction(hexValue)
.sendAsync().get();

String transactionHash = transactionResponse.getTransactionHash();

return waitForTransactionReceipt(transactionHash);
}


/**
* Execute the provided function as a transaction asynchronously.
*
Expand All @@ -173,47 +150,6 @@ protected Future<TransactionReceipt> executeTransactionAsync(Function function)
return result;
}

private BigInteger getNonce(String address) throws InterruptedException, ExecutionException {
EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(
address, DefaultBlockParameterName.LATEST).sendAsync().get();

return ethGetTransactionCount.getTransactionCount();
}

private TransactionReceipt waitForTransactionReceipt(
String transactionHash) throws InterruptedException, ExecutionException,
TransactionTimeoutException {

return getTransactionReceipt(transactionHash, SLEEP_DURATION, ATTEMPTS);
}

private TransactionReceipt getTransactionReceipt(
String transactionHash, int sleepDuration, int attempts)
throws InterruptedException, ExecutionException, TransactionTimeoutException {

Optional<TransactionReceipt> receiptOptional =
sendTransactionReceiptRequest(transactionHash);
for (int i = 0; i < attempts; i++) {
if (!receiptOptional.isPresent()) {
Thread.sleep(sleepDuration);
receiptOptional = sendTransactionReceiptRequest(transactionHash);
} else {
return receiptOptional.get();
}
}

throw new TransactionTimeoutException("Transaction receipt was not generated after " +
((sleepDuration * attempts) / 1000 + " seconds"));
}

private Optional<TransactionReceipt> sendTransactionReceiptRequest(
String transactionHash) throws InterruptedException, ExecutionException {
EthGetTransactionReceipt transactionReceipt =
web3j.ethGetTransactionReceipt(transactionHash).sendAsync().get();

return transactionReceipt.getTransactionReceipt();
}

protected EventValues extractEventParameters(
Event event, TransactionReceipt transactionReceipt) {

Expand Down
93 changes: 93 additions & 0 deletions src/main/java/org/web3j/abi/ManagedTransaction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package org.web3j.abi;

import java.math.BigInteger;
import java.util.Optional;
import java.util.concurrent.ExecutionException;

import org.web3j.crypto.Credentials;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.request.RawTransaction;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.exceptions.TransactionTimeoutException;
import org.web3j.utils.Numeric;


/**
* Generic transaction manager
*/
public abstract class ManagedTransaction {

private static final BigInteger GAS_PRICE = BigInteger.valueOf(50_000_000_000L);
private static final BigInteger GAS_LIMIT = BigInteger.valueOf(2_000_000);

private static final int SLEEP_DURATION = 15000;
private static final int ATTEMPTS = 40;

protected Web3j web3j;
protected Credentials credentials;

protected ManagedTransaction(Web3j web3j, Credentials credentials) {
this.web3j = web3j;
this.credentials = credentials;
}

protected TransactionReceipt signAndSend(RawTransaction rawTransaction)
throws InterruptedException, ExecutionException, TransactionTimeoutException{
byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
String hexValue = Numeric.toHexString(signedMessage);

// This might be a good candidate for using functional composition with CompletableFutures
EthSendTransaction transactionResponse = web3j.ethSendRawTransaction(hexValue)
.sendAsync().get();

String transactionHash = transactionResponse.getTransactionHash();

return waitForTransactionReceipt(transactionHash);
}

protected BigInteger getNonce(String address) throws InterruptedException, ExecutionException {
EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(
address, DefaultBlockParameterName.LATEST).sendAsync().get();

return ethGetTransactionCount.getTransactionCount();
}

private TransactionReceipt waitForTransactionReceipt(
String transactionHash) throws InterruptedException, ExecutionException,
TransactionTimeoutException {

return getTransactionReceipt(transactionHash, SLEEP_DURATION, ATTEMPTS);
}

private TransactionReceipt getTransactionReceipt(
String transactionHash, int sleepDuration, int attempts)
throws InterruptedException, ExecutionException, TransactionTimeoutException {

Optional<TransactionReceipt> receiptOptional =
sendTransactionReceiptRequest(transactionHash);
for (int i = 0; i < attempts; i++) {
if (!receiptOptional.isPresent()) {
Thread.sleep(sleepDuration);
receiptOptional = sendTransactionReceiptRequest(transactionHash);
} else {
return receiptOptional.get();
}
}

throw new TransactionTimeoutException("Transaction receipt was not generated after " +
((sleepDuration * attempts) / 1000 + " seconds"));
}

private Optional<TransactionReceipt> sendTransactionReceiptRequest(
String transactionHash) throws InterruptedException, ExecutionException {
EthGetTransactionReceipt transactionReceipt =
web3j.ethGetTransactionReceipt(transactionHash).sendAsync().get();

return transactionReceipt.getTransactionReceipt();
}
}
Loading

0 comments on commit adc5ecc

Please sign in to comment.