1

Sending from Account A to B is not working in my implementation. The docs provided by stellar for Java are straight forward but I have been receiving a BaseEncodingException when trying to sign the transaction. My code is identical to that on the Java docs for stellar, am I missing something here?

Also, checks are done on both accounts to ensure they are not-null and have proper funds for the transaction to go through.

KeyPair destination = KeyPair.fromAccountId(request.getSource());
        KeyPair source = KeyPair.fromSecretSeed(ServerInfo.PRIVATE_KEY_MAIN_ACCOUNT);
        Transaction trns = null;
        try {
            AccountResponse sourceAccount = checkForFunds(request);
            trns = new Transaction.Builder(sourceAccount, Network.TESTNET)
                    .addOperation(new PaymentOperation
                            .Builder(destination.getPublicKey().toString(), new AssetTypeNative(), request.getAmount())
                            .build())
                    .addMemo(Memo.text("Test Transaction"))
                    .setTimeout(180)
                    .setOperationFee(100)
                    .build();
            System.out.println(".buildTransaction() - transaction created: " + trns.hashCode());
            // Sign the transaction to prove you are actually the person sending it.
            trns.sign(source);
            return trns;
        } catch (IOException e) {
            throw e;
        }

1 Answer 1

3

You need to pass the account id encoding of the public key to the PaymentOperation builder. In other words, instead of passing destination.getPublicKey().toString() to the builder you should be passing in destination.getAccountId(). However, looking at your entire code snippet, it seems like you already have the destination account id.

I believe your code can be simplified to:

        String destination = request.getSource());
        KeyPair source = KeyPair.fromSecretSeed(ServerInfo.PRIVATE_KEY_MAIN_ACCOUNT);
        Transaction trns = null;
        try {
            AccountResponse sourceAccount = checkForFunds(request);
            trns = new Transaction.Builder(sourceAccount, Network.TESTNET)
                    .addOperation(new PaymentOperation
                            .Builder(destination, new AssetTypeNative(), request.getAmount())
                            .build())
                    .addMemo(Memo.text("Test Transaction"))
                    .setTimeout(180)
                    .setOperationFee(100)
                    .build();
            System.out.println(".buildTransaction() - transaction created: " + trns.hashCode());
            // Sign the transaction to prove you are actually the person sending it.
            trns.sign(source);
            return trns;
        } catch (IOException e) {
            throw e;
        }

The difference between destination.getAccountId() and destination.getPublicKey().toString() is that destination.getPublicKey() returns the underlying bytes of the Ed25519 public key. When you call toString() on a byte array in Java it will invoke the default toString() implementation which returns something like [B@1f57539:

    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }


destination.getAccountId() will return an ASCII encoding of the public key. The specifics of the encoding are described here: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0023.md

1
  • Thanks a bunch! Transaction works now, Cheers! Commented Apr 28, 2020 at 15:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.