/nervosj

Java library for working with Smart Contract and integrating with clients on Nervos Network.

Primary LanguageJavaOtherNOASSERTION

nervosj

Build Status

Introduction

nervosj, originally adapted from Ethereum Web3j, is a Java library for working with Smart Contract and integrating with clients on Nervos network.

Features

  • Complete implementation of Nervos JSON-RPC API over HTTP.
  • Auto-generation of Java smart contract wrappers to create, deploy, transact with and call smart contracts from native Java code (Solidity and Truffle definition formats supported).
  • Comprehensive integration tests demonstrating a number of the above scenarios
  • Android compatible

Getting Started

Prerequisites

Java 8
Gradle 4.3

Install

git clone https://github.com/cryptape/nervosj.git gradle shadowJar to generate a jar file for nervosj.

Test net

Use Nervos AppChain test net (recommended):
http://121.196.200.225:1337 is provided as a testnet for tests.

Or build your own Nervos AppChain net:
Please find more information in how to set up client in your local.

Get started

Deploy smart contract

Similar as Ethereum, smart contracts are deployed in Nervos AppChain network by sending transactions. Nervos AppChain transaction is defined in Transaction.java. In Nervos transaction, there are 3 special parameters:

  • nonce: generated randomly or depend on specific logic to avoid replay attack.
  • quota: transaction execution fee for operation, like gasPrice * gasLimit in Ethereum.
  • valid_until_block: timeout mechanism which should be set in (currentHeight, currentHeight + 100]. Transaction will be discarded beyond valid_until_block.

Please see the example below for a smart contract deployment.

Generate binary file for the contract by below command:

$solc example.sol --bin

Construct a transaction with generated binary code and other 3 parameters.

long currentHeight = currentBlockNumber();
long validUntilBlock = currentHeight + 80;
BigInteger nonce = BigInteger.valueOf(Math.abs(random.nextLong()));
long quota = 1000000;
Transaction tx = Transaction.createContractTransaction(nonce, quota, validUntilBlock, contractCode);

Sign the transaction with sender's private key and send it to Nervos AppChain net.

String rawTx = tx.sign(privateKey);
Nervosj service = Nervosj.build(new HttpService(ipAddr + ":" + port));
EthSendTransaction result = service.appSendRawTransaction(rawTx).send();

Please be attention that all transactions need to be signed since Nervos AppChain only supports method sendRawTransaction rather than sendTransaction.

Call functions in smart contract

In Nervos AppChain smart contract call, like contract deployment, a transaction needs to be created with 2 more parameters:

  • contract address: address of the deployed contract.
  • functionCallData: ABI of function and parameter.

After contract deployed, contract address can be fetched from TransactionReceipt. functionCallData is encoded from functionName and parameters by contract ABI. For example, functionCallData of function set() with parameter 1 is 60fe47b10000000000000000000000000000000000000000000000000000000000000001.

//get receipt and address from transaction
String txHash = result.getSendTransactionResult().getHash();
TransactionReceipt txReceipt = service.appGetTransactionReceipt(txHash).send().getTransactionReceipt().get();
String contractAddress = txReceipt.getContractAddress();

//sign and send the transaction
Transaction tx = Transaction.createFunctionCallTransaction(contractAddress, nonce, quota, validUntilBlock, functionCallData);
String rawTx = tx.sign(privateKey);
String txHash =  service.ethSendRawTransaction(rawTx).send().getSendTransactionResult().getHash();

Please check TokenTransactionTest.java to see a complete example for smart contract deployment and function invocation.

Working with smart contract with nervosj wrapper

Besides interacting with smart contracts by sending transactions with binary code, nervosj provides a tool to help to convert solidity contract to a Java class from which smart contracts can be deployed and called.

Run gradle shadowJar to generate jars so that the tool can be found under console/build/libs. Name of the tool is console-version-all.jar.

Usage of console-version-all is shown below:

$ java -jar console-0.17-all.jar solidity generate [--javaTypes|--solidityTypes] /path/to/{smart-contract}.bin /path/to/{smart-contract}.abi -o /path/to/src/main/java -p {package-path}

Example generate Java class from Token.sol, Token.bin and Token.abi under nervosj/tests/src/main/resources:

java -jar console/build/libs/console-0.17-all.jar solidity generate tests/src/main/resources/Token.bin tests/src/main/resources/Token.abi -o tests/src/main/java/ -p org.nervos.appchain.tests

Token.java will be created from commands above and class Token can be used with CitaTransactionManager to deploy and call smart contract Token. Please be attention that CitaTransactionManager is supposed to be used as TransactionManager for transaction creation in Nervos AppChain network. Please check TokenCodegenTest.java for a complete example.

Working with smart contract with nervosj Account

nervosj provides interface Account for smart contract manipulations. With parameters of smart contract's name, address, method and method's arguments, smart contracts can be deployed and called through the interface without exposing extra java, bin or abi file to developers.

Method of smart contract deployment:

// Deploy contract in sync and async way.
public EthSendTransaction deploy(File contractFile, BigInteger nonce, BigInteger quota)

public CompletableFuture<EthSendTransaction> deployAsync(File contractFile, BigInteger nonce, BigInteger quota)

Method of smart contract method call:

public Object callContract(String contractAddress, String funcName, BigInteger nonce, BigInteger quota, Object... args)

//function is a encapsulation of method including name, argument datatypes, return type and other info.
public Object callContract(String contractAddress, AbiDefinition functionAbi, BigInteger nonce, BigInteger quota, Object... args)

While contract file is required when first deploy the contract, nervosj can get the abi file according to address when call methods in deployed contract. Please find complete code in TokenAccountTest.