Name | pyhmy JSON |
Version |
0.1.0
JSON |
| download |
home_page | |
Summary | A library for interacting and working the Harmony blockchain and related codebases |
upload_time | 2022-08-24 19:24:11 |
maintainer | |
docs_url | None |
author | |
requires_python | >=3.0 |
license | MIT |
keywords |
harmony
blockchain
protocol
staking
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# Pyhmy - Harmony's python utilities
**This library only supports Python 3.6+**
A Python library for interacting and working the [Harmony blockchain](https://harmony.one/)
and [related codebases](https://github.com/harmony-one).
[Full documentation is located on Harmony's GitBook](https://docs.harmony.one/) (in progress).
## Installation
```bash
pip install pyhmy
```
On MacOS:
Make sure you have Python3 installed, and use python3 to install pyhmy
```bash
sudo pip3 install pathlib
sudo pip3 install pyhmy
```
## Development
Clone the repository and then run the following:
```bash
make install
```
## Running tests
Before you can run tests, you need the python dependencies (`make install`), `docker` and `go` installed to quickly run a local blockchain with staking enabled (detailed instructions [here](https://github.com/harmony-one/harmony/blob/main/README.md)):
```bash
mkdir -p $(go env GOPATH)/src/github.com/harmony-one
cd $(go env GOPATH)/src/github.com/harmony-one
git clone https://github.com/harmony-one/mcl.git
git clone https://github.com/harmony-one/bls.git
git clone https://github.com/harmony-one/harmony.git
cd harmony
make debug
```
Once the terminal displays a couple of `Started server` lines, use another shell to run the following tests
```bash
make test
```
Or directly with `pytest` (reference [here](https://docs.pytest.org/en/latest/index.html) for more info):
```bash
pytest tests
```
## Releasing
You can release this library with the following command (assuming you have the credentials to upload):
```bash
make release
```
## Usage
```py
test_net = 'https://api.s0.b.hmny.io' # this is shard 0
test_net_shard_1 = 'https://api.s1.b.hmny.io'
test_address = 'one18t4yj4fuutj83uwqckkvxp9gfa0568uc48ggj7'
main_net = 'https://rpc.s0.t.hmny.io'
main_net_shard_1 = 'https://rpc.s1.t.hmny.io'
```
#### utilities
##### Address conversion
```py
from pyhmy import util
hex_addr = util.convert_one_to_hex('one155jp2y76nazx8uw5sa94fr0m4s5aj8e5xm6fu3')
one_addr = util.convert_hex_to_one('0xA5241513DA9F4463F1d4874b548dFBAC29D91f34')
```
##### Ether / Wei conversion
```py
from pyhmy import numbers
one_ether_in_wei = numbers.convert_one_to_atto(1) # as a decimal.Decimal
wei_to_ether = numbers.convert_atto_to_one(int(1e18))
```
#### accounts
```py
from pyhmy import account
```
##### Balance / account related information
````py
balance = account.get_balance(test_address, endpoint=test_net) # on shard 0, in ATTO
total_balance = account.get_total_balance(test_address, endpoint=test_net) # on all shards, in ATTO
balance_by_shard = account.get_balance_on_all_shards(test_address, endpoint=test_net) # list of dictionaries with shard and balance as keys
genesis_balance = account.get_balance_by_block(test_address, block_num=0, endpoint=test_net)
latest_balance = account.get_balance_by_block(test_address, block_num='latest', endpoint=test_net) # block_num can be a string 'latest', or 'pending', if implemented at the RPC level
account_nonce = account.get_account_nonce(test_address, block_num='latest', endpoint=test_net)
````
##### Transaction counts
````py
tx_count = account.get_transactions_count(test_address, tx_type='ALL', endpoint=test_net)
sent_tx_count = account.get_transactions_count(test_address, tx_type='SENT', endpoint=test_net)
received_tx_count = account.get_transactions_count(test_address, tx_type='RECEIVED', endpoint=test_net)
legacy_tx_count = account.get_transaction_count(test_address, block_num='latest', endpoint=test_net) # API is legacy
legacy_tx_count_pending = account.get_transaction_count(test_address, block_num='pending', endpoint=test_net)
````
##### Staking transaction counts
````py
stx_count = account.get_staking_transactions_count(test_address, tx_type='ALL', endpoint=test_net)
sent_stx_count = account.get_staking_transactions_count(test_address, tx_type='SENT', endpoint=test_net)
received_stx_count = account.get_staking_transactions_count(test_address, tx_type='RECEIVED', endpoint=test_net)
````
##### Transaction history
To get a list of hashes, use `include_full_tx=False`
````py
first_100_tx_hashes = account.get_transaction_history(test_address, page=0, page_size=100, include_full_tx=False, endpoint=test_net)
````
To get the next 100 transactions, change the `page`
```py
next_100_tx_hashes = account.get_transaction_history(test_address, page=1, page_size=100, include_full_tx=False, endpoint=test_net)
```
To get a list of full transaction details, use `include_full_tx=True` (see `get_transaction_by_hash` for the reply structure
````py
first_3_full_tx = account.get_transaction_history(test_address, page=0, page_size=3, include_full_tx=True, endpoint=test_net)
````
To get newest transactions, use `order='DESC'`
````py
last_3_full_tx = account.get_transaction_history(test_address, page=0, page_size=3, include_full_tx=True, order='DESC', endpoint=test_net)
````
To change the transaction type (SENT / RECEIVED / ALL), pass the `tx_type` parameter
```py
first_100_received_tx_hashes = account.get_transaction_history(test_address, page=0, page_size=100, include_full_tx=False, tx_type='RECEIVED', endpoint=test_net)
```
##### Staking transaction history
To get a list of staking hashes, use `include_full_tx=False`
````py
first_100_stx_hashes = account.get_staking_transaction_history(test_address, page=0, page_size=100, include_full_tx=False, endpoint=test_net)
````
To get the next 100 staking transactions, change the `page`
```py
next_100_stx_hashes = account.get_staking_transaction_history(test_address, page=1, page_size=100, include_full_tx=False, endpoint=test_net)
```
To get a list of full staking transaction details, use `include_full_tx=True` (see `get_transaction_by_hash` for the reply structure
````py
first_3_full_stx = account.get_staking_transaction_history(test_address, page=0, page_size=3, include_full_tx=True, endpoint=test_net)
````
To get newest staking transactions, use `order='DESC'`
````py
last_3_full_stx = account.get_staking_transaction_history(test_address, page=0, page_size=3, include_full_tx=True, order='DESC', endpoint=test_net)
````
To change the staking transaction type (SENT / RECEIVED / ALL), pass the `tx_type` parameter
```py
first_100_received_stx_hashes = account.get_staking_transaction_history(test_address, page=0, page_size=100, include_full_tx=False, tx_type='RECEIVED', endpoint=test_net)
```
#### Blockchain
```py
from pyhmy import blockchain
from decimal import Decimal
```
##### Node / network information
```py
chain_id = blockchain.chain_id(test_net) # chain type, for example, mainnet or testnet
node_metadata = blockchain.get_node_metadata(test_net) # metadata about the endpoint
peer_info = blockchain.get_peer_info(test_net) # peers of the endpoint
protocol_version = blockchain.protocol_version(test_net) # protocol version being used
num_peers = blockchain.get_num_peers(test_net) # number of peers of the endpoin
version = blockchain.get_version(test_net) # EVM chain id, https://chainid.network
is_node_in_sync = blockchain.in_sync(test_net) # whether the node is in sync (not out of sync or not syncing)
is_beacon_in_sync = blockchain.beacon_in_sync(test_net) # whether the beacon node is in sync
prestaking_epoch_number = blockchain.get_prestaking_epoch(test_net)
staking_epoch_number = blockchain.get_staking_epoch(test_net)
```
##### Sharding information
```py
shard_id = blockchain.get_shard(test_net) # get shard id of the endpoint
sharding_structure = blockchain.get_sharding_structure(test_net) # list of dictionaries, each representing a shard
last_cross_links = blockchain.get_last_cross_links(test_net) # list of dictionaries for each shard except test_net
```
##### Current network status
```py
leader_address = blockchain.get_leader_address(test_net)
is_last_block = blockchain.is_last_block(block_num=0, test_net)
last_block_of_epoch5 = blockchain.epoch_last_block(block_num=5, test_net)
circulating_supply = Decimal(blockchain.get_circulating_supply(test_net))
premined = blockchain.get_total_supply(test_net) # should be None?
current_block_num = blockchain.get_block_number(test_net)
current_epoch = blockchain.get_current_epoch(test_net)
gas_price = blockchain.get_gas_price(test_net) # this returns 1 always
```
##### Block headers
```py
latest_header = blockchain.get_latest_header(test_net) # header contains hash, number, cross links, signature, time, etc (see get_latest_header for a full list)
latest_hash = latest_header['blockHash']
latest_number = latest_header['blockNumber']
previous_header = blockchain.get_header_by_number(latest_number-1, test_net)
chain_headers = blockchain.get_latest_chain_headers(test_net_shard_1) # chain headers by beacon and shard
```
##### Blocks
###### By block number
Fetch the barebones information about the block as a dictionary
```py
latest_block = blockchain.get_block_by_number(block_num='latest', endpoint=test_net)
```
Fetch a block with full information (`full_tx=True`) for each transaction in the block
```py
block = blockchain.get_block_by_number(block_num=9017724, full_tx=True, include_tx=True, include_staking_tx=True, endpoint=test_net)
```
Fetch a block and only staking transactions (`include_tx=False, include_staking_tx=True`) for the block
```py
block = blockchain.get_block_by_number(block_num='latest', include_tx=False, include_staking_tx=True, endpoint=test_net)
```
Fetch block signer addresses (`include_signers=True`) as a list
```py
signers = blockchain.get_block_by_number(block_num=9017724, include_signers=True, endpoint=test_net)['signers']
```
Or, alternatively, use the direct `get_block_signers` method:
```py
signers = blockchain.get_block_signers(block_num=9017724, endpoint=test_net)
```
Fetch the public keys for signers
```py
signers_keys = blockchain.get_block_signers_keys(block_num=9017724, endpoint=test_net)
```
Check if an address is a signer for a block
```py
is_block_signer = blockchain.is_block_signer(block_num=9017724, address='one1yc06ghr2p8xnl2380kpfayweguuhxdtupkhqzw', endpoint=test_net)
```
Fetch the number of blocks signed by a particular validator for the last epoch
```py
number_signed_blocks = blockchain.get_signed_blocks(address='one1yc06ghr2p8xnl2380kpfayweguuhxdtupkhqzw', endpoint=test_net)
```
Fetch a list of validators and their public keys for specific epoch number
```py
validators = blockchain.get_validators(epoch=12, endpoint=test_net)
validator_keys = blockchain.get_validator_keys(epoch=12, endpoint=test_net)
```
Fetch number of transactions
```py
tx_count = blockchain.get_block_transaction_count_by_number(block_num='latest', endpoint=test_net)
```
Fetch number of staking transactactions
```py
stx_count = blockchain.get_block_staking_transaction_count_by_number(block_num='latest', endpoint=test_net)
```
Fetch a list of blocks using the block numbers
```py
blocks = blockchain.get_blocks(start_block=0, end_block=2, full_tx=False, include_tx=False, include_staking_tx=False, include_signers=False, endpoint=test_net)
```
###### By block hash
Most of the functions described above can be applied for fetching information about a block whose hash is known, for example:
```py
block_hash = '0x44fa170c25f262697e5802098cd9eca72889a637ea52feb40c521f2681a6d720'
block = blockchain.get_block_by_hash(block_hash=block_hash, endpoint=test_net)
block_with_full_tx = blockchain.get_block_by_hash(block_hash=block_hash, full_tx=True, include_tx=True, include_staking_tx=True, endpoint=test_net)
block_with_only_staking_tx = blockchain.get_block_by_hash(block_hash=block_hash, include_tx=False, include_staking_tx=True, endpoint=test_net)
signers = blockchain.get_block_by_hash(block_hash=block_hash, include_signers=True, endpoint=test_net)['signers']
tx_count = blockchain.get_block_transaction_count_by_hash(block_hash=block_hash, endpoint=test_net)
stx_count = blockchain.get_block_staking_transaction_count_by_hash(block_hash=block_hash, endpoint=test_net)
```
#### Staking
```py
from pyhmy import staking
validator_addr = 'one1xjanr7lgulc0fqyc8dmfp6jfwuje2d94xfnzyd'
delegator_addr = 'one1y2624lg0mpkxkcttaj0c85pp8pfmh2tt5zhdte'
```
##### Validation
```py
all_validators = staking.get_all_validator_addresses(endpoint=test_net) # list of addresses
validator_information = staking.get_validator_information(validator_addr, endpoint=test_net) # dict with all info
validator_information_100 = staking.get_all_validator_information(page=0, endpoint=test_net)
elected_validators = staking.get_elected_validator_addresses(endpoint=test_net) # list of addresses
validators_for_epoch = staking.get_validators(epoch=73772, endpoint=test_net) # dict with list of validators and balance
validators_information_100_for_block = staking.get_all_validator_information_by_block_number(block_num=9017724, page=0, endpoint=test_net)
validator_keys_for_epoch = staking.get_validator_keys(epoch=73772, endpoint=test_net) # list of public keys
validator_information_at_block = staking.get_validator_information_by_block_number(validator_addr, block_num=9017724, endpoint=test_net)
self_delegation = staking.get_validator_self_delegation(validator_addr, endpoint=test_net)
total_delegation = staking.get_validator_total_delegation(validator_addr, endpoint=test_net)
```
##### Delegation
```py
delegation_information = staking.get_all_delegation_information(page=0, endpoint=test_net)
delegations_by_delegator = staking.get_delegations_by_delegator(delegator_addr, test_net)
delegations_by_delegator_at_block = staking.get_delegations_by_delegator_by_block_number(delegator_addr, block_num=9017724, endpoint=test_net)
delegation_by_delegator_and_validator = staking.get_delegation_by_delegator_and_validator(delegator_addr, validator_addr, test_net)
avail_redelegation_balance = staking.get_available_redelegation_balance(delegator_addr, test_net)
delegations_by_validator = staking.get_delegations_by_validator(validator_addr, test_net) # list of delegations made to this validator, each a dictionary
```
##### Network
```py
utility_metrics = staking.get_current_utility_metrics(test_net)
network_info = staking.get_staking_network_info(test_net)
super_committees = staking.get_super_committees(test_net)
super_committees_current = super_committees['current'] # list of voting committees as a dict
super_committees_previous = super_committees['previous']
total_staking = staking.get_total_staking(endpoint=test_net) # by all validators, only for beaconchain
median_stake_snapshot = staking.get_raw_median_stake_snapshot(test_net)
```
##### Validator class
Instantiate a validator object and load it from the chain
```py
from pyhmy.validator import Validator
validator = Validator(validator_addr)
validator.load_from_blockchain(test_net)
```
Create a new validator object and load from dictionary
```py
from pyhmy.numbers import convert_one_to_atto
validator = Validator('one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9')
info = {
'name': 'Alice',
'identity': 'alice',
'website': 'alice.harmony.one',
'details': "Don't mess with me!!!",
'security-contact': 'Bob',
'min-self-delegation': convert_one_to_atto(10000),
'amount': convert_one_to_atto(10001),
'max-rate': '0.9',
'max-change-rate': '0.05',
'rate': '0.01',
'bls-public-keys': ['0xa20e70089664a874b00251c5e85d35a73871531306f3af43e02138339d294e6bb9c4eb82162199c6a852afeaa8d68712'],
"bls-key-sigs": [
"0xef2c49a2f31fbbd23c21bc176eaf05cd0bebe6832033075d81fea7cff6f9bc1ab42f3b6895c5493fe645d8379d2eaa1413de55a9d3ce412a4f747cb57d52cc4da4754bfb2583ec9a41fe5dd48287f964f276336699959a5fcef3391dc24df00d",
]
'max-total-delegation': convert_one_to_atto(40000)
}
validator.load(info)
```
Sign a validator creation transaction
```py
signed_create_tx_hash = validator.sign_create_validator_transaction(
nonce = 2,
gas_price = 1,
gas_limit = 100,
private_key = '4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48',
chain_id = 2).rawTransaction.hex()
```
To edit validator, change its parameters using the `setter` functions, for example, `validator.set_details`, except the `rate`, `bls_keys_to_add` and `bls_keys_to_remove` which can be passed to the below function:
```py
signed_edit_tx_hash = validator.sign_edit_validator_transaction(
nonce = 2,
gas_price = 1,
gas_limit = 100,
rate = '0.06',
bls_key_to_add = "0xb8c3b3a0f1966c169ca73c348f4b8aee333a407125ab5c67f1d6e1e18ab052ed5fff0f1f7d4a7f789528b5ccd9c47b04",
bls_key_to_add_sig = "0x3de4dff17451fb76a9690efce34bced97dd87eccd371fcd25335826cb879ca21281e82e5c2c76d4ef0ab0fc16e462312628834cbc1f29008b28e16a757367808be85180945b991be3103f98c14c7e3b3e54796d34aab4d8e812d440aa251c419",
bls_keys_to_remove = '0xa20e70089664a874b00251c5e85d35a73871531306f3af43e02138339d294e6bb9c4eb82162199c6a852afeaa8d68712',
private_key = '4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48',
chain_id = 2).rawTransaction.hex()
```
### Transactions
```py
from pyhmy import transaction
```
##### Pool
```py
pending_tx = transaction.get_pending_transactions(test_net)
pending_stx = transaction.get_pending_staking_transactions(test_net)
tx_error_sink = transaction.get_transaction_error_sink(test_net)
stx_error_sink = transaction.get_staking_transaction_error_sink(test_net)
pool_stats = transaction.get_pool_stats(test_net)
pending_cx_receipts = transaction.get_pending_cx_receipts(test_net)
```
##### Fetching transactions
```py
tx_hash = '0x500f7f0ee70f866ba7e80592c06b409fabd7ace018a9b755a7f1f29e725e4423'
block_hash = '0xb94bf6e8a8a970d4d42dfe42f7f231af0ff7fd54e7f410395e3b306f2d4000d4'
tx = transaction.get_transaction_by_hash(tx_hash, test_net) # dict with tx-level info like from / to / gas
tx_from_block_hash = transaction.get_transaction_by_block_hash_and_index(block_hash, tx_index=0, endpoint=test_net)
tx_from_block_number = transaction.get_transaction_by_block_number_and_index(9017724, tx_index=0, endpoint=test_net)
tx_receipt = transaction.get_transaction_receipt(tx_hash, test_net)
```
##### Fetching staking transactions
```py
stx_hash = '0x3f616a8ef34f111f11813630cdcccb8fb6643b2affbfa91d3d8dbd1607e9bc33'
block_hash = '0x294dc88c7b6f3125f229a3cfd8d9b788a0bcfe9409ef431836adcd83839ba9f0' # block number 9018043
stx = transaction.get_staking_transaction_by_hash(stx_hash, test_net)
stx_from_block_hash = transaction.get_staking_transaction_by_block_hash_and_index(block_hash, tx_index=0, endpoint=test_net)
stx_from_block_number = transaction.get_staking_transaction_by_block_number_and_index(9018043, tx_index=0, endpoint=test_net)
```
##### Cross shard transactions
```py
cx_hash = '0xd324cc57280411dfac5a7ec2987d0b83e25e27a3d5bb5d3531262387331d692b'
cx_receipt = transaction.get_cx_receipt_by_hash(cx_hash, main_net_shard_1) # the shard which receives the tx
tx_resent = transaction.resend_cx_receipt(cx_hash, main_net) # beacon chain
```
##### Sending transactions
Sign it with your private key and use `send_raw_transaction`
```py
from pyhmy import signing
tx = {
'chainId': 2,
'from': 'one18t4yj4fuutj83uwqckkvxp9gfa0568uc48ggj7',
'gas': 6721900,
'gasPrice': 1000000000,
'nonce': 6055,
'shardID': 0,
'to': 'one1ngt7wj57ruz7kg4ejp7nw8z7z6640288ryckh9',
'toShardID': 0,
'value': 500000000000000000000
}
transaction.send_raw_transaction(signing.sign_transaction(tx, '01F903CE0C960FF3A9E68E80FF5FFC344358D80CE1C221C3F9711AF07F83A3BD').rawTransaction.hex(), test_net)
```
A similar approach can be followed for staking transactions
```py
from pyhmy import staking_structures, staking_signinge
tx = {
'chainId': 2,
'delegatorAddress': 'one18t4yj4fuutj83uwqckkvxp9gfa0568uc48ggj7',
'directive': staking_structures.Directive.CollectRewards,
'gasLimit': 6721900,
'gasPrice': 1,
'nonce': 6056
}
transaction.send_raw_staking_transaction(staking_signing.sign_staking_transaction(tx, private_key = '01F903CE0C960FF3A9E68E80FF5FFC344358D80CE1C221C3F9711AF07F83A3BD').rawTransaction.hex(), test_net)
```
### Contracts
```py
from pyhmy import contract
from pyhmy.util import convert_one_to_hex
contract_addr = 'one1rcs4yy4kln53ux60qdeuhhvpygn2sutn500dhw'
```
Call a contract without saving state
```py
from pyhmy import numbers
result = contract.call(convert_one_to_hex(contract_addr), 'latest', value=hex(int(numbers.convert_one_to_atto(5)))
, gas_price=hex(1), gas=hex(100000), endpoint=test_net)
```
Estimate gas required for a smart contract call
```py
estimated_gas = contract.estimate_gas(convert_one_to_hex(contract_addr), endpoint=test_net)
```
Fetch the byte code of the contract
```py
byte_code = contract.get_code(convert_one_to_hex(contract_addr), 'latest', endpoint=test_net)
```
Get storage in the contract at `key`
```py
storage = contract.get_storage_at(convert_one_to_hex(contract_addr), key='0x0', block_num='latest', endpoint=test_net)
```
Calling a function on a contract needs the contract ABI. The ABI can be obtained by compiling the contract.
```py
from web3 import Web3
from web3 import providers
from pyhmy.util import convert_one_to_hex
contract_abi = '[{"constant":true,"inputs":[],"name":"manager","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pickWinner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getPlayers","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"enter","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"players","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]'
w3 = Web3(providers.HTTPProvider(test_net))
lottery = w3.eth.contract(abi=contract_abi, address=convert_one_to_hex('one1rcs4yy4kln53ux60qdeuhhvpygn2sutn500dhw'))
lottery.functions.getPlayers().call()
```
To actually participate in a contract, you can sign a transaction from your account to it.
```py
from pyhmy import signing
contract_addr = 'one1rcs4yy4kln53ux60qdeuhhvpygn2sutn500dhw'
tx = {
'chainId': 2,
'from': 'one18t4yj4fuutj83uwqckkvxp9gfa0568uc48ggj7',
'gas': 6721900,
'gasPrice': 1000000000,
'nonce': 6054,
'shardID': 0,
'to': contract_addr,
'toShardID': 0,
'value': 500000000000000000000
}
tx_hash = transaction.send_raw_transaction(signing.sign_transaction(tx, '01F903CE0C960FF3A9E68E80FF5FFC344358D80CE1C221C3F9711AF07F83A3BD').rawTransaction.hex(), test_net)
```
To deploy a contract, sign a transaction from your account without a `to` field and with the byte code as `data` and send it.
```py
from pyhmy import signing
from pyhmy import transaction
contract_tx = {
'chainId': 2, # test net data
'data': '0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063445df0ac146100465780638da5cb5b14610064578063fdacd576146100ae575b600080fd5b61004e6100dc565b6040518082815260200191505060405180910390f35b61006c6100e2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100da600480360360208110156100c457600080fd5b8101908080359060200190929190505050610107565b005b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561016457806001819055505b5056fea265627a7a723158209b80813a158b44af65aee232b44c0ac06472c48f4abbe298852a39f0ff34a9f264736f6c63430005100032', # Migrations.sol
'from': 'one18t4yj4fuutj83uwqckkvxp9gfa0568uc48ggj7',
'gas': 6721900,
'gasPrice': 1000000000,
'nonce': 6049,
'shardID': 0,
'toShardID': 0
}
ctx_hash = transaction.send_raw_transaction(signing.sign_transaction(contract_tx, private_key = '01F903CE0C960FF3A9E68E80FF5FFC344358D80CE1C221C3F9711AF07F83A3BD').rawTransaction.hex(), test_net)
# the below may be need a time gap before the transaction reaches the chain
contract_address = transaction.get_transaction_receipt(ctx_hash, test_net)['contractAddress']
```
### Signing transactions
```py
from pyhmy import signing
```
Create a `transaction_dict` with the parameters, and supply your private key to sign (but not submit) a transaction. A signed transaction can be submitted using `transaction.sendRawTransaction`.
```py
transaction_dict = {
'nonce': 2,
'gasPrice': 1,
'gas': 100, # signing.py uses Ether, which by default calls it gas
'to': '0x14791697260e4c9a71f18484c9f997b308e59325',
'value': 5,
'shardID': 0,
'toShardID': 1,
'chainId': 'HmyMainnet'
}
signed_tx = signing.sign_transaction(transaction_dict, private_key = '4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48')
signed_hash = signed_tx.rawTransaction.hex()
```
For a transaction with is Ethereum-like, the `shardID` and `toShardID` are optional, which implies that the transaction is not cross-shard.
```py
transaction_dict = {
'nonce': 2,
'gasPrice': 1,
'gas': 100, # signing.py uses Ether, which by default calls it gas
'to': '0x14791697260e4c9a71f18484c9f997b308e59325',
'value': 5,
}
signed_tx = signing.sign_transaction(transaction_dict, private_key = '4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48')
signed_hash = signed_tx.rawTransaction.hex()
```
The `chainId` parameter is also optional, and [according to Ethereum](https://github.com/ethereum/eth-account/blob/00e7b10005c5fa7090086fcef37a76296c524e17/eth_account/_utils/transactions.py#L122), it should not be passed if "you want a transaction that can be replayed across networks." A full list of the possible values of `chainId` is provided below. You can pass either the `str` or the `int`. The RPC API may, however, reject the transaction, which is why it is recommended to pass either `1` or `2` for `mainnet` and `testnet` respectively.
```py
Default = 0,
EthMainnet = 1,
Morden = 2,
Ropsten = 3,
Rinkeby = 4,
RootstockMainnet = 30,
RootstockTestnet = 31,
Kovan = 42,
EtcMainnet = 61,
EtcTestnet = 62,
Geth = 1337,
Ganache = 0,
HmyMainnet = 1,
HmyTestnet = 2,
HmyLocal = 2,
HmyPangaea = 3,
```
### Signing staking transactions
```py
from pyhmy import staking_structures, staking_signing
```
To sign a transaction to collect rewards, supply the dictionary containing the `delegatorAddress` and the private key.
```py
transaction_dict = {
'directive': staking_structures.Directive.CollectRewards,
'delegatorAddress': 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
'nonce': 2,
'gasPrice': 1,
'gasLimit': 100,
}
signed_tx = staking_signing.sign_staking_transaction(transaction_dict, private_key = '4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48')
```
To sign a transaction to delegate or undelegate, supply the dictionary containing the `delegatorAddress`, the `validatorAddress`, the `amount` to delegate or undelegate, and the private key.
```py
transaction_dict = {
'directive': staking_structures.Directive.Delegate,
'delegatorAddress': 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
'validatorAddress': 'one1xjanr7lgulc0fqyc8dmfp6jfwuje2d94xfnzyd',
'amount': 5,
'nonce': 2,
'gasPrice': 1,
'gasLimit': 100,
}
signed_tx = staking_signing.sign_staking_transaction(transaction_dict, '4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48')
transaction_dict = {
'directive': staking_structures.Directive.Undelegate,
'delegatorAddress': 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
'validatorAddress': 'one1xjanr7lgulc0fqyc8dmfp6jfwuje2d94xfnzyd',
'amount': 5,
'nonce': 2,
'gasPrice': 1,
'gasLimit': 100,
}
signed_tx = staking_signing.sign_staking_transaction(transaction_dict, '4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48')
```
For validator-related transactions, see the [section on the Validator class](#validator-class).
## Keeping your private key safe
You need `eth-keyfile` installed
```bash
pip install eth-keyfile
```
In a `Python` shell, you can save or load the key into / from a key file.
```py
import eth_keyfile
from eth_utils import to_bytes, to_hex
import json
keyfile = eth_keyfile.create_keyfile_json(to_bytes(hexstr='01F903CE0C960FF3A9E68E80FF5FFC344358D80CE1C221C3F9711AF07F83A3BD'), b'password')
with open('keyfile.json', 'w+') as outfile:
json.dump(keyfile, outfile)
private_key = to_hex(eth_keyfile.extract_key_from_keyfile('keyfile.json', b'password'))[2:].upper()
```
Raw data
{
"_id": null,
"home_page": "",
"name": "pyhmy",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.0",
"maintainer_email": "",
"keywords": "Harmony,blockchain,protocol,staking",
"author": "",
"author_email": "",
"download_url": "https://files.pythonhosted.org/packages/78/c3/11532b359be961891fa96b2abb7edc23ac0db2bcb8dbfec60813d419f4db/pyhmy-0.1.0.tar.gz",
"platform": null,
"description": "# Pyhmy - Harmony's python utilities\n\n**This library only supports Python 3.6+**\n\nA Python library for interacting and working the [Harmony blockchain](https://harmony.one/)\nand [related codebases](https://github.com/harmony-one).\n\n[Full documentation is located on Harmony's GitBook](https://docs.harmony.one/) (in progress).\n\n## Installation\n```bash\npip install pyhmy\n```\nOn MacOS:\nMake sure you have Python3 installed, and use python3 to install pyhmy\n```bash\nsudo pip3 install pathlib\nsudo pip3 install pyhmy\n```\n\n## Development\n\nClone the repository and then run the following:\n```bash\nmake install\n```\n\n## Running tests\nBefore you can run tests, you need the python dependencies (`make install`), `docker` and `go` installed to quickly run a local blockchain with staking enabled (detailed instructions [here](https://github.com/harmony-one/harmony/blob/main/README.md)):\n```bash\nmkdir -p $(go env GOPATH)/src/github.com/harmony-one\ncd $(go env GOPATH)/src/github.com/harmony-one\ngit clone https://github.com/harmony-one/mcl.git\ngit clone https://github.com/harmony-one/bls.git\ngit clone https://github.com/harmony-one/harmony.git\ncd harmony\nmake debug\n```\n\nOnce the terminal displays a couple of `Started server` lines, use another shell to run the following tests\n```bash\nmake test\n```\nOr directly with `pytest` (reference [here](https://docs.pytest.org/en/latest/index.html) for more info):\n```bash\npytest tests\n```\n\n## Releasing\n\nYou can release this library with the following command (assuming you have the credentials to upload):\n```bash\nmake release\n```\n## Usage\n```py\ntest_net = 'https://api.s0.b.hmny.io'\t\t\t\t# this is shard 0\ntest_net_shard_1 = 'https://api.s1.b.hmny.io'\ntest_address = 'one18t4yj4fuutj83uwqckkvxp9gfa0568uc48ggj7'\n\nmain_net = 'https://rpc.s0.t.hmny.io'\nmain_net_shard_1 = 'https://rpc.s1.t.hmny.io'\n```\n#### utilities\n##### Address conversion\n```py\nfrom pyhmy import util\nhex_addr = util.convert_one_to_hex('one155jp2y76nazx8uw5sa94fr0m4s5aj8e5xm6fu3')\none_addr = util.convert_hex_to_one('0xA5241513DA9F4463F1d4874b548dFBAC29D91f34')\n```\n##### Ether / Wei conversion\n```py\nfrom pyhmy import numbers\none_ether_in_wei = numbers.convert_one_to_atto(1) # as a decimal.Decimal\nwei_to_ether = numbers.convert_atto_to_one(int(1e18))\n```\n#### accounts\n```py\nfrom pyhmy import account\n```\n##### Balance / account related information\n````py\nbalance = account.get_balance(test_address, endpoint=test_net)\t\t\t\t# on shard 0, in ATTO\ntotal_balance = account.get_total_balance(test_address, endpoint=test_net)\t# on all shards, in ATTO\nbalance_by_shard = account.get_balance_on_all_shards(test_address, endpoint=test_net)\t# list of dictionaries with shard and balance as keys\ngenesis_balance = account.get_balance_by_block(test_address, block_num=0, endpoint=test_net)\nlatest_balance = account.get_balance_by_block(test_address, block_num='latest', endpoint=test_net)\t# block_num can be a string 'latest', or 'pending', if implemented at the RPC level\naccount_nonce = account.get_account_nonce(test_address, block_num='latest', endpoint=test_net)\n````\n##### Transaction counts\n````py\ntx_count = account.get_transactions_count(test_address, tx_type='ALL', endpoint=test_net)\nsent_tx_count = account.get_transactions_count(test_address, tx_type='SENT', endpoint=test_net)\nreceived_tx_count = account.get_transactions_count(test_address, tx_type='RECEIVED', endpoint=test_net)\nlegacy_tx_count = account.get_transaction_count(test_address, block_num='latest', endpoint=test_net)\t# API is legacy\nlegacy_tx_count_pending = account.get_transaction_count(test_address, block_num='pending', endpoint=test_net)\n````\n##### Staking transaction counts\n````py\nstx_count = account.get_staking_transactions_count(test_address, tx_type='ALL', endpoint=test_net)\nsent_stx_count = account.get_staking_transactions_count(test_address, tx_type='SENT', endpoint=test_net)\nreceived_stx_count = account.get_staking_transactions_count(test_address, tx_type='RECEIVED', endpoint=test_net)\n````\n##### Transaction history\nTo get a list of hashes, use `include_full_tx=False`\n````py\nfirst_100_tx_hashes = account.get_transaction_history(test_address, page=0, page_size=100, include_full_tx=False, endpoint=test_net)\n````\nTo get the next 100 transactions, change the `page`\n```py\nnext_100_tx_hashes = account.get_transaction_history(test_address, page=1, page_size=100, include_full_tx=False, endpoint=test_net)\n```\nTo get a list of full transaction details, use `include_full_tx=True` (see `get_transaction_by_hash` for the reply structure\n````py\nfirst_3_full_tx = account.get_transaction_history(test_address, page=0, page_size=3, include_full_tx=True, endpoint=test_net)\n````\nTo get newest transactions, use `order='DESC'`\n````py\nlast_3_full_tx = account.get_transaction_history(test_address, page=0, page_size=3, include_full_tx=True, order='DESC', endpoint=test_net)\n````\nTo change the transaction type (SENT / RECEIVED / ALL), pass the `tx_type` parameter\n```py\nfirst_100_received_tx_hashes = account.get_transaction_history(test_address, page=0, page_size=100, include_full_tx=False, tx_type='RECEIVED', endpoint=test_net)\n```\n##### Staking transaction history\nTo get a list of staking hashes, use `include_full_tx=False`\n````py\nfirst_100_stx_hashes = account.get_staking_transaction_history(test_address, page=0, page_size=100, include_full_tx=False, endpoint=test_net)\n````\nTo get the next 100 staking transactions, change the `page`\n```py\nnext_100_stx_hashes = account.get_staking_transaction_history(test_address, page=1, page_size=100, include_full_tx=False, endpoint=test_net)\n```\nTo get a list of full staking transaction details, use `include_full_tx=True` (see `get_transaction_by_hash` for the reply structure\n````py\nfirst_3_full_stx = account.get_staking_transaction_history(test_address, page=0, page_size=3, include_full_tx=True, endpoint=test_net)\n````\nTo get newest staking transactions, use `order='DESC'`\n````py\nlast_3_full_stx = account.get_staking_transaction_history(test_address, page=0, page_size=3, include_full_tx=True, order='DESC', endpoint=test_net)\n````\nTo change the staking transaction type (SENT / RECEIVED / ALL), pass the `tx_type` parameter\n```py\nfirst_100_received_stx_hashes = account.get_staking_transaction_history(test_address, page=0, page_size=100, include_full_tx=False, tx_type='RECEIVED', endpoint=test_net)\n```\n#### Blockchain\n```py\nfrom pyhmy import blockchain\nfrom decimal import Decimal\n```\n##### Node / network information\n```py\nchain_id = blockchain.chain_id(test_net)\t\t\t\t\t# chain type, for example, mainnet or testnet\nnode_metadata = blockchain.get_node_metadata(test_net)\t\t# metadata about the endpoint\npeer_info = blockchain.get_peer_info(test_net)\t\t\t\t# peers of the endpoint\nprotocol_version = blockchain.protocol_version(test_net)\t# protocol version being used\nnum_peers = blockchain.get_num_peers(test_net)\t\t\t\t# number of peers of the endpoin\nversion = blockchain.get_version(test_net)\t\t\t\t\t# EVM chain id, https://chainid.network\nis_node_in_sync = blockchain.in_sync(test_net)\t\t\t\t\t\t# whether the node is in sync (not out of sync or not syncing)\nis_beacon_in_sync = blockchain.beacon_in_sync(test_net)\t\t# whether the beacon node is in sync\nprestaking_epoch_number = blockchain.get_prestaking_epoch(test_net)\nstaking_epoch_number = blockchain.get_staking_epoch(test_net)\n```\n##### Sharding information\n```py\nshard_id = blockchain.get_shard(test_net)\t\t\t\t\t\t\t# get shard id of the endpoint\nsharding_structure = blockchain.get_sharding_structure(test_net)\t# list of dictionaries, each representing a shard\nlast_cross_links = blockchain.get_last_cross_links(test_net)\t\t# list of dictionaries for each shard except test_net\n```\n##### Current network status\n```py\nleader_address = blockchain.get_leader_address(test_net)\nis_last_block = blockchain.is_last_block(block_num=0, test_net)\nlast_block_of_epoch5 = blockchain.epoch_last_block(block_num=5, test_net)\ncirculating_supply = Decimal(blockchain.get_circulating_supply(test_net))\npremined = blockchain.get_total_supply(test_net)\t\t\t\t\t# should be None?\ncurrent_block_num = blockchain.get_block_number(test_net)\ncurrent_epoch = blockchain.get_current_epoch(test_net)\ngas_price = blockchain.get_gas_price(test_net)\t\t\t\t\t\t# this returns 1 always\n```\n##### Block headers\n```py\nlatest_header = blockchain.get_latest_header(test_net)\t\t\t\t\t\t# header contains hash, number, cross links, signature, time, etc (see get_latest_header for a full list)\nlatest_hash = latest_header['blockHash']\nlatest_number = latest_header['blockNumber']\nprevious_header = blockchain.get_header_by_number(latest_number-1, test_net)\nchain_headers = blockchain.get_latest_chain_headers(test_net_shard_1)\t\t# chain headers by beacon and shard\n```\n##### Blocks\n###### By block number\nFetch the barebones information about the block as a dictionary\n```py\nlatest_block = blockchain.get_block_by_number(block_num='latest', endpoint=test_net)\n```\nFetch a block with full information (`full_tx=True`) for each transaction in the block\n```py\nblock = blockchain.get_block_by_number(block_num=9017724, full_tx=True, include_tx=True, include_staking_tx=True, endpoint=test_net)\n```\nFetch a block and only staking transactions (`include_tx=False, include_staking_tx=True`) for the block\n```py\nblock = blockchain.get_block_by_number(block_num='latest', include_tx=False, include_staking_tx=True, endpoint=test_net)\n```\nFetch block signer addresses (`include_signers=True`) as a list\n```py\nsigners = blockchain.get_block_by_number(block_num=9017724, include_signers=True, endpoint=test_net)['signers']\n```\nOr, alternatively, use the direct `get_block_signers` method:\n```py\nsigners = blockchain.get_block_signers(block_num=9017724, endpoint=test_net)\n```\nFetch the public keys for signers\n```py\nsigners_keys = blockchain.get_block_signers_keys(block_num=9017724, endpoint=test_net)\n```\nCheck if an address is a signer for a block\n```py\nis_block_signer = blockchain.is_block_signer(block_num=9017724, address='one1yc06ghr2p8xnl2380kpfayweguuhxdtupkhqzw', endpoint=test_net)\n```\nFetch the number of blocks signed by a particular validator for the last epoch\n```py\nnumber_signed_blocks = blockchain.get_signed_blocks(address='one1yc06ghr2p8xnl2380kpfayweguuhxdtupkhqzw', endpoint=test_net)\n```\nFetch a list of validators and their public keys for specific epoch number\n```py\nvalidators = blockchain.get_validators(epoch=12, endpoint=test_net)\nvalidator_keys = blockchain.get_validator_keys(epoch=12, endpoint=test_net)\n```\nFetch number of transactions\n```py\ntx_count = blockchain.get_block_transaction_count_by_number(block_num='latest', endpoint=test_net)\n```\nFetch number of staking transactactions\n```py\nstx_count = blockchain.get_block_staking_transaction_count_by_number(block_num='latest', endpoint=test_net)\n```\nFetch a list of blocks using the block numbers\n```py\nblocks = blockchain.get_blocks(start_block=0, end_block=2, full_tx=False, include_tx=False, include_staking_tx=False, include_signers=False, endpoint=test_net)\n```\n###### By block hash\nMost of the functions described above can be applied for fetching information about a block whose hash is known, for example:\n```py\nblock_hash = '0x44fa170c25f262697e5802098cd9eca72889a637ea52feb40c521f2681a6d720'\nblock = blockchain.get_block_by_hash(block_hash=block_hash, endpoint=test_net)\nblock_with_full_tx = blockchain.get_block_by_hash(block_hash=block_hash, full_tx=True, include_tx=True, include_staking_tx=True, endpoint=test_net)\nblock_with_only_staking_tx = blockchain.get_block_by_hash(block_hash=block_hash, include_tx=False, include_staking_tx=True, endpoint=test_net)\nsigners = blockchain.get_block_by_hash(block_hash=block_hash, include_signers=True, endpoint=test_net)['signers']\ntx_count = blockchain.get_block_transaction_count_by_hash(block_hash=block_hash, endpoint=test_net)\nstx_count = blockchain.get_block_staking_transaction_count_by_hash(block_hash=block_hash, endpoint=test_net)\n```\n#### Staking\n```py\nfrom pyhmy import staking\nvalidator_addr = 'one1xjanr7lgulc0fqyc8dmfp6jfwuje2d94xfnzyd'\ndelegator_addr = 'one1y2624lg0mpkxkcttaj0c85pp8pfmh2tt5zhdte'\n```\n##### Validation\n```py\nall_validators = staking.get_all_validator_addresses(endpoint=test_net)\t\t\t\t\t\t\t# list of addresses\nvalidator_information = staking.get_validator_information(validator_addr, endpoint=test_net)\t# dict with all info\nvalidator_information_100 = staking.get_all_validator_information(page=0, endpoint=test_net)\nelected_validators = staking.get_elected_validator_addresses(endpoint=test_net)\t\t\t\t\t# list of addresses\nvalidators_for_epoch = staking.get_validators(epoch=73772, endpoint=test_net)\t\t\t\t\t# dict with list of validators and balance\nvalidators_information_100_for_block = staking.get_all_validator_information_by_block_number(block_num=9017724, page=0, endpoint=test_net)\nvalidator_keys_for_epoch = staking.get_validator_keys(epoch=73772, endpoint=test_net)\t\t\t# list of public keys\nvalidator_information_at_block = staking.get_validator_information_by_block_number(validator_addr, block_num=9017724, endpoint=test_net)\nself_delegation = staking.get_validator_self_delegation(validator_addr, endpoint=test_net)\ntotal_delegation = staking.get_validator_total_delegation(validator_addr, endpoint=test_net)\n```\n##### Delegation\n```py\ndelegation_information = staking.get_all_delegation_information(page=0, endpoint=test_net)\ndelegations_by_delegator = staking.get_delegations_by_delegator(delegator_addr, test_net)\ndelegations_by_delegator_at_block = staking.get_delegations_by_delegator_by_block_number(delegator_addr, block_num=9017724, endpoint=test_net)\ndelegation_by_delegator_and_validator = staking.get_delegation_by_delegator_and_validator(delegator_addr, validator_addr, test_net)\navail_redelegation_balance = staking.get_available_redelegation_balance(delegator_addr, test_net)\ndelegations_by_validator = staking.get_delegations_by_validator(validator_addr, test_net)\t\t# list of delegations made to this validator, each a dictionary\n```\n##### Network\n```py\nutility_metrics = staking.get_current_utility_metrics(test_net)\nnetwork_info = staking.get_staking_network_info(test_net)\nsuper_committees = staking.get_super_committees(test_net)\nsuper_committees_current = super_committees['current']\t\t# list of voting committees as a dict\nsuper_committees_previous = super_committees['previous']\ntotal_staking = staking.get_total_staking(endpoint=test_net)\t# by all validators, only for beaconchain\nmedian_stake_snapshot = staking.get_raw_median_stake_snapshot(test_net)\n```\n##### Validator class\nInstantiate a validator object and load it from the chain\n```py\nfrom pyhmy.validator import Validator\nvalidator = Validator(validator_addr)\nvalidator.load_from_blockchain(test_net)\n```\nCreate a new validator object and load from dictionary\n```py\nfrom pyhmy.numbers import convert_one_to_atto\nvalidator = Validator('one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9')\ninfo = {\n 'name': 'Alice',\n 'identity': 'alice',\n 'website': 'alice.harmony.one',\n 'details': \"Don't mess with me!!!\",\n 'security-contact': 'Bob',\n 'min-self-delegation': convert_one_to_atto(10000),\n 'amount': convert_one_to_atto(10001),\n 'max-rate': '0.9',\n 'max-change-rate': '0.05',\n 'rate': '0.01',\n 'bls-public-keys': ['0xa20e70089664a874b00251c5e85d35a73871531306f3af43e02138339d294e6bb9c4eb82162199c6a852afeaa8d68712'],\n \"bls-key-sigs\": [\n \"0xef2c49a2f31fbbd23c21bc176eaf05cd0bebe6832033075d81fea7cff6f9bc1ab42f3b6895c5493fe645d8379d2eaa1413de55a9d3ce412a4f747cb57d52cc4da4754bfb2583ec9a41fe5dd48287f964f276336699959a5fcef3391dc24df00d\",\n ]\n 'max-total-delegation': convert_one_to_atto(40000)\n }\nvalidator.load(info)\n```\nSign a validator creation transaction\n```py\nsigned_create_tx_hash = validator.sign_create_validator_transaction(\n nonce = 2,\n gas_price = 1,\n gas_limit = 100,\n private_key = '4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48',\n chain_id = 2).rawTransaction.hex()\n```\nTo edit validator, change its parameters using the `setter` functions, for example, `validator.set_details`, except the `rate`, `bls_keys_to_add` and `bls_keys_to_remove` which can be passed to the below function:\n```py\nsigned_edit_tx_hash = validator.sign_edit_validator_transaction(\n nonce = 2,\n gas_price = 1,\n gas_limit = 100,\n rate = '0.06',\n bls_key_to_add = \"0xb8c3b3a0f1966c169ca73c348f4b8aee333a407125ab5c67f1d6e1e18ab052ed5fff0f1f7d4a7f789528b5ccd9c47b04\",\n bls_key_to_add_sig = \"0x3de4dff17451fb76a9690efce34bced97dd87eccd371fcd25335826cb879ca21281e82e5c2c76d4ef0ab0fc16e462312628834cbc1f29008b28e16a757367808be85180945b991be3103f98c14c7e3b3e54796d34aab4d8e812d440aa251c419\",\n bls_keys_to_remove = '0xa20e70089664a874b00251c5e85d35a73871531306f3af43e02138339d294e6bb9c4eb82162199c6a852afeaa8d68712',\n private_key = '4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48',\n chain_id = 2).rawTransaction.hex()\n```\n\n### Transactions\n```py\nfrom pyhmy import transaction\n```\n##### Pool\n```py\npending_tx = transaction.get_pending_transactions(test_net)\npending_stx = transaction.get_pending_staking_transactions(test_net)\ntx_error_sink = transaction.get_transaction_error_sink(test_net)\nstx_error_sink = transaction.get_staking_transaction_error_sink(test_net)\npool_stats = transaction.get_pool_stats(test_net)\npending_cx_receipts = transaction.get_pending_cx_receipts(test_net)\n```\n##### Fetching transactions\n```py\ntx_hash = '0x500f7f0ee70f866ba7e80592c06b409fabd7ace018a9b755a7f1f29e725e4423'\nblock_hash = '0xb94bf6e8a8a970d4d42dfe42f7f231af0ff7fd54e7f410395e3b306f2d4000d4'\ntx = transaction.get_transaction_by_hash(tx_hash, test_net)\t\t\t# dict with tx-level info like from / to / gas\ntx_from_block_hash = transaction.get_transaction_by_block_hash_and_index(block_hash, tx_index=0, endpoint=test_net)\ntx_from_block_number = transaction.get_transaction_by_block_number_and_index(9017724, tx_index=0, endpoint=test_net)\ntx_receipt = transaction.get_transaction_receipt(tx_hash, test_net)\n```\n##### Fetching staking transactions\n```py\nstx_hash = '0x3f616a8ef34f111f11813630cdcccb8fb6643b2affbfa91d3d8dbd1607e9bc33'\nblock_hash = '0x294dc88c7b6f3125f229a3cfd8d9b788a0bcfe9409ef431836adcd83839ba9f0'\t# block number 9018043\nstx = transaction.get_staking_transaction_by_hash(stx_hash, test_net)\nstx_from_block_hash = transaction.get_staking_transaction_by_block_hash_and_index(block_hash, tx_index=0, endpoint=test_net)\nstx_from_block_number = transaction.get_staking_transaction_by_block_number_and_index(9018043, tx_index=0, endpoint=test_net)\n```\n##### Cross shard transactions\n```py\ncx_hash = '0xd324cc57280411dfac5a7ec2987d0b83e25e27a3d5bb5d3531262387331d692b'\ncx_receipt = transaction.get_cx_receipt_by_hash(cx_hash, main_net_shard_1)\t# the shard which receives the tx\ntx_resent = transaction.resend_cx_receipt(cx_hash, main_net)\t\t\t\t# beacon chain\n```\n##### Sending transactions\nSign it with your private key and use `send_raw_transaction`\n```py\nfrom pyhmy import signing\ntx = {\n'chainId': 2,\n'from': 'one18t4yj4fuutj83uwqckkvxp9gfa0568uc48ggj7',\n'gas': 6721900,\n'gasPrice': 1000000000,\n'nonce': 6055,\n'shardID': 0,\n'to': 'one1ngt7wj57ruz7kg4ejp7nw8z7z6640288ryckh9',\n'toShardID': 0,\n'value': 500000000000000000000\n}\ntransaction.send_raw_transaction(signing.sign_transaction(tx, '01F903CE0C960FF3A9E68E80FF5FFC344358D80CE1C221C3F9711AF07F83A3BD').rawTransaction.hex(), test_net)\n```\nA similar approach can be followed for staking transactions\n```py\nfrom pyhmy import staking_structures, staking_signinge\ntx = {\n 'chainId': 2,\n 'delegatorAddress': 'one18t4yj4fuutj83uwqckkvxp9gfa0568uc48ggj7',\n 'directive': staking_structures.Directive.CollectRewards,\n 'gasLimit': 6721900,\n 'gasPrice': 1,\n 'nonce': 6056\n}\ntransaction.send_raw_staking_transaction(staking_signing.sign_staking_transaction(tx, private_key = '01F903CE0C960FF3A9E68E80FF5FFC344358D80CE1C221C3F9711AF07F83A3BD').rawTransaction.hex(), test_net)\n```\n### Contracts\n```py\nfrom pyhmy import contract\nfrom pyhmy.util import convert_one_to_hex\ncontract_addr = 'one1rcs4yy4kln53ux60qdeuhhvpygn2sutn500dhw'\n```\nCall a contract without saving state\n```py\nfrom pyhmy import numbers\nresult = contract.call(convert_one_to_hex(contract_addr), 'latest', value=hex(int(numbers.convert_one_to_atto(5)))\n, gas_price=hex(1), gas=hex(100000), endpoint=test_net)\n```\nEstimate gas required for a smart contract call\n```py\nestimated_gas = contract.estimate_gas(convert_one_to_hex(contract_addr), endpoint=test_net)\n```\nFetch the byte code of the contract\n```py\nbyte_code = contract.get_code(convert_one_to_hex(contract_addr), 'latest', endpoint=test_net)\n```\nGet storage in the contract at `key`\n```py\nstorage = contract.get_storage_at(convert_one_to_hex(contract_addr), key='0x0', block_num='latest', endpoint=test_net)\n```\nCalling a function on a contract needs the contract ABI. The ABI can be obtained by compiling the contract.\n```py\nfrom web3 import Web3\nfrom web3 import providers\nfrom pyhmy.util import convert_one_to_hex\ncontract_abi = '[{\"constant\":true,\"inputs\":[],\"name\":\"manager\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"pickWinner\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getPlayers\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"enter\",\"outputs\":[],\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"players\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]'\nw3 = Web3(providers.HTTPProvider(test_net))\nlottery = w3.eth.contract(abi=contract_abi, address=convert_one_to_hex('one1rcs4yy4kln53ux60qdeuhhvpygn2sutn500dhw'))\nlottery.functions.getPlayers().call()\n```\nTo actually participate in a contract, you can sign a transaction from your account to it.\n```py\nfrom pyhmy import signing\ncontract_addr = 'one1rcs4yy4kln53ux60qdeuhhvpygn2sutn500dhw'\ntx = {\n 'chainId': 2,\n 'from': 'one18t4yj4fuutj83uwqckkvxp9gfa0568uc48ggj7',\n 'gas': 6721900,\n 'gasPrice': 1000000000,\n 'nonce': 6054,\n 'shardID': 0,\n 'to': contract_addr,\n 'toShardID': 0,\n 'value': 500000000000000000000\n}\ntx_hash = transaction.send_raw_transaction(signing.sign_transaction(tx, '01F903CE0C960FF3A9E68E80FF5FFC344358D80CE1C221C3F9711AF07F83A3BD').rawTransaction.hex(), test_net)\n```\nTo deploy a contract, sign a transaction from your account without a `to` field and with the byte code as `data` and send it.\n```py\nfrom pyhmy import signing\nfrom pyhmy import transaction\ncontract_tx = {\n 'chainId': 2,\t# test net data\n 'data': '0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063445df0ac146100465780638da5cb5b14610064578063fdacd576146100ae575b600080fd5b61004e6100dc565b6040518082815260200191505060405180910390f35b61006c6100e2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100da600480360360208110156100c457600080fd5b8101908080359060200190929190505050610107565b005b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561016457806001819055505b5056fea265627a7a723158209b80813a158b44af65aee232b44c0ac06472c48f4abbe298852a39f0ff34a9f264736f6c63430005100032', \t# Migrations.sol\n 'from': 'one18t4yj4fuutj83uwqckkvxp9gfa0568uc48ggj7',\n 'gas': 6721900,\n 'gasPrice': 1000000000,\n 'nonce': 6049,\n 'shardID': 0,\n 'toShardID': 0\n}\nctx_hash = transaction.send_raw_transaction(signing.sign_transaction(contract_tx, private_key = '01F903CE0C960FF3A9E68E80FF5FFC344358D80CE1C221C3F9711AF07F83A3BD').rawTransaction.hex(), test_net)\n# the below may be need a time gap before the transaction reaches the chain\ncontract_address = transaction.get_transaction_receipt(ctx_hash, test_net)['contractAddress']\n```\n### Signing transactions\n```py\nfrom pyhmy import signing\n```\nCreate a `transaction_dict` with the parameters, and supply your private key to sign (but not submit) a transaction. A signed transaction can be submitted using `transaction.sendRawTransaction`.\n```py\ntransaction_dict = {\n 'nonce': 2,\n 'gasPrice': 1,\n 'gas': 100, # signing.py uses Ether, which by default calls it gas\n 'to': '0x14791697260e4c9a71f18484c9f997b308e59325',\n 'value': 5,\n 'shardID': 0,\n 'toShardID': 1,\n 'chainId': 'HmyMainnet'\n }\nsigned_tx = signing.sign_transaction(transaction_dict, private_key = '4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48')\nsigned_hash = signed_tx.rawTransaction.hex()\n```\nFor a transaction with is Ethereum-like, the `shardID` and `toShardID` are optional, which implies that the transaction is not cross-shard.\n```py\ntransaction_dict = {\n 'nonce': 2,\n 'gasPrice': 1,\n 'gas': 100, # signing.py uses Ether, which by default calls it gas\n 'to': '0x14791697260e4c9a71f18484c9f997b308e59325',\n 'value': 5,\n }\nsigned_tx = signing.sign_transaction(transaction_dict, private_key = '4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48')\nsigned_hash = signed_tx.rawTransaction.hex()\n```\nThe `chainId` parameter is also optional, and [according to Ethereum](https://github.com/ethereum/eth-account/blob/00e7b10005c5fa7090086fcef37a76296c524e17/eth_account/_utils/transactions.py#L122), it should not be passed if \"you want a transaction that can be replayed across networks.\" A full list of the possible values of `chainId` is provided below. You can pass either the `str` or the `int`. The RPC API may, however, reject the transaction, which is why it is recommended to pass either `1` or `2` for `mainnet` and `testnet` respectively.\n```py\nDefault = 0,\nEthMainnet = 1,\nMorden = 2,\nRopsten = 3,\nRinkeby = 4,\nRootstockMainnet = 30,\nRootstockTestnet = 31,\nKovan = 42,\nEtcMainnet = 61,\nEtcTestnet = 62,\nGeth = 1337,\nGanache = 0,\nHmyMainnet = 1,\nHmyTestnet = 2,\nHmyLocal = 2,\nHmyPangaea = 3,\n```\n### Signing staking transactions\n```py\nfrom pyhmy import staking_structures, staking_signing\n```\nTo sign a transaction to collect rewards, supply the dictionary containing the `delegatorAddress` and the private key.\n```py\ntransaction_dict = {\n 'directive': staking_structures.Directive.CollectRewards,\n 'delegatorAddress': 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',\n 'nonce': 2,\n 'gasPrice': 1,\n 'gasLimit': 100,\n}\nsigned_tx = staking_signing.sign_staking_transaction(transaction_dict, private_key = '4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48')\n```\nTo sign a transaction to delegate or undelegate, supply the dictionary containing the `delegatorAddress`, the `validatorAddress`, the `amount` to delegate or undelegate, and the private key.\n```py\ntransaction_dict = {\n 'directive': staking_structures.Directive.Delegate,\n 'delegatorAddress': 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',\n 'validatorAddress': 'one1xjanr7lgulc0fqyc8dmfp6jfwuje2d94xfnzyd',\n 'amount': 5,\n 'nonce': 2,\n 'gasPrice': 1,\n 'gasLimit': 100,\n }\nsigned_tx = staking_signing.sign_staking_transaction(transaction_dict, '4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48')\ntransaction_dict = {\n 'directive': staking_structures.Directive.Undelegate,\n 'delegatorAddress': 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',\n 'validatorAddress': 'one1xjanr7lgulc0fqyc8dmfp6jfwuje2d94xfnzyd',\n 'amount': 5,\n 'nonce': 2,\n 'gasPrice': 1,\n 'gasLimit': 100,\n }\nsigned_tx = staking_signing.sign_staking_transaction(transaction_dict, '4edef2c24995d15b0e25cbd152fb0e2c05d3b79b9c2afd134e6f59f91bf99e48')\n```\nFor validator-related transactions, see the [section on the Validator class](#validator-class).\n## Keeping your private key safe\nYou need `eth-keyfile` installed\n```bash\npip install eth-keyfile\n```\nIn a `Python` shell, you can save or load the key into / from a key file.\n```py\nimport eth_keyfile\nfrom eth_utils import to_bytes, to_hex\nimport json\nkeyfile = eth_keyfile.create_keyfile_json(to_bytes(hexstr='01F903CE0C960FF3A9E68E80FF5FFC344358D80CE1C221C3F9711AF07F83A3BD'), b'password')\nwith open('keyfile.json', 'w+') as outfile:\n json.dump(keyfile, outfile)\n\nprivate_key = to_hex(eth_keyfile.extract_key_from_keyfile('keyfile.json', b'password'))[2:].upper()\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A library for interacting and working the Harmony blockchain and related codebases",
"version": "0.1.0",
"split_keywords": [
"harmony",
"blockchain",
"protocol",
"staking"
],
"urls": [
{
"comment_text": "",
"digests": {
"md5": "5831b87bc51a7492c26e5ac326911042",
"sha256": "932b0ac0dc976eea93a7ca0c3108a4cb3d8912e851c8ec04192ed387de4b0329"
},
"downloads": -1,
"filename": "pyhmy-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5831b87bc51a7492c26e5ac326911042",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.0",
"size": 55685,
"upload_time": "2022-08-24T19:24:08",
"upload_time_iso_8601": "2022-08-24T19:24:08.367230Z",
"url": "https://files.pythonhosted.org/packages/8f/71/9bede2e2993a31c732128109825e993bcf0faa436d654bbf0cc030df5356/pyhmy-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"md5": "64e2e39926796ea39a5eced24bf99473",
"sha256": "badb449364c29be2d63f2f2d6a2e9813813c6b09e7f79ef29cba063da23afb87"
},
"downloads": -1,
"filename": "pyhmy-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "64e2e39926796ea39a5eced24bf99473",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.0",
"size": 57289,
"upload_time": "2022-08-24T19:24:11",
"upload_time_iso_8601": "2022-08-24T19:24:11.629456Z",
"url": "https://files.pythonhosted.org/packages/78/c3/11532b359be961891fa96b2abb7edc23ac0db2bcb8dbfec60813d419f4db/pyhmy-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2022-08-24 19:24:11",
"github": false,
"gitlab": false,
"bitbucket": false,
"lcname": "pyhmy"
}