BAEL-1461

This commit is contained in:
Thoughtscript 2018-04-19 05:37:34 +01:00
parent 263009fb32
commit 21bd180c1c
28 changed files with 3125 additions and 0 deletions

View File

@ -74,6 +74,7 @@
<module>dozer</module>
<module>ethereumj</module>
<module>web3j</module>
<!--<module>ejb</module>-->

3
web3j/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.idea
target
*.iml

4
web3j/README.md Normal file
View File

@ -0,0 +1,4 @@
## Web3j
### Relevant Articles:
- [Lightweight Web3](http://www.baeldung.com/lightweight-web3/)

View File

@ -0,0 +1,23 @@
# Ganache Readme
TL:DR - To set up Ganache visit: http://truffleframework.com/ganache/
# Three Ways to Install Ganache
Ganache is provided in three libraries or distributions:
(1) Ganache - https://github.com/trufflesuite/ganache
This is a pre-built and out-of-the-box solution. Easiest to set up. It provides an interface and server shell for Ganache CLI.
(2) Ganache CLI - https://www.npmjs.com/package/ganache-cli
Ganache CLI abstracts Ganache Core and supplies the default options and arguments used.
(3) Ganache Core - https://www.npmjs.com/package/ganache-core
Basically, only use Ganache Core if you need to build a totally customized option.
# Use
The default port is *8545* on *localhost*

View File

@ -0,0 +1,43 @@
# Using Truffle
Basic Truffle walkthrough readme.
See also: http://truffleframework.com/docs/
# Bash
Truffle install
```bash
$ npm install truffle -g
$ truffle version
```
Truffle commands:
```bash
$ truffle init
$ truffle compile
$ truffle migrate
$ truffle test
```
# Directory Structure
The command `$ truffle init` will create a directory structure in the specified root according to the following:
```
root -|
|-build (Compiled Solc JSON Output Dir)
|-contracts (Solc Contracts to be Compiled and Migrated)
|-migrations (Specify the Order and Dependencies of Contracts to Be Deployed)
|-test (Truffle Tests)
```
# Compile
Truffle will compile the smart contracts and expose their **JSON ABI's for use with Web3.js** or **Binary ABI's for use with Web3J**.
# Migration
Truffle will let you deploy your Solc contracts directly to a blockchin of your choice.

View File

@ -0,0 +1,455 @@
{
"contractName": "ConvertLib",
"abi": [
{
"constant": false,
"inputs": [
{
"name": "amount",
"type": "uint256"
},
{
"name": "conversionRate",
"type": "uint256"
}
],
"name": "convert",
"outputs": [
{
"name": "convertedAmount",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x60d161002f600b82828239805160001a6073146000811461001f57610021565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146060604052600436106056576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806396e4ee3d14605b575b600080fd5b8115606557600080fd5b608260048080359060200190919080359060200190919050506098565b6040518082815260200191505060405180910390f35b60008183029050929150505600a165627a7a72305820ab84b2740847d7b84a33de9738ae9cf9aabac1b68e6a64d60bd5020b9b6235e40029",
"deployedBytecode": "0x73000000000000000000000000000000000000000030146060604052600436106056576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806396e4ee3d14605b575b600080fd5b8115606557600080fd5b608260048080359060200190919080359060200190919050506098565b6040518082815260200191505060405180910390f35b60008183029050929150505600a165627a7a72305820ab84b2740847d7b84a33de9738ae9cf9aabac1b68e6a64d60bd5020b9b6235e40029",
"sourceMap": "28:148:0:-;;132:2:-1;166:7;155:9;146:7;137:37;252:7;246:14;243:1;238:23;232:4;229:33;270:1;265:20;;;;222:63;;265:20;274:9;222:63;;298:9;295:1;288:20;328:4;319:7;311:22;352:7;343;336:24",
"deployedSourceMap": "28:148:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;50:123;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109:20;154:14;145:6;:23;138:30;;50:123;;;;:::o",
"source": "pragma solidity ^0.4.17;\r\n\r\nlibrary ConvertLib{\r\n\tfunction convert(uint amount,uint conversionRate) returns (uint convertedAmount)\r\n\t{\r\n\t\treturn amount * conversionRate;\r\n\t}\r\n}\r\n",
"sourcePath": "C:\\workspace\\current_workspace\\web3java\\dev_truffle\\contracts\\ConvertLib.sol",
"ast": {
"absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/ConvertLib.sol",
"exportedSymbols": {
"ConvertLib": [
16
]
},
"id": 17,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1,
"literals": [
"solidity",
"^",
"0.4",
".17"
],
"nodeType": "PragmaDirective",
"src": "0:24:0"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "library",
"documentation": null,
"fullyImplemented": true,
"id": 16,
"linearizedBaseContracts": [
16
],
"name": "ConvertLib",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 14,
"nodeType": "Block",
"src": "133:40:0",
"statements": [
{
"expression": {
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 12,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 10,
"name": "amount",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 3,
"src": "145:6:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "BinaryOperation",
"operator": "*",
"rightExpression": {
"argumentTypes": null,
"id": 11,
"name": "conversionRate",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 5,
"src": "154:14:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"src": "145:23:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"functionReturnParameters": 9,
"id": 13,
"nodeType": "Return",
"src": "138:30:0"
}
]
},
"documentation": null,
"id": 15,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "convert",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 6,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 3,
"name": "amount",
"nodeType": "VariableDeclaration",
"scope": 15,
"src": "67:11:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 2,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "67:4:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 5,
"name": "conversionRate",
"nodeType": "VariableDeclaration",
"scope": 15,
"src": "79:19:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 4,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "79:4:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "66:33:0"
},
"payable": false,
"returnParameters": {
"id": 9,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 8,
"name": "convertedAmount",
"nodeType": "VariableDeclaration",
"scope": 15,
"src": "109:20:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 7,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "109:4:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "108:22:0"
},
"scope": 16,
"src": "50:123:0",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 17,
"src": "28:148:0"
}
],
"src": "0:178:0"
},
"legacyAST": {
"absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/ConvertLib.sol",
"exportedSymbols": {
"ConvertLib": [
16
]
},
"id": 17,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 1,
"literals": [
"solidity",
"^",
"0.4",
".17"
],
"nodeType": "PragmaDirective",
"src": "0:24:0"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "library",
"documentation": null,
"fullyImplemented": true,
"id": 16,
"linearizedBaseContracts": [
16
],
"name": "ConvertLib",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 14,
"nodeType": "Block",
"src": "133:40:0",
"statements": [
{
"expression": {
"argumentTypes": null,
"commonType": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"id": 12,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"leftExpression": {
"argumentTypes": null,
"id": 10,
"name": "amount",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 3,
"src": "145:6:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "BinaryOperation",
"operator": "*",
"rightExpression": {
"argumentTypes": null,
"id": 11,
"name": "conversionRate",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 5,
"src": "154:14:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"src": "145:23:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"functionReturnParameters": 9,
"id": 13,
"nodeType": "Return",
"src": "138:30:0"
}
]
},
"documentation": null,
"id": 15,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "convert",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 6,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 3,
"name": "amount",
"nodeType": "VariableDeclaration",
"scope": 15,
"src": "67:11:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 2,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "67:4:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
},
{
"constant": false,
"id": 5,
"name": "conversionRate",
"nodeType": "VariableDeclaration",
"scope": 15,
"src": "79:19:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 4,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "79:4:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "66:33:0"
},
"payable": false,
"returnParameters": {
"id": 9,
"nodeType": "ParameterList",
"parameters": [
{
"constant": false,
"id": 8,
"name": "convertedAmount",
"nodeType": "VariableDeclaration",
"scope": 15,
"src": "109:20:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName": {
"id": 7,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "109:4:0",
"typeDescriptions": {
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
}
],
"src": "108:22:0"
},
"scope": 16,
"src": "50:123:0",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 17,
"src": "28:148:0"
}
],
"src": "0:178:0"
},
"compiler": {
"name": "solc",
"version": "0.4.21+commit.dfe3193c.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-04-14T03:37:39.678Z"
}

View File

@ -0,0 +1,251 @@
{
"contractName": "Example",
"abi": [
{
"inputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"constant": false,
"inputs": [],
"name": "ExampleFunction",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x60606040523415600e57600080fd5b60848061001c6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b818dacd146044575b600080fd5b3415604e57600080fd5b60546056565b005b5600a165627a7a72305820bebcbbdf06550591bc772dfcb0eadc842f95953869feb7a9528bac91487d95240029",
"deployedBytecode": "0x606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b818dacd146044575b600080fd5b3415604e57600080fd5b60546056565b005b5600a165627a7a72305820bebcbbdf06550591bc772dfcb0eadc842f95953869feb7a9528bac91487d95240029",
"sourceMap": "28:134:1:-;;;50:45;;;;;;;;28:134;;;;;;",
"deployedSourceMap": "28:134:1:-;;;;;;;;;;;;;;;;;;;;;;;;101:58;;;;;;;;;;;;;;;:::o",
"source": "pragma solidity ^0.4.17;\r\n\r\ncontract Example {\r\n function Example() {\r\n // constructor\r\n }\r\n\r\n function ExampleFunction() {\r\n // example function\r\n }\r\n}",
"sourcePath": "C:\\workspace\\current_workspace\\web3java\\dev_truffle\\contracts\\Example.sol",
"ast": {
"absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/Example.sol",
"exportedSymbols": {
"Example": [
27
]
},
"id": 28,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 18,
"literals": [
"solidity",
"^",
"0.4",
".17"
],
"nodeType": "PragmaDirective",
"src": "0:24:1"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": true,
"id": 27,
"linearizedBaseContracts": [
27
],
"name": "Example",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 21,
"nodeType": "Block",
"src": "69:26:1",
"statements": []
},
"documentation": null,
"id": 22,
"implemented": true,
"isConstructor": true,
"isDeclaredConst": false,
"modifiers": [],
"name": "Example",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 19,
"nodeType": "ParameterList",
"parameters": [],
"src": "66:2:1"
},
"payable": false,
"returnParameters": {
"id": 20,
"nodeType": "ParameterList",
"parameters": [],
"src": "69:0:1"
},
"scope": 27,
"src": "50:45:1",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
},
{
"body": {
"id": 25,
"nodeType": "Block",
"src": "128:31:1",
"statements": []
},
"documentation": null,
"id": 26,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "ExampleFunction",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 23,
"nodeType": "ParameterList",
"parameters": [],
"src": "125:2:1"
},
"payable": false,
"returnParameters": {
"id": 24,
"nodeType": "ParameterList",
"parameters": [],
"src": "128:0:1"
},
"scope": 27,
"src": "101:58:1",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 28,
"src": "28:134:1"
}
],
"src": "0:162:1"
},
"legacyAST": {
"absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/Example.sol",
"exportedSymbols": {
"Example": [
27
]
},
"id": 28,
"nodeType": "SourceUnit",
"nodes": [
{
"id": 18,
"literals": [
"solidity",
"^",
"0.4",
".17"
],
"nodeType": "PragmaDirective",
"src": "0:24:1"
},
{
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": true,
"id": 27,
"linearizedBaseContracts": [
27
],
"name": "Example",
"nodeType": "ContractDefinition",
"nodes": [
{
"body": {
"id": 21,
"nodeType": "Block",
"src": "69:26:1",
"statements": []
},
"documentation": null,
"id": 22,
"implemented": true,
"isConstructor": true,
"isDeclaredConst": false,
"modifiers": [],
"name": "Example",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 19,
"nodeType": "ParameterList",
"parameters": [],
"src": "66:2:1"
},
"payable": false,
"returnParameters": {
"id": 20,
"nodeType": "ParameterList",
"parameters": [],
"src": "69:0:1"
},
"scope": 27,
"src": "50:45:1",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
},
{
"body": {
"id": 25,
"nodeType": "Block",
"src": "128:31:1",
"statements": []
},
"documentation": null,
"id": 26,
"implemented": true,
"isConstructor": false,
"isDeclaredConst": false,
"modifiers": [],
"name": "ExampleFunction",
"nodeType": "FunctionDefinition",
"parameters": {
"id": 23,
"nodeType": "ParameterList",
"parameters": [],
"src": "125:2:1"
},
"payable": false,
"returnParameters": {
"id": 24,
"nodeType": "ParameterList",
"parameters": [],
"src": "128:0:1"
},
"scope": 27,
"src": "101:58:1",
"stateMutability": "nonpayable",
"superFunction": null,
"visibility": "public"
}
],
"scope": 28,
"src": "28:134:1"
}
],
"src": "0:162:1"
},
"compiler": {
"name": "solc",
"version": "0.4.21+commit.dfe3193c.Emscripten.clang"
},
"networks": {},
"schemaVersion": "2.0.0",
"updatedAt": "2018-04-14T03:37:39.710Z"
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
pragma solidity ^0.4.17;
library ConvertLib{
function convert(uint amount,uint conversionRate) returns (uint convertedAmount)
{
return amount * conversionRate;
}
}

View File

@ -0,0 +1,11 @@
pragma solidity ^0.4.17;
contract Example {
function Example() {
// constructor
}
function ExampleFunction() {
// example function
}
}

View File

@ -0,0 +1,23 @@
pragma solidity ^0.4.17;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
function Migrations() public {
owner = msg.sender;
}
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) public restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}

View File

@ -0,0 +1,3 @@
module.exports = deployer => {
deployer.deploy(artifacts.require("./Migrations.sol"));
};

View File

@ -0,0 +1,8 @@
const Example = artifacts.require("./Example.sol"),
ConvertLib = artifacts.require("./ConvertLib.sol");
module.exports = deployer => {
deployer.deploy(ConvertLib);
deployer.link(ConvertLib, Example);
deployer.deploy(Example);
};

View File

@ -0,0 +1,20 @@
module.exports = {
contracts_build_directory: "./build/contracts",
networks: {
live: {
network_id: 1, // Ethereum public network
host: 'localhost',
port: 8545
},
testnet: {
network_id: 3, // Official Ethereum test network (Ropsten)
host: 'localhost',
port: 8545
},
development: {
host: 'localhost',
port: 8545,
network_id: '*'
}
}
}

210
web3j/pom.xml Normal file
View File

@ -0,0 +1,210 @@
<?xml version="1.0"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.web3j</groupId>
<artifactId>Web3j</artifactId>
<packaging>war</packaging>
<version>1.0.0</version>
<name>web3j</name>
<properties>
<hamcrest.version>1.3</hamcrest.version>
<jackson.version>2.9.3</jackson.version>
<javax-jsp.version>2.3.1</javax-jsp.version>
<javax-servlet.version>3.1.0</javax-servlet.version>
<jsonpath.version>2.4.0</jsonpath.version>
<jstl.version>1.2</jstl.version>
<junit.version>4.12</junit.version>
<logback.version>1.2.3</logback.version>
<maven-surefire.version>2.18.1</maven-surefire.version>
<mockito.version>1.10.19</mockito.version>
<slf4j.version>1.7.25</slf4j.version>
<springframework.version>5.0.5.RELEASE</springframework.version>
</properties>
<dependencies>
<!-- Spring Dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax-servlet.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>${javax-jsp.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- Jackson Dependencies -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- Web3J -->
<dependency>
<groupId>org.web3j</groupId>
<artifactId>core</artifactId>
<version>3.3.1</version>
</dependency>
<!-- Testing -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>${hamcrest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${springframework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>${jsonpath.version}</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat8-maven-plugin</artifactId>
<version>3.0-r1655215</version>
<configuration>
<path>/javaweb3</path>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire.version}</version>
<executions>
<execution>
<id>install</id>
<phase>install</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<includes>
<include>
test/com/baeldung/web3j/controllers/EthereumRestControllerIntegrationTest.java
</include>
<include>
test/com/baeldung/web3j/controllers/EthereumRestControllerUnitTest.java
</include>
<include>
test/com/baeldung/web3j/services/EthereumContractUnitTest.java
</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<finalName>web3j</finalName>
</build>
</project>

View File

@ -0,0 +1,68 @@
package com.baeldung.web3j.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.PathResourceResolver;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
import java.util.concurrent.Executor;
@Configuration
@EnableWebMvc
@EnableAsync
@ComponentScan("com.baeldung.web3j")
public class AppConfig implements WebMvcConfigurer {
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
/**
* Static resource locations including themes
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**/*")
.addResourceLocations("/", "/resources/")
.setCachePeriod(3600)
.resourceChain(true)
.addResolver(new PathResourceResolver());
}
/**
* View resolver for JSP
*/
@Bean
public UrlBasedViewResolver viewResolver() {
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
/**
* Configuration for async thread bean
*
* More: https://docs.spring.io/autorepo/docs/spring-framework/5.0.3.RELEASE/javadoc-api/org/springframework/scheduling/SchedulingTaskExecutor.html
*/
@Bean
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("CsvThread");
executor.initialize();
return executor;
}
}

View File

@ -0,0 +1,28 @@
package com.baeldung.web3j.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
//AbstractDispatcherServletInitializer override DEFAULT_SERVLET_NAME
@Override
protected String getServletName() {
return "dispatcher";
}
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{AppConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.web3j.constants;
public class Constants {
public static final String API_BLOCK = "/api/block";
public static final String API_ACCOUNTS = "/api/accounts";
public static final String API_TRANSACTIONS = "/api/transactions";
public static final String API_BALANCE = "/api/balance";
public static final String GENERIC_EXCEPTION = "Exception encountered!";
public static final String PLEASE_SUPPLY_REAL_DATA = "Please Supply Real Data!";
public static final String DEFAULT_ADDRESS = "0x281055afc982d96fab65b3a49cac8b878184cb16";
public static final String DEFAULT_CONTRACT_ADDRESS = "00000000000000000000";
}

View File

@ -0,0 +1,74 @@
package com.baeldung.web3j.contracts;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.RemoteCall;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.tx.Contract;
import org.web3j.tx.TransactionManager;
/**
* <p>Auto generated code.
* <p><strong>Do not modify!</strong>
* <p>Please use the <a href="https://docs.web3j.io/command_line.html">web3j command line tools</a>,
* or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the
* <a href="https://github.com/web3j/web3j/tree/master/codegen">codegen module</a> to update.
*
* <p>Generated with web3j version 3.3.1.
*/
public class Example extends Contract {
private static final String BINARY = "0x60606040523415600e57600080fd5b60848061001c6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b818dacd146044575b600080fd5b3415604e57600080fd5b60546056565b005b5600a165627a7a72305820bebcbbdf06550591bc772dfcb0eadc842f95953869feb7a9528bac91487d95240029";
protected static final HashMap<String, String> _addresses;
static {
_addresses = new HashMap<>();
}
protected Example(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
}
protected Example(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
}
public static RemoteCall<Example> deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
return deployRemoteCall(Example.class, web3j, credentials, gasPrice, gasLimit, BINARY, "");
}
public static RemoteCall<Example> deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
return deployRemoteCall(Example.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "");
}
public RemoteCall<TransactionReceipt> ExampleFunction() {
final Function function = new Function(
"ExampleFunction",
Arrays.<Type>asList(),
Collections.<TypeReference<?>>emptyList());
return executeRemoteCallTransaction(function);
}
public static Example load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
return new Example(contractAddress, web3j, credentials, gasPrice, gasLimit);
}
public static Example load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
return new Example(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
}
protected String getStaticDeployedAddress(String networkId) {
return _addresses.get(networkId);
}
public static String getPreviouslyDeployedAddress(String networkId) {
return _addresses.get(networkId);
}
}

View File

@ -0,0 +1,103 @@
package com.baeldung.web3j.controllers;
import com.baeldung.web3j.constants.Constants;
import com.baeldung.web3j.helpers.TimeHelper;
import com.baeldung.web3j.services.Web3Service;
import com.baeldung.web3j.transfers.ResponseTransfer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.web3j.protocol.core.methods.response.EthAccounts;
import org.web3j.protocol.core.methods.response.EthBlockNumber;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import java.time.Instant;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import static com.baeldung.web3j.constants.Constants.GENERIC_EXCEPTION;
@RestController
public class EthereumRestController {
@Autowired
Web3Service web3Service;
@RequestMapping(value = Constants.API_BLOCK, method = RequestMethod.GET)
public Future<ResponseTransfer> getBlock() {
ResponseTransfer responseTransfer = new ResponseTransfer();
Instant start = TimeHelper.start();
return CompletableFuture.supplyAsync(() -> {
try {
CompletableFuture<EthBlockNumber> result = web3Service.getBlockNumber();
responseTransfer.setMessage(result.get().toString());
} catch (Exception e) {
responseTransfer.setMessage(GENERIC_EXCEPTION);
}
return responseTransfer;
}).thenApplyAsync(result -> {
result.setPerformance(TimeHelper.stop(start));
return result;
});
}
@RequestMapping(value = Constants.API_ACCOUNTS, method = RequestMethod.GET)
public Future<ResponseTransfer> getAccounts() {
ResponseTransfer responseTransfer = new ResponseTransfer();
Instant start = TimeHelper.start();
return CompletableFuture.supplyAsync(() -> {
try {
CompletableFuture<EthAccounts> result = web3Service.getEthAccounts();
responseTransfer.setMessage(result.get().toString());
} catch (Exception e) {
responseTransfer.setMessage(GENERIC_EXCEPTION);
}
return responseTransfer;
}).thenApplyAsync(result -> {
result.setPerformance(TimeHelper.stop(start));
return result;
});
}
@RequestMapping(value = Constants.API_TRANSACTIONS, method = RequestMethod.GET)
public Future<ResponseTransfer> getTransactions() {
ResponseTransfer responseTransfer = new ResponseTransfer();
Instant start = TimeHelper.start();
return CompletableFuture.supplyAsync(() -> {
try {
CompletableFuture<EthGetTransactionCount> result = web3Service.getTransactionCount();
responseTransfer.setMessage(result.get().toString());
} catch (Exception e) {
responseTransfer.setMessage(GENERIC_EXCEPTION);
}
return responseTransfer;
}).thenApplyAsync(result -> {
result.setPerformance(TimeHelper.stop(start));
return result;
});
}
@RequestMapping(value = Constants.API_BALANCE, method = RequestMethod.GET)
public Future<ResponseTransfer> getBalance() {
ResponseTransfer responseTransfer = new ResponseTransfer();
Instant start = TimeHelper.start();
return CompletableFuture.supplyAsync(() -> {
try {
CompletableFuture<EthGetBalance> result = web3Service.getEthBalance();
responseTransfer.setMessage(result.get().toString());
} catch (Exception e) {
responseTransfer.setMessage(GENERIC_EXCEPTION);
}
return responseTransfer;
}).thenApplyAsync(result -> {
result.setPerformance(TimeHelper.stop(start));
return result;
});
}
}

View File

@ -0,0 +1,16 @@
package com.baeldung.web3j.helpers;
import java.time.Duration;
import java.time.Instant;
public class TimeHelper {
public static Instant start() {
return Instant.now();
}
public static Duration stop(Instant start) {
Instant end = Instant.now();
return Duration.between(start, end);
}
}

View File

@ -0,0 +1,156 @@
package com.baeldung.web3j.services;
import com.baeldung.web3j.contracts.Example;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.datatypes.Function;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.WalletUtils;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.EthAccounts;
import org.web3j.protocol.core.methods.response.EthBlockNumber;
import org.web3j.protocol.core.methods.response.EthGetBalance;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.Contract;
import org.web3j.tx.ManagedTransaction;
import java.io.File;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static com.baeldung.web3j.constants.Constants.DEFAULT_ADDRESS;
import static com.baeldung.web3j.constants.Constants.GENERIC_EXCEPTION;
import static com.baeldung.web3j.constants.Constants.PLEASE_SUPPLY_REAL_DATA;
@Service
public class Web3Service {
private Web3j web3j = Web3j.build(new HttpService());
//Create and Init the default Web3J connection
public void customInit(String provider) {
this.web3j = Web3j.build(new HttpService(provider));
}
//Convert to and from supplied contract ABI bytecode
public static String toBinary(String bytecode) {
return bytecode.replaceFirst("^0x", "");
}
public static String toByteCode(String binary) {
return "0x" + binary;
}
@Async
public CompletableFuture<EthBlockNumber> getBlockNumber() {
EthBlockNumber result = new EthBlockNumber();
try {
this.web3j.ethBlockNumber().sendAsync().thenApply(r -> r.getBlockNumber());
} catch (Exception ex) {
System.out.println(GENERIC_EXCEPTION);
}
return CompletableFuture.completedFuture(result);
}
@Async
public CompletableFuture<EthAccounts> getEthAccounts() {
EthAccounts result = new EthAccounts();
try {
this.web3j.ethAccounts().sendAsync().thenApply(r -> r.getAccounts());
} catch (Exception ex) {
System.out.println(GENERIC_EXCEPTION);
}
return CompletableFuture.completedFuture(result);
}
@Async
public CompletableFuture<EthGetTransactionCount> getTransactionCount() {
EthGetTransactionCount result = new EthGetTransactionCount();
try {
this.web3j.ethGetTransactionCount(DEFAULT_ADDRESS, DefaultBlockParameter.valueOf("latest")).sendAsync().thenApply(r -> r.getTransactionCount());
} catch (Exception ex) {
System.out.println(GENERIC_EXCEPTION);
}
return CompletableFuture.completedFuture(result);
}
@Async
public CompletableFuture<EthGetBalance> getEthBalance() {
EthGetBalance result = new EthGetBalance();
try {
this.web3j.ethGetBalance(DEFAULT_ADDRESS, DefaultBlockParameter.valueOf("latest")).sendAsync().thenApply(r -> r.getBalance());
} catch (Exception ex) {
System.out.println(GENERIC_EXCEPTION);
}
return CompletableFuture.completedFuture(result);
}
@Async
public CompletableFuture<String> fromScratchContractExample() {
String contractAddress = "";
try {
//Create a wallet
WalletUtils.generateNewWalletFile("PASSWORD", new File("/path/to/destination"), true);
//Load the credentials from it
Credentials credentials = WalletUtils.loadCredentials("PASSWORD", "/path/to/walletfile");
//Deploy contract to address specified by wallet
Example contract = Example.deploy(this.web3j,
credentials,
ManagedTransaction.GAS_PRICE,
Contract.GAS_LIMIT).send();
//Het the address
contractAddress = contract.getContractAddress();
} catch (Exception ex) {
System.out.println(PLEASE_SUPPLY_REAL_DATA);
return CompletableFuture.completedFuture(PLEASE_SUPPLY_REAL_DATA);
}
return CompletableFuture.completedFuture(contractAddress);
}
@Async
public CompletableFuture<String> sendTx() {
String transactionHash = "";
try {
List inputParams = new ArrayList();
List outputParams = new ArrayList();
Function function = new Function("fuctionName", inputParams, outputParams);
String encodedFunction = FunctionEncoder.encode(function);
BigInteger nonce = BigInteger.valueOf(100);
BigInteger gasprice = BigInteger.valueOf(100);
BigInteger gaslimit = BigInteger.valueOf(100);
Transaction transaction = Transaction.createFunctionCallTransaction("FROM_ADDRESS", nonce, gasprice, gaslimit, "TO_ADDRESS", encodedFunction);
org.web3j.protocol.core.methods.response.EthSendTransaction transactionResponse = web3j.ethSendTransaction(transaction).sendAsync().get();
transactionHash = transactionResponse.getTransactionHash();
} catch (Exception ex) {
System.out.println(PLEASE_SUPPLY_REAL_DATA);
return CompletableFuture.completedFuture(PLEASE_SUPPLY_REAL_DATA);
}
return CompletableFuture.completedFuture(transactionHash);
}
}

View File

@ -0,0 +1,28 @@
package com.baeldung.web3j.transfers;
import java.time.Duration;
public class ResponseTransfer {
public ResponseTransfer() {}
private Duration performance;
private String message;
public Duration getPerformance() {
return performance;
}
public void setPerformance(Duration performance) {
this.performance = performance;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

View File

View File

@ -0,0 +1,78 @@
package com.baeldung.web3j.controllers;
import com.baeldung.web3j.config.AppConfig;
import com.baeldung.web3j.constants.Constants;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {AppConfig.class})
@WebAppConfiguration
public class EthereumRestControllerIntegrationTest {
private MockMvc mockMvc;
private void constructAsyncTest(String endpoint) {
try {
MvcResult asyncResult = mockMvc
.perform(get(endpoint))
.andReturn();
mockMvc.perform(asyncDispatch(asyncResult))
.andDo(print())
.andExpect(status().isOk());
} catch (Exception e) {
System.out.println("Exception: " + e);
}
}
@Autowired
private WebApplicationContext wac;
@Before
public void preTest() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void accounts() {
constructAsyncTest(Constants.API_ACCOUNTS);
}
@Test
public void transactions() {
constructAsyncTest(Constants.API_TRANSACTIONS);
}
@Test
public void block() {
constructAsyncTest(Constants.API_BLOCK);
}
@Test
public void balance() {
constructAsyncTest(Constants.API_BALANCE);
}
@After
public void postTest() {
mockMvc = null;
}
}

View File

@ -0,0 +1,76 @@
package com.baeldung.web3j.controllers;
import com.baeldung.web3j.constants.Constants;
import com.baeldung.web3j.services.Web3Service;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
public class EthereumRestControllerUnitTest {
private MockMvc mockMvc;
private void constructAsyncTest(String endpoint) {
try {
MvcResult asyncResult = mockMvc
.perform(get(endpoint))
.andReturn();
mockMvc.perform(asyncDispatch(asyncResult))
.andDo(print())
.andExpect(status().isOk());
} catch (Exception e) {
System.out.println("Exception: " + e);
}
}
@Mock
private Web3Service web3Service;
@InjectMocks
private EthereumRestController ethereumRestController;
@Before
public void preTest() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(ethereumRestController).build();
}
@Test
public void accounts() {
constructAsyncTest(Constants.API_ACCOUNTS);
}
@Test
public void transactions() {
constructAsyncTest(Constants.API_TRANSACTIONS);
}
@Test
public void block() {
constructAsyncTest(Constants.API_BLOCK);
}
@Test
public void balance() {
constructAsyncTest(Constants.API_BALANCE);
}
@After
public void postTest() {
mockMvc = null;
}
}

View File

@ -0,0 +1,37 @@
package com.baeldung.web3j.services;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.concurrent.CompletableFuture;
import static com.baeldung.web3j.constants.Constants.PLEASE_SUPPLY_REAL_DATA;
public class EthereumContractUnitTest {
private Web3Service web3Service;
@Before
public void setup() {
web3Service = new Web3Service();
}
@Test
public void testContract() {
CompletableFuture<String> result = web3Service.fromScratchContractExample();
assert (result instanceof CompletableFuture);
}
@Test
public void sendTx() {
CompletableFuture<String> result = web3Service.sendTx();
assert (result instanceof CompletableFuture);
}
@After
public void cleanup() {
}
}