Transfer token

transfer token from miner 2 on Geth console by contract object

> eth.accounts
["0x4d0362700bcdc69e2e4e083c3f098ca55efd1119"]
> var contract = web3.eth.contract(abi)
undefined
> var instance = contract.at('0xf13c9660190749124ad90c8defc77cc6c5d36494');
undefined

> instance.symbol()
"YEN"

> instance.balanceOf('0xaeF72A6461e5392e9fa1537372b98701780a1819')
0

> instance.transfer('0xaeF72A6461e5392e9fa1537372b98701780a1819', web3.toWei(999, 'ether'))
Error: invalid address
    at web3.js:3930:15
    at web3.js:3756:20
    at web3.js:5025:28
    at map (<native code>)
    at web3.js:5024:12
    at web3.js:5050:18
    at web3.js:5075:23
    at web3.js:4137:16
    at apply (<native code>)
    at web3.js:4223:16

> instance.transfer('0xaeF72A6461e5392e9fa1537372b98701780a1819', web3.toWei(999, 'ether'), { from: eth.coinbase })
INFO [12-25|11:16:16] Submitted transaction                    fullhash=0x4a1d5b4de007e5232962ebd63976d24290295b6e00189b9a15a928bb17a47031 recipient=0xf13C9660190749124AD90C8dEfC77cC6c5D36494
"0x4a1d5b4de007e5232962ebd63976d24290295b6e00189b9a15a928bb17a47031"

> instance.balanceOf('0xaeF72A6461e5392e9fa1537372b98701780a1819')
999000000000000000000

> eth.getTransaction("0x4a1d5b4de007e5232962ebd63976d24290295b6e00189b9a15a928bb17a47031")
{
  blockHash: "0xa05f41a144e500df9d235b483fa8112df706b44fbcea1f40bdfd2dee7fde9722",
  blockNumber: 44,
  from: "0x4d0362700bcdc69e2e4e083c3f098ca55efd1119",
  gas: 90000,
  gasPrice: 18000000000,
  hash: "0x4a1d5b4de007e5232962ebd63976d24290295b6e00189b9a15a928bb17a47031",
  input: "0xa9059cbb000000000000000000000000aef72a6461e5392e9fa1537372b98701780a181900000000000000000000000000000000000000000000003627e8f712373c0000",
  nonce: 8,
  r: "0x5972ba41a88e662aca23d3324aa73244226a1f40b7a55861fab77222a49f6935",
  s: "0x1ad21dc1f96e288fd15284376ed4ee298363e4954fe41468dfdf232bfdca712",
  to: "0xf13c9660190749124ad90c8defc77cc6c5d36494",
  transactionIndex: 0,
  v: "0x11ba9",
  value: 0
}

> eth.getTransactionReceipt("0x4a1d5b4de007e5232962ebd63976d24290295b6e00189b9a15a928bb17a47031")
{
  blockHash: "0xa05f41a144e500df9d235b483fa8112df706b44fbcea1f40bdfd2dee7fde9722",
  blockNumber: 44,
  contractAddress: null,
  cumulativeGasUsed: 52111,
  from: "0x4d0362700bcdc69e2e4e083c3f098ca55efd1119",
  gasUsed: 52111,
  logs: [{
      address: "0xf13c9660190749124ad90c8defc77cc6c5d36494",
      blockHash: "0xa05f41a144e500df9d235b483fa8112df706b44fbcea1f40bdfd2dee7fde9722",
      blockNumber: 44,
      data: "0x00000000000000000000000000000000000000000000003627e8f712373c0000",
      logIndex: 0,
      removed: false,
      topics: ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x0000000000000000000000004d0362700bcdc69e2e4e083c3f098ca55efd1119", "0x000000000000000000000000aef72a6461e5392e9fa1537372b98701780a1819"],
      transactionHash: "0x4a1d5b4de007e5232962ebd63976d24290295b6e00189b9a15a928bb17a47031",
      transactionIndex: 0
  }],
  logsBloom: "0x00000200000000000000000500000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000002000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000",
  root: "0x0fc99e552cbeb92d44d8986a81631dabe3503c35a4eee7330f91d02832c57a1b",
  to: "0xf13c9660190749124ad90c8defc77cc6c5d36494",
  transactionHash: "0x4a1d5b4de007e5232962ebd63976d24290295b6e00189b9a15a928bb17a47031",
  transactionIndex: 0
}

using send raw transaction of JSON-RPC API

First, I have to hash the transfer(address _to, uint256 _value) and then take first ten letters to be the method Id.

> web3.sha3('transfer(address,uint256)').substring(0,10)
"0xa9059cbb"

And prefix to address with zero, hex the value.

> web3.toHex(web3.toWei(2.345, "ether"))
"0x208b1d135e4a8000"

Then append them to method id, to makes the input data.

static final String PLACEHOLDER = "000000000000000000000000";

String TRANSFER = "0xa9059cbb";

public static byte[] makeInputDataForTransferMethod(@NonNull String toAddress, @NonNull BigInteger valueInWei) {
  final String hexWithoutPrefix0x = removePrefix0x(toAddress);
  final String valueHaxWithoutPrefix0x = prefix0In64Digital(toHexWithoutPrefix0x(valueInWei));
  return ByteString.decodeHex(removePrefix0x(TRANSFER) + PLACEHOLDER + hexWithoutPrefix0x + valueHaxWithoutPrefix0x).toByteArray();
}

Second, I have to sign below transaction.

{
  "chain": 36291,
  "nonce": 2,
  "from": "0xaeF72A6461e5392e9fa1537372b98701780a1819",
  "to": "0xf13C9660190749124AD90C8dEfC77cC6c5D36494",
  "gas": 60000,
  "gasPrice": 20000000000,
  "value": 0,
  "input": "0xa9059cbb00000000000000000000000088dd6b191d4bca6b059dd35ac0cffb2ffd072d62000000000000000000000000000000000000000000000000208b1d135e4a8000"
}
@NonNull
private Transaction makeSignedTxForTransferToken(@NonNull String password, @IntRange(from = 0) long nonce, @NonNull String toAddress, long gasLimit, long gasPrice, @NonNull BigInteger amount)
throws Exception {
  final Transaction tx = Geth.newTransaction(
    nonce,
    new Address(contractAddress),
    new BigInt(0),
    new BigInt(gasLimit),
    new BigInt(gasPrice),
    makeInputDataForTransferMethod(toAddress, amount)
  );
  unlock(password);
  final Transaction result = keyStore.signTx(getFirstAccount(), tx, new BigInt(networkId));
  lock();
  return result;
}

Then getting the RLP encoded transaction by below Java program.

@NonNull
private String makeSignedRlpTxHex(@NonNull Transaction signedTx) throws Exception {
  return PREFIX_HEX + ByteString.of(signedTx.encodeRLP()).hex();
}

Finally, doing the HTTP POST request with below body.

  • request

    {
        "jsonrpc":"2.0",
        "method":"eth_sendRawTransaction",
        "params":["0xf8ac028504a817c80082ea6094f13c9660190749124ad90c8defc77cc6c5d3649480b844a9059cbb00000000000000000000000088dd6b191d4bca6b059dd35ac0cffb2ffd072d62000000000000000000000000000000000000000000000000208b1d135e4a800083011ba9a0daf4a5ea69c253de73bee8dc39ac9d1bf671feba59a54773841ed77552ee3df5a065ee2c9f6ea2014efa19d5998bb61b3a88cd358d798046dc5ef5c9b4fdaa7a78"],
        "id":63
    }
    
  • response

    {
        "jsonrpc": "2.0",
        "id": 63,
        "result": "0x7f1d6a78768486177360b19f2fdcc5cfcb1663030c64f55a832700c5fe27abcc"
    }
    
  • miner 2 console

    > INFO [01-02|16:14:29] Submitted transaction                    fullhash=0x7f1d6a78768486177360b19f2fdcc5cfcb1663030c64f55a832700c5fe27abcc recipient=0xf13C9660190749124AD90C8dEfC77cC6c5D36494
    
    > INFO [01-02|16:17:42] Starting mining operation 
    INFO [01-02|16:17:42] Commit new mining work                   number=110 txs=1 uncles=0 elapsed=3.189ms
    
    > eth.getTransaction("0x7f1d6a78768486177360b19f2fdcc5cfcb1663030c64f55a832700c5fe27abcc")
    {
      blockHash: "0x5383b71065dadf8fb7b91bdecf65cefd771f0ae4487e2d559fece25e6e011bd4",
      blockNumber: 110,
      from: "0xaef72a6461e5392e9fa1537372b98701780a1819",
      gas: 60000,
      gasPrice: 20000000000,
      hash: "0x7f1d6a78768486177360b19f2fdcc5cfcb1663030c64f55a832700c5fe27abcc",
      input: "0xa9059cbb00000000000000000000000088dd6b191d4bca6b059dd35ac0cffb2ffd072d62000000000000000000000000000000000000000000000000208b1d135e4a8000",
      nonce: 2,
      r: "0xdaf4a5ea69c253de73bee8dc39ac9d1bf671feba59a54773841ed77552ee3df5",
      s: "0x65ee2c9f6ea2014efa19d5998bb61b3a88cd358d798046dc5ef5c9b4fdaa7a78",
      to: "0xf13c9660190749124ad90c8defc77cc6c5d36494",
      transactionIndex: 0,
      v: "0x11ba9",
      value: 0
    }
    
    > eth.getTransactionReceipt("0x7f1d6a78768486177360b19f2fdcc5cfcb1663030c64f55a832700c5fe27abcc")
    {
      blockHash: "0x5383b71065dadf8fb7b91bdecf65cefd771f0ae4487e2d559fece25e6e011bd4",
      blockNumber: 110,
      contractAddress: null,
      cumulativeGasUsed: 37111,
      from: "0xaef72a6461e5392e9fa1537372b98701780a1819",
      gasUsed: 37111,
      logs: [{
          address: "0xf13c9660190749124ad90c8defc77cc6c5d36494",
          blockHash: "0x5383b71065dadf8fb7b91bdecf65cefd771f0ae4487e2d559fece25e6e011bd4",
          blockNumber: 110,
          data: "0x000000000000000000000000000000000000000000000000208b1d135e4a8000",
          logIndex: 0,
          removed: false,
          topics: ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x000000000000000000000000aef72a6461e5392e9fa1537372b98701780a1819", "0x00000000000000000000000088dd6b191d4bca6b059dd35ac0cffb2ffd072d62"],
          transactionHash: "0x7f1d6a78768486177360b19f2fdcc5cfcb1663030c64f55a832700c5fe27abcc",
          transactionIndex: 0
      }],
      logsBloom: "0x00000200000000000000000100000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000010000000000040040000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000002000000000000000000000000000002000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000",
      root: "0xdcf34557c3394cc93a8c4dba07613db353f8e496b18506d3d99cee787e1059c5",
      to: "0xf13c9660190749124ad90c8defc77cc6c5d36494",
      transactionHash: "0x7f1d6a78768486177360b19f2fdcc5cfcb1663030c64f55a832700c5fe27abcc",
      transactionIndex: 0
    }
    

RLP of ethereum Wiki

Block#encodeRLP()

eth_sendRawTransaction

using Geth mobile SDK

  • GoEthereum.java

    import org.ethereum.geth.Transaction;
    
    public class GoEthereum implements Ethereum {
    
      public boolean transferToken(@NonNull String password, @NonNull Address toAddress, long amount, long gasLimit, long gasPrice) {
        try {
          unlock(password);
          new TokenTransfer(contractAddress, abi, getAccount(), ethClient, ethContext, new MySigner(keyStore, networkId))
            .sendTransaction(password, toAddress, amount, gasLimit, gasPrice);
          lock();
          return true;
        } catch (Exception e) {
          e.printStackTrace();
        }
        return false;
      }
    }
    
  • TokenTransfer.java

    import org.ethereum.geth.Account;
    import org.ethereum.geth.Address;
    import org.ethereum.geth.BigInt;
    import org.ethereum.geth.BoundContract;
    import org.ethereum.geth.Context;
    import org.ethereum.geth.Geth;
    import org.ethereum.geth.Interface;
    import org.ethereum.geth.Interfaces;
    import org.ethereum.geth.Signer;
    import org.ethereum.geth.TransactOpts;
    import org.ethereum.geth.Transaction;
    
    public class TokenTransfer {
    
      @TokenAddress
      @NonNull
      private final String contractAddress;
    
      @NonNull
      private final String abi;
    
      @NonNull
      private final Account account;
    
      @NonNull
      private final EthereumClient client;
    
      @NonNull
      private final Context context;
    
      @NonNull
      private final Signer signer;
    
      TokenTransfer(@TokenAddress @NonNull String contractAddress, @NonNull String abi, @NonNull Account account,
        @NonNull EthereumClient client, @NonNull Context context, @NonNull Signer signer) {
        this.contractAddress = contractAddress;
        this.abi = abi;
        this.account = account;
        this.client = client;
        this.account = account;
        this.context = context;
        this.signer = signer;
      }
    
      @NonNull
      public Transaction sendTransaction (@NonNull String password, @NonNull Address toAddress, long amount, long gasLimit, long gasPrice) {
        try {
          final long nonce = client.getPendingNonceAt(context, account.getAddress());
          final BoundContract boundContract = Geth.bindContract(contractAddress, abi, client);
    
          final TransactOpts transactOpts = new TransactOpts();
          transactOpts.setContext(context);
          transactOpts.setGasLimit(Geth.newBigInt(gasLimit));
          transactOpts.setGasPrice(Geth.newBigInt(gasPrice));
          transactOpts.setNonce(nonce);
          transactOpts.setFrom(account.getAddress());
          transactOpts.setSigner(signer);
    
          final Interface paramToAddress = Geth.newInterface();
          paramToAddress.setAddress(toAddress);
    
          final Interface paramAmount = Geth.newInterface();
          paramAmount.setBigInt(Geth.newBigInt(amount));
    
          final Interfaces params = Geth.newInterfaces(2);
          params.set(0, paramToAddress);
          params.set(1, paramAmount);
    
          return boundContract.transact(transactOpts, "transfer", params);
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
      }
    }
    
  • MySigner.java

    public class MySigner implements Signer {
      @NonNull
      private final KeyStore keyStore;
    
      @NonNull
      private final BigInt networkId;
    
      MySigner(@NonNull KeyStore keyStore, @IntRange(from = 0) int networkId) {
        this.keyStore = keyStore;
        this.networkId = Geth.newBigInt(networkId);
      }
    
      @NonNull
      @Override
      public Transaction sign(Address address, Transaction transaction) throws Exception {
        return keyStore.signTx(address, transaction, networkId);
      }
    }
    

Kin SDK core in GitHub

Nonce too low issue

  • request

    {
      "jsonrpc":"2.0",
      "method":"eth_sendRawTransaction",
      "params":["0xf86b808223288275309488dd6b191d4bca6b059dd35ac0cffb2ffd072d6287038d7ea4c680008083011baaa02f5786edffdf79d5c67302e357cd674434d6e81b592180231fc5e030887e2e23a005d6102da7d01c725dc909a6306e97b750b4c9bdf846aa6d7b678c15cc2db12a"],
      "id":63
    }
    
  • response

    {
      "jsonrpc": "2.0",
      "id": 63,
      "error": {
        "code": -32000,
        "message": "nonce too low"
      }
    }
    

Needs to increase the nonce.

results matching ""

    No results matching ""