Basic use of SmartBCH with Python, Web3Py
SmartBCH becoming is becoming more popular with time, It brings the best of Ethereum world to BCH. I wanted to explore it and help others too so I created this short introduction to use smartBCH for Python developers. First you should install `web3` : pip3 install web3 Let us start a Python interpreter and import `Web3:` >>> from web3 import Web3 Then we should use a provider, for a quick start you will depend on an external service that connects us to the network >>> w3 = Web3(Web3.HTTPProvider('https://smartbch.fountainhead.cash/mainnet')) We have used here the smartBCH node from fountainhead.cash here is a list of provider that we can use: https://fountainhead.cash https://smartbch.fountainhead.cash/mainnet wss://smartbch-wss.greyh.at https://global.uat.cash https://rpc.uatvo.com http://35.220.203.194:8545 (testnet) ℹ️ http://35.220.203.194:8545/ https://docs.smartbch.org/smartbch/testnets https://moeing.tech:9545 (testnet) ℹ️ https://docs.smartbch.org/smartbch/testnets If you use the one with Websocket instead of http you will have to change the provider method to be Websocket like this: w3 = Web3(Web3.WebsocketProvider('wss://smartbch-wss.greyh.at')) Testing connection Let us test connection, we should get `True` if the node is up and ready: >>> w3.isConnected() True Lest us start querying for some useful data, Let us query for the **latest block** : >>> w3.eth.get_block('latest') AttributeDict({'difficulty': 0, 'extraData': HexBytes('0x'), 'gasLimit': 1000000000, 'gasUsed': 0, 'hash': HexBytes('0xcfa93b9979df7ea7658940eb319a22a208947f43c4983a83c5d7bc7934d88d5c'), 'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'), 'miner': '0x930C23CE7536B0ede6AfE7754134d4011217D6AA', 'mixHash': HexBytes('0x0000000000000000000000000000000000000000000000000000000000000000'), 'nonce': HexBytes('0x0000000000000000'), 'number': 665462, 'parentHash': HexBytes('0xbe439275cbc6588651ea43c4b58c3372c3a5a7ee18b639a9f0390f58d05adceb'), 'receiptsRoot': HexBytes('0x0000000000000000000000000000000000000000000000000000000000000000'), 'sha3Uncles': HexBytes('0x0000000000000000000000000000000000000000000000000000000000000000'), 'size': 557, 'stateRoot': HexBytes('0x38bbd2b0bfb71e273080fee38aaf84edd25bcf04e30a874f781a10252a93a521'), 'timestamp': 1631452685, 'totalDifficulty': 0, 'transactions': [], 'transactionsRoot': HexBytes('0x0000000000000000000000000000000000000000000000000000000000000000'), 'uncles': []}) To just get the **number of latest block**: >>> w3.eth.block_number 665466 To get the **balance of an account**/address: >>> w3.eth.get_balance('0x54E4F23a819F0DDe10344F5BD06b57906a752934') 393343977270000000 Balances are shown in a unit called Wei by default, to **convert to BCH** use: >>> balance = w3.eth.get_balance('0x54E4F23a819F0DDe10344F5BD06b57906a752934') >>> w3.fromWei(balance, 'ether') Decimal('0.39117037731') To **convert from BCH to Wei**: >>> w3.toWei(Decimal('0.000000005'), 'ether') 5000000000 To **get a transaction detail**: >>> w3.eth.get_transaction('0xaac856e36d6ccae43bc07c1e078e4c29efb14efc8f0d795c63632557c1bb1642') AttributeDict({'blockHash': HexBytes('0x649d3f7eb7fbe805edb6ad7d63aceb60041c4ede1ca5f1e31b4bab6da1ad0442'), 'blockNumber': 631598, 'from': '0x579564809ACDA82232b91f2931a0876f97669df6', 'gas': 208096, 'gasPrice': 1050000000, 'hash': HexBytes('0xaac856e36d6ccae43bc07c1e078e4c29efb14efc8f0d795c63632557c1bb1642'), 'input': '0xe2bbb158000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000f3b4741d5bbf42c20', 'nonce': 32, 'to': '0xDEa721EFe7cBC0fCAb7C8d65c598b21B6373A2b6', 'transactionIndex': 1, 'value': 0, 'v': None, 'r': None, 's': None}) To **lookup transaction receipt**: >>> w3.eth.get_transaction_receipt('0xaac856e36d6ccae43bc07c1e078e4c29efb14efc8f0d795c63632557c1bb1642') Contracts I don't have good understanding of how contracts work on Ethereum but still we can query them and get some useful information. To start dealing with contracts we need two pieces of information: Contract address ABI (Application Binary Interface) Contract Address Normally you can find the contract on the explorer and it seems it serve similar purpose to token id for SLP token.
You can look it from here: https://www.smartscan.cash/address/0x481De06DCA0198844faA36FCa04Db364e5c2f86C Address should be in Checksum format (few letters should be capitals), if you got the address in non-checksum format you can use this to convert it: >>> w3.toChecksumAddress('0x481de06dca0198844faa36fca04db364e5c2f86c') '0x481De06DCA0198844faA36FCa04Db364e5c2f86C' ABI @b_s_z in smartBCH community group on Telegram provided me with the ABI for the Maze token, you can get it from this gitlab snippet: https://gitlab.com/-/snippets/2174502 In Etherscan you can see an Ethereum Token API like this one for Tether https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7#code
https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7#code Dealing with contracts After getting the address and ABI we assign them, I'll not post the full ABI here as it's a bit long. Just copy it from snippet, you may want to minify so it fit in one line. >>> address = '0x481De06DCA0198844faA36FCa04Db364e5c2f86C' >>> abi = '[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false, OMITTED Then we **create an instance for the contract** and **check for the address**: >>> contract = w3.eth.contract(address=address, abi=abi) >>> contract.address '0x481De06DCA0198844faA36FCa04Db364e5c2f86C' Get **token symbol**: >>> contract.functions.symbol().call() 'MAZE' We can ask for **total supply**: >>> contract.functions.totalSupply().call() 21000000000000 **Number of decimals:** >>> contract.functions.decimals().call() 6 Get **Token balance on account**: >>> bob = '0x481De06DCA0198844faA36FCa04Db364e5c2f86C' >>> raw_balance = contract.functions.balanceOf(bob).call() >>> raw_balance 1000000000 You can find much more examples from Web3.py example page, All what I've to do is to set the provider to SmartBCH provider. You need also to make sure that unites are correct because apparently it uses Ethereum definition like wei and ether. Resources Web3py quickstart https://web3py.readthedocs.io/en/latest/quickstart.html Web3py examples https://web3py.readthedocs.io/en/latest/examples.html How to get an ABI, seems extractable from contract. https://ethereum.stackexchange.com/questions/3149/how-do-you-get-a-json-file-abi-from-a-known-contract-address Maze contract, Maze ABI https://github.com/mazetoken/smartMaze/tree/main/contracts https://gitlab.com/-/snippets/2174502 SmartBCH explorer https://www.smartscan.cash SmartBCH community on Telegram https://t.me/smartbch_community SmartBCH official website https://smartbch.org In this article I've just explained few very basic uses. Hopefully in the feature I'll have time to explore EVM more. It's attractive and very useful.
5 comments
But what a wonderful article we have here! I am a computer engineer, programmer and designer. I program in several languages such as: c, c ++, c # and php. I have used python for some very specific thing. Definitely using this tutorial I will do something about it and put it to the test. I start fresh in read (I've only been 1 day), and the truth is I really like the content I find here. Thanks for sharing and congratulations on such a wonderful post.
WOw this is cool. I'm going to wait for games within the smartBCH network.. I think they are going to happen soon.
That's really cool. Didn't know this. Thanks for sharing!!
Glad you like it.
✊Thanks for the info, I may be new to crypto but I am trying my best to learn