1

I am trying to send Plasma tokens in testnet but unfortunately misunderstand how I should create transaction properly.

I try to create tx like this:

String privateKeyString = "xxx";
BigInteger bigInteger = new BigInteger(privateKeyString, 16);
ECKey ecKey = ECKey.fromPrivate(bigInteger);

String plasmaContrtactAddress = "0x95D7321EdCe519419ba1DbC60A89bAfbF55EAC0D";

Transaction ethTx = new Transaction(
     nonce,
     gasPrice,
     gasLimit,
     plasmaContrtactAddress,
     value,
     data);

ethTx.sign(ecKey)

But how I should to create byte[] data properly? Here is json abi interface for plasma:

[{"constant":true,"inputs":[],"name":"message","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ViewerStatus","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ViewerValue","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenRateEther","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"Login","type":"string"}],"name":"registrationFromLogin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"MainAccount","type":"address"},{"name":"ActiveAliasAccount","type":"bool"},{"name":"ActiveMainAccount","type":"bool"},{"name":"PromilleDeposit","type":"uint256"},{"name":"DeleteMainAccount","type":"bool"}],"name":"setupAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"NewPIN","type":"uint256"}],"name":"setupAccountPIN","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"deleteLogin","type":"string"},{"name":"newLogin","type":"string"}],"name":"setupLoginVipAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"MainAccount","type":"address"}],"name":"setupAliasAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"Account","type":"address"},{"name":"Freezen","type":"bool"}],"name":"frozenSubAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"Account","type":"address"}],"name":"buyVipStatusPay","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"buyTokenPay","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"toTransferETHER","type":"address"},{"name":"microToken","type":"uint256"},{"name":"SellDeposit","type":"bool"}],"name":"sellToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"login","type":"string"},{"name":"password","type":"string"}],"name":"depositaryPay","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"Account","type":"address"},{"name":"microToken","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"Login","type":"string"},{"name":"PIN","type":"uint256"}],"name":"transferFromLoginPay","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"Login","type":"string"}],"name":"transferToLoginPay","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"microToken","type":"uint256"}],"name":"returnDepositToBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"SubAccount","type":"address"},{"name":"PIN","type":"uint256"}],"name":"transferProtectPay","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"PIN","type":"uint256"}],"name":"unblockTransferProtectPay","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"SubAccount","type":"address"},{"name":"pinSubAccount","type":"uint256"},{"name":"promilleRefund","type":"uint256"}],"name":"transferRefundSubAccountPay","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"MainAccount","type":"address"},{"name":"pinMainAccount","type":"uint256"},{"name":"SubAccount","type":"address"},{"name":"pinSubAccount","type":"uint256"},{"name":"promilleReferee","type":"uint256"}],"name":"refereeTransferProtect","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"VipAccount","type":"bool"},{"name":"ActiveAliasAccount","type":"bool"},{"name":"ActiveMainAccount","type":"bool"},{"name":"MainAccount","type":"address"},{"name":"MyReferralAccount","type":"address"}],"name":"MyAccountStatus","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"Deposit","type":"bool"},{"name":"PromilleDeposit","type":"bool"},{"name":"ZoneToken","type":"bool"}],"name":"MyAccountValue","outputs":[{"name":"value","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"myMessage","type":"string"}],"name":"advertisingPay","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"burnToken","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"microToken","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":false,"name":"Message","type":"string"}],"name":"Advertising","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":false,"name":"microToken","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"PriceVipAccountMicroEther","type":"uint256"},{"indexed":false,"name":"TransferTokensFeeInPromille","type":"uint256"},{"indexed":false,"name":"BonusForZone1InPromille","type":"uint256"},{"indexed":false,"name":"BonusForZone2InPromille","type":"uint256"},{"indexed":false,"name":"BonusForZone3InPromille","type":"uint256"},{"indexed":false,"name":"BonusForZone4InPromille","type":"uint256"},{"indexed":false,"name":"BonusForZone5InPromille","type":"uint256"}],"name":"OptionsContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"microETHER","type":"uint256"}],"name":"TokenSellingRate","type":"event"}]

And the receiver's address:

0xEA8e872b51d76D690E4779F9AC403cf18B8460Fe

How can I implement this with ethereumJ library or manualy, whatever?

UPDATED:

First of all - thanks to cleanunicorn for the answer below.

In addition to the code above - my version of the byte[] data for transferring tokens:

public byte[] createTransferData(String addressTo, @NonNull String value) {

    String functionSig = "0xa9059cbb"; // transfer
    byte[] functionBytes = ByteUtil.hexStringToBytes(functionSig);

    byte[] addressSrc = Hex.decode(Numeric.cleanHexPrefix(addressTo));
    byte[] emptyBytesAddress = new byte[32 - addressSrc.length];
    addressSrc = ByteUtil.merge(emptyBytesAddress, addressSrc);

    BigInteger bigInteger = new BigInteger(value);
    byte[] valueSrc = ByteUtil.hexStringToBytes(bigInteger.toString(16));

    // here we should calculate bytes' count of our hex value
    // and if we are out of bounds of the count/32 - we should provide 32 bytes extra
    int additionalEmptyBytes = 32 - (valueSrc.length - (valueSrc.length / 32) * 32);
    if (additionalEmptyBytes != 0) {
        valueSrc = ByteUtil.merge(new byte[additionalEmptyBytes], valueSrc);
    }

    return ByteUtil.merge(functionBytes, addressSrc, valueSrc);
}

Here is ByteUtils class.

If someone know how to implement it via ethereumJ or maybe faster - please provide your answer.

1 Answer 1

0

I don't have experience with ethereumJ but in order to send tokens you need to send a transaction to the tokens smart contract.

It seems like you are trying to interact with the Plasma token contract.

The data parameter needs to have 3 components

  • signature of the function you are calling

it's the signature of the transfer(address,uint256) which translates to

0xa9059cbb

  • the destination of the tokens

your destination is 0xEA8e872b51d76D690E4779F9AC403cf18B8460Fe and this needs to be 32 byte padded

000000000000000000000000ea8e872b51d76d690e4779f9ac403cf18b8460fe

  • how many tokens are sent

let's assume you are trying to send 1000 tokens, in hex this means 0x3e8, again 32 byte padded

00000000000000000000000000000000000000000000000000000000000003e8


Putting it all together your data parameter should look like this

0xa9059cbb000000000000000000000000ea8e872b51d76d690e4779f9ac403cf18b8460fe00000000000000000000000000000000000000000000000000000000000003e8

There is an easy to use tool to help you manually figure this out

https://jimkberry.github.io/eth-contractor/

And there is another tool that helps you find out signatures for any ABI or function you provide

https://github.com/cleanunicorn/abi2signature

1
  • Thank you so much for your answer and excellent links inside! You pushed me to move in the right direction :) but if I'm not mistaken - initial bytes' count for address's and tokens' value is 32 bytes (64 chars). If I`m right please edit your unswer. All of my other calculations and thoughts I will put under the "Updated" block of my question. Commented Apr 5, 2018 at 13:11

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.