This is the contract that resides in a privacy group:

pragma solidity 0.7.4;

import "./Coin.sol";

contract PrivateTransfer {

    Coin coin;

    constructor(Coin _coin) {
        coin = _coin;

    function transfer(address from, address to, uint amount) external {
        coin.subBalance(from, amount);
        coin.addBalance(to, amount);

    function getBal() external view returns (uint) {
        return coin.getBalanceOfCB();

And, this is the public smart contract:

import "./SafeMath.sol";

contract Coin {

    using SafeMath for uint256;

    mapping(address => uint) private balances;

    // some more code here

    function addBalance(address bank, uint amount) external {
        balances[bank] = balances[bank].add(amount);

    function subBalance(address bank, uint amount) external {
        require(balances[bank] >= amount, "Insufficient balance.");

        balances[bank] = balances[bank].sub(amount);

    function getBalanceOfCB() external view returns (uint) {
        return balances[auth.centralBankAddress()];

    function issue(uint amount) external {
        balances[msg.sender] = balances[msg.sender].add(amount);


Finally, here is my web3j code:

final ContractGasPrice contractGasPrice = new ContractGasPrice();
final BesuPrivacyGasProvider besuPrivacyGasProvider = new BesuPrivacyGasProvider(BigInteger.ZERO);

final Credentials CENTRAL_BANK = Credentials.create("8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63");
final Credentials ALPHA_BANK = Credentials.create("c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3");
final Credentials OMEGA_BANK = Credentials.create("ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f");

final Base64String ENCLAVE_KEY_CENTRAL_BANK = Base64String.wrap("ApXYaIWJ8Mfm18YPHNdWLfZfdttcxfXPGOmKyshsC3g=");
final Base64String ENCLAVE_KEY_ALPHA_BANK = Base64String.wrap("vyGLN7JpYuk04z/aWlHIdAHXcdBj0I1F/BVlEEElSiU=");
final Base64String ENCLAVE_KEY_OMEGA_BANK = Base64String.wrap("pAjuacbr+85FEy4/f56k81CaJ2nwsm8GgqywzQPaM1w=");

Besu nodeCentralBank = Besu.build(new HttpService("http://localhost:8545"));
Besu nodeAlphaBank = Besu.build(new HttpService("http://localhost:8546"));
Besu nodeOmegaBank = Besu.build(new HttpService("http://localhost:8547"));

Web3j web3j = Web3j.build(new HttpService());

// Create a privacy group
final Base64String privacyGroupId = nodeCentralBank.privCreatePrivacyGroup(Arrays.asList(ENCLAVE_KEY_CENTRAL_BANK, ENCLAVE_KEY_ALPHA_BANK), "bankA_bankB", "desc").send().getPrivacyGroupId();
System.out.println("Privacy Group created with Id: " + privacyGroupId.toString());

PrivateTransactionManager transactionManagerBankA = new BesuPrivateTransactionManager(nodeCentralBank, besuPrivacyGasProvider, CENTRAL_BANK, Long.decode("0x7e2"), ENCLAVE_KEY_CENTRAL_BANK, privacyGroupId);

// Deploy the public contracts
System.out.println("Deploying Contracts...");
Auth auth = Auth.deploy(web3j, CENTRAL_BANK, contractGasPrice).send();
Coin coin = Coin.deploy(web3j, CENTRAL_BANK, contractGasPrice, auth.getContractAddress()).send();

// Deploy the private contract
PrivateTransfer privateTransferBankA = PrivateTransfer.deploy(web3j, transactionManagerBankA, besuPrivacyGasProvider, coin.getContractAddress()).send();

// Perform the transfers
System.out.println(coin.issue(BigInteger.TEN).send());  // works
System.out.println(coin.getBalanceOfCB().send());   // works
System.out.println("PT Bal: " + privateTransferBankA.getBal().send());  // fails
System.out.println(privateTransferBankA.transfer(CENTRAL_BANK.getAddress(), ALPHA_BANK.getAddress(), BigInteger.ONE).send());  // fails
System.out.println("PT Bal: " + privateTransferBankA.getBal().send());  // fails

The lines commented with fails doesn't run and throw this error:

Transaction null has failed with status: 0x0. Gas used: unknown. Revert reason: '0x'.

I ran the contracts on Remix and there they work fine. But, of course, I couldn't test the privacy group aspect of this. Can anyone please point what is that I am missing or is there something wrong with the web3j library?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.