Python 3, Ethereum - how to send ERC20 Tokens?
Asked Answered
I

2

5

i have some script using to sending Ethers from address to addres. Im using Parity, and Python 3.6. It is using Flask looks like:

from flask import Flask, render_template, json, request
import urllib
import requests
import binascii
from decimal import *
app = Flask(__name__)

def Eth(method,params=[]):
    data = {"method":method,"params":params,"id":1,"jsonrpc":"2.0"}
    headers = {'Content-type': 'application/json'}
    r = requests.post(ethrpc, data=json.dumps(data), headers=headers)
    r = r.text
    response = json.loads(r)
    return(response)
hot = str("XXXXXXX")
@app.route('/')
def index():
    ethnumbers = int(10)**int(18)
    hot = str("XXXXX")
    balance = Eth("eth_getBalance",[hot,'latest'])
    balance = balance["result"]
    balance = int(balance, 16)
    balance = float(balance)
    balance = balance / ethnumbers
    balance = str(balance)
    return render_template('index.html',hot = hot,balance=balance)


@app.route('/send/',methods=['POST','GET'])
def send():
    getcontext().prec = 28
    ethnumbers = Decimal(10)**Decimal(18)
    print(ethnumbers)
    if request.method == "POST":    
        _myaddress = request.form['_myaddress']
        _youraddress = request.form['_youraddress']
        _amount = request.form['_amount']
        _gas = request.form['_gas']
        _gas = hex(int(_gas))
        passy = str("XXXXXXXXX")
        getcontext().prec = 28
        _amount = Decimal(_amount)
        getcontext().prec = 28
        _amount = _amount * ethnumbers
        getcontext().prec = 28
        _amount = int(_amount)
        _amount = hex(_amount)
        r = [{'from':_myaddress,"to":_youraddress,"value":_amount,"gas":_gas,},str("XXXXXXXXXX!")]
        print(r)
        json.dumps(r)
        resultio = Eth("personal_sendTransaction",r)
        try: 
            resultio["result"]
            return render_template('sent.html',resultio=resultio["result"])
        except: KeyError
        return render_template('sent.html',resultio=resultio["error"]["message"])

    else:
        return render_template('index.html')







if __name__ == "__main__":
    app.run()

Im pretty sure, that i have to use "data" to do this, but i have no idea how to send via this script ERC20 tokens. Structure of tokens transaction looks like "my address -> token address -> token receiver".

Any ideas?

Irreversible answered 24/1, 2018 at 22:38 Comment(2)
I'd recommend checking out web3py.readthedocs.io to abstract away the json-rpc protocol.Mann
You can refer the node version. Refer to this answer of Send ERC20 token with web3.Condemnation
I
5

Guys it was simpler than it looks like. You just have to put:

contract address

as receiver and make a long "data" field, it represents string as:

// method name, its constans in erc20

0xa9059cbb

//receiver address (you have to do it without "0x" because its needed only when
//you have to tell "im using hexadecimal". You did it above, in method field.
//so, receiver address:

5b7b3b499fb69c40c365343cb0dc842fe8c23887

// and fill it with zeros, it have to be lenght 64. So fill rest of address 

0000000000000000000000005b7b3b499fb69c40c365343cb0dc842fe8c23887

// then you need amount, please convert it to hexadecimal, delete "0x" and 
// remember, you need to integer first, so if token has 18 "decimals" it need
// to be amount / 10**18 first!!
//1e27786570c272000 and fill that with zeros, like above:

000000000000000000000000000000000000000000000001e27786570c272000

//just add string, to string, to string, and you have data field: 

0xa9059cbb0000000000000000000000005b7b3b499fb69c40c365343cb0dc842fe8c23887000000000000000000000000000000000000000000000001e27786570c272000

Sample transaction: https://etherscan.io/tx/0x9c27df8af24e06edb819a8d7a380f548fad637de5edddd6155d15087d1619964

Irreversible answered 5/11, 2018 at 8:14 Comment(0)
L
3

web3.py is definitely the way to go. If you want to do it by hand and you just want to call the standard ERC-20 transfer method, the from address should stay the same, the to address should be the token contract, and then the data should be the following concatenated together and formatted as hexadecimal:

  1. The first 4 bytes of the keccak256 hash of "transfer(address,uint256)", which is the function's signature.
  2. The address of the recipient, left-zero-padded to be 32 bytes.
  3. The amount to be transferred. (Be sure to take into account the token's decimals... 1 token is often 10**18, but the number of decimal places varies from token to token and can be retrieved by calling the decimals() function.) This should also be formatted as a 32-byte number (so left-zero-padded).

web3.py would be much easier. :-) Something like:

web3.eth.contract(address, abi=standard_token_abi).sendTransaction({
    'from': from_address
}).transfer(to_address, amount)
Leet answered 25/1, 2018 at 4:4 Comment(2)
hmm "standard token abi" you mean that every contract has a unique abi, or maybe i have generate abi from transaction?Irreversible
The ABI essentially describes the interface exposed by a contract. ERC20 is a standard for tokens, so all token contracts implement the same basic ABI. You can use that.Leet

© 2022 - 2024 — McMap. All rights reserved.