Skip to content

Commit

Permalink
Merge pull request #3 from ghareeb-falazi/support-fabric-sc
Browse files Browse the repository at this point in the history
Support Hyperledger Fabric Smart Contract Invocation
  • Loading branch information
ghareeb-falazi authored Sep 17, 2019
2 parents 05ef324 + 2361ce1 commit dc17fda
Show file tree
Hide file tree
Showing 26 changed files with 500 additions and 239 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ build/src/main/resources/static/**/*
# IDEs and editors
.idea
*.iws
*.iml
BlockchainAccessLayer.iml
*.ipr
.project
.classpath
Expand Down Expand Up @@ -54,3 +54,4 @@ testem.log
# System Files
.DS_Store
Thumbs.db
*.iml
24 changes: 20 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ Furthermore, the layer directly accesses the keystore file holding the private k
and receiving transactions.
On the other hand, the BAL also needs to be able to communicate with a [bitcoind node](https://bitcoin.org/en/bitcoin-core/)
which has RPC connections enabled.
The configuration file that can be used to configure these aspects (communication with a geth, and a bitcoind nodes and the local Ethereum keystore) can be found
[here](src/main/resources/config.properties)
Finally, it needs to communicate with a [Hyperledger Fabric](https://hyperledger-fabric.readthedocs.io/) network.
The configuration file that can be used to configure these aspects (communication with the Fabric network, a geth, and a bitcoind nodes etc.) can be found
[here](src/main/resources/gatewayConfiguration.json)


## Building and Deployment
Expand Down Expand Up @@ -90,7 +91,7 @@ In order to connect a _bitcoind_ node to [testnet3](https://en.bitcoin.it/wiki/T

1. [Install bitcoind](https://bitcoin.org/en/download):
this differs depending on your operating system. For the installation instructions on Ubuntu you can follow [these steps](https://gist.github.com/rjmacarthy/b56497a81a6497bfabb1).
2. Configure _bitcoind_: This can be done by editing the bitcoin.conf file. The configuration file we used can be found [here](src/main/resources/bitcoin.conf).
2. Configure _bitcoind_: This can be done by editing and using the [`bitcoin.conf`](src/main/resources/bitcoin.conf) file when starting the bicoind daemon.
The configuration allows external rpc-based communication with the node, and instructs it to communicate with the testnet rather than
the mainnet. Furthermore, it orders the node to build an index on the blockchain that allows querying even historic transactions. Finally, it instructs the node
to send notifications to the BAL when it detects a new block or a transaction addressed to one of the Bitcoin wallet's addresses.
Expand All @@ -105,6 +106,21 @@ bitcoin-cli -getinfo -rpcconnect=<ip address of the node> -rpcport=<port of the
## Setting-up a Hyperledger Fabric Network
Please follow these steps [Fabric Setup](https://hyperledger-fabric.readthedocs.io/en/latest/getting_started.html)

### Note
The included Fabric unit test depends on the [FabCar official example](https://hyperledger-fabric.readthedocs.io/en/release-1.4/write_first_app.html), so in order to run it
ensure the following:

1. follow the steps of running the first Fabric tutorial at: https://hyperledger-fabric.readthedocs.io/en/release-1.4/write_first_app.html (use the javascript smart contract).
2. execute the enrollAdmin.js and the registerUser.js node programs.
3. alter the local hosts file by adding the following entries:
* 127.0.0.1 orderer.example.com
* 127.0.0.1 peer0.org1.example.com
* 127.0.0.1 peer0.org2.example.com
* 127.0.0.1 peer1.org1.example.com
* 127.0.0.1 peer1.org2.example.com

This ensures that the SDK is able to find the orderer and network peers.

## Case Study (For BlockME)
The case study invloves a cryptocurrency exchange service utilitzing the blockchain access layer.
The exchange uses the following simplified BlockME-model:
Expand All @@ -114,7 +130,7 @@ The exchange uses the following simplified BlockME-model:
Please follow these instructions:
1. Configure and run a local geth node (see above).
2. Configure and run a local bitcoind node (see above).
3. Configure the blockchain access layer to communicate with this node and to read a valid Ethereum keystore file (see above)
3. Configure the blockchain access layer to communicate with these nodes (see the file [gatewayConfiguration.json](src/main/resources/gatewayConfiguration.json)).
4. Build and deploy the blockchain access layer (see above).
5. Configure, build, deploy and initiate the process model ([see this Github repository for instructions](https://github.com/ghareeb-falazi/BlockME-UseCase))
6. Send ethers to the address maintained by the blockchain access layer (the first address of the keyfile mentioned in step 3).
Expand Down
27 changes: 23 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@
<id>local-maven-repo</id>
<url>file:///${project.basedir}/local-maven-repo</url>
</repository>

<!-- The snapshots repository of the Heyperledger fabric java libraries.-->
<repository>
<id>hyperledger-snapshots-repo</id>
<url>https://nexus.hyperledger.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>


Expand All @@ -47,9 +59,9 @@

<dependencies>
<dependency>
<groupId>org.hyperledger.fabric-sdk-java</groupId>
<artifactId>fabric-sdk-java</artifactId>
<version>1.4.1</version>
<groupId>org.hyperledger.fabric-gateway-java</groupId>
<artifactId>fabric-gateway-java</artifactId>
<version>1.4.0-SNAPSHOT</version>
</dependency>

<dependency>
Expand Down Expand Up @@ -90,6 +102,13 @@
<version>4.2.0</version>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>com.neemre.btcd-cli4j</groupId>
<artifactId>btcd-cli4j-core</artifactId>
Expand Down Expand Up @@ -179,7 +198,7 @@
</dependencies>
<properties>
<jersey.version>2.9.1</jersey.version>
<jackson.version>2.8.5</jackson.version>
<jackson.version>[2.9.9.2,)</jackson.version>
<org.slf4j>1.7.25</org.slf4j>
<ch.qos.logback.logback-classic.version>1.2.3</ch.qos.logback.logback-classic.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@

import blockchains.iaas.uni.stuttgart.de.adaptation.adapters.bitcoin.BitcoinAdapter;
import blockchains.iaas.uni.stuttgart.de.adaptation.adapters.ethereum.EthereumAdapter;
import blockchains.iaas.uni.stuttgart.de.adaptation.adapters.fabric.FabricAdapter;
import blockchains.iaas.uni.stuttgart.de.adaptation.interfaces.BlockchainAdapter;
import blockchains.iaas.uni.stuttgart.de.adaptation.utils.PoWConfidenceCalculator;
import blockchains.iaas.uni.stuttgart.de.gateways.AbstractGateway;
import blockchains.iaas.uni.stuttgart.de.gateways.BitcoinGateway;
import blockchains.iaas.uni.stuttgart.de.gateways.EthereumGateway;
import blockchains.iaas.uni.stuttgart.de.gateways.FabricGateway;
import blockchains.iaas.uni.stuttgart.de.gateways.GatewayManager;
import com.neemre.btcdcli4j.core.BitcoindException;
import com.neemre.btcdcli4j.core.CommunicationException;
Expand Down Expand Up @@ -53,6 +55,8 @@ public BlockchainAdapter createBlockchainAdapter(String gatewayKey) throws Excep
return createEthereumAdapter((EthereumGateway) gateway);
} else if (gateway instanceof BitcoinGateway) {
return createBitcoinAdapter((BitcoinGateway) gateway);
} else if (gateway instanceof FabricGateway) {
return createFabricAdapter((FabricGateway) gateway);
} else {
log.error("Invalid gateway type!");
return null;
Expand Down Expand Up @@ -86,4 +90,12 @@ private BitcoinAdapter createBitcoinAdapter(BitcoinGateway gateway) throws Bitco

return result;
}

private FabricAdapter createFabricAdapter(FabricGateway gateway) {
return FabricAdapter.builder()
.connectionProfilePath(gateway.getConnectionProfilePath())
.userName(gateway.getUserName())
.walletPath(gateway.getWalletPath())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import blockchains.iaas.uni.stuttgart.de.exceptions.InvalidTransactionException;
import blockchains.iaas.uni.stuttgart.de.model.Block;
import blockchains.iaas.uni.stuttgart.de.model.SmartContractFunctionArgument;
import blockchains.iaas.uni.stuttgart.de.model.LinearChainTransaction;
import blockchains.iaas.uni.stuttgart.de.model.Transaction;
import blockchains.iaas.uni.stuttgart.de.model.TransactionState;
import com.neemre.btcdcli4j.core.BitcoindException;
Expand Down Expand Up @@ -78,12 +79,12 @@ private static Block generateBlockObject(com.neemre.btcdcli4j.core.domain.Block
return result;
}

private Transaction generateTransactionObject(com.neemre.btcdcli4j.core.domain.Transaction transaction, Block block, boolean detectSender) {
Transaction result = null;
private LinearChainTransaction generateTransactionObject(com.neemre.btcdcli4j.core.domain.Transaction transaction, Block block, boolean detectSender) {
LinearChainTransaction result = null;
// there might be multi-inputs and/or multi-outputs for a transactions, we only consider the first input/output affecting the wallet
if (transaction.getDetails().size() > 0) {
final PaymentOverview overview = transaction.getDetails().get(0);
result = new Transaction();
result = new LinearChainTransaction();
result.setTo(overview.getAddress());
result.setBlock(block);
result.setTransactionHash(transaction.getTxId());
Expand Down Expand Up @@ -124,13 +125,13 @@ void handleDetectedState(final com.neemre.btcdcli4j.core.domain.Transaction tran
CompletableFuture<Transaction> future) {
// Only complete the future if we are interested in this event
if (Arrays.asList(interesting).contains(detectedState)) {
Transaction result = null;
LinearChainTransaction result;

if (transactionDetails != null) {
final Block myBlock = generateBlockObject(block);
result = generateTransactionObject(transactionDetails, myBlock, true);
} else {
result = new Transaction();
result = new LinearChainTransaction();
}

result.setState(detectedState);
Expand Down Expand Up @@ -194,7 +195,7 @@ public CompletableFuture<Transaction> submitTransaction(long waitFor, String rec
} else {
result = new CompletableFuture<>();
final com.neemre.btcdcli4j.core.domain.Transaction tx = client.getTransaction(transactionId);
final Transaction resultTx = generateTransactionObject(tx, null, true);
final LinearChainTransaction resultTx = generateTransactionObject(tx, null, true);
resultTx.setState(TransactionState.CONFIRMED);
result.complete(resultTx);
}
Expand Down Expand Up @@ -232,7 +233,7 @@ public void walletChanged(com.neemre.btcdcli4j.core.domain.Transaction transacti
return null;
});
} else {
final Transaction resultTx = generateTransactionObject(transaction, null, true);
final LinearChainTransaction resultTx = generateTransactionObject(transaction, null, true);
resultTx.setState(TransactionState.CONFIRMED);
subject.onNext(resultTx);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import blockchains.iaas.uni.stuttgart.de.exceptions.InvalidTransactionException;
import blockchains.iaas.uni.stuttgart.de.exceptions.InvokeSmartContractFunctionFailure;
import blockchains.iaas.uni.stuttgart.de.model.Block;
import blockchains.iaas.uni.stuttgart.de.model.LinearChainTransaction;
import blockchains.iaas.uni.stuttgart.de.model.SmartContractFunctionArgument;
import blockchains.iaas.uni.stuttgart.de.model.SmartContractFunctionParameter;
import blockchains.iaas.uni.stuttgart.de.model.Transaction;
Expand Down Expand Up @@ -365,7 +366,7 @@ private static void handleDetectedState(final Optional<org.web3j.protocol.core.m
CompletableFuture<Transaction> future) {
// Only complete the future if we are interested in this event
if (Arrays.asList(interesting).contains(detectedState)) {
final Transaction result = new Transaction();
final LinearChainTransaction result = new LinearChainTransaction();
result.setState(detectedState);

if (transactionDetails.isPresent()) {
Expand Down
Loading

0 comments on commit dc17fda

Please sign in to comment.