/celo-sdk-py

Primary LanguagePythonApache License 2.0Apache-2.0

Python ContractKit

Celo's ContractKit is a library to help developers and validators to interact with the celo-blockchain.

ContractKit supports the following functionality:

  • Connect to a node
  • Access web3 object to interact with node's Json RPC API
  • Send Transaction with celo's extra fields: (feeCurrency)
  • Simple interface to interact with CELO and cUSD
  • Simple interface to interact with Celo Core contracts
  • Utilities

User Guide

Getting Started

To install:

pip install .

You need in Python version 3.8 or higher.

To start working with python contractkit you need a Kit instance:

from celo_sdk.kit import Kit

kit = Kit('https://alfajores-forno.celo-testnet.org')

To access web3:

kit.w3.eth.getBalance(some_address)

Setting Default Tx Options

Kit allows you to set default transaction options:

from celo_sdk.kit import Kit

kit = Kit('https://alfajores-forno.celo-testnet.org')
currency_address = kit.base_wrapper.registry.load_contract_by_name('StableToken')['address']
kit.wallet_fee_currency = currency_address

Interacting with CELO & cUSD

celo-blockchain has two initial coins: CELO and cUSD (stableToken). Both implement the ERC20 standard, and to interact with them is as simple as:

gold_token = kit.base_wrapper.create_and_get_contract_by_name('GoldToken')
balance = gold_token.balance_of(address)

To send funds:

one_gold = kit.w3.toWei(1, 'ether')
tx_hash = gold_token.transfer(address, one_gold)

To interact with cUSD, is the same but with a different contract:

stable_token = kit.base_wrapper.create_and_get_contract_by_name('StableToken')

If you would like to pay fees in cUSD, set the gas price manually:

stable_token = kit.base_wrapper.create_and_get_contract_by_name('StableToken')
gas_price_contract = kit.base_wrapper.create_and_get_contract_by_name('GasPriceMinimum')
gas_price_minimum = gas_price_contract.get_gas_price_minimum(stable_token.address)
gas_price = int(gas_price_minimum * 1.3) # Wiggle room if gas price minimum changes before tx is sent
kit.wallet_fee_currency = stable_token.address # Default to paying fees in cUSD
kit.wallet_gas_price = gas_price

tx = stable_token.transfer(recipient, wei_transfer_amount)

Interacting with Other Contracts

Apart from GoldToken and StableToken, there are many core contracts.

For the moment, we have contract wrappers for:

  • Accounts
  • Attestations
  • BlockchainParameters
  • DoubleSigningSlasher
  • DowntimeSlasher
  • Election
  • LockedGold
  • Escrow
  • Exchange
  • Freezer
  • GasPriceMinimum
  • GoldToken
  • Governance
  • MultiSig
  • Reserve
  • ReleaseGold
  • SortedOracles
  • StableToken
  • Validators

To create object of contract wrapper you shold set one of those contract names as a parameter to function BaseWrapper.create_and_get_contract_by_name(...)

A Note About Contract Addresses

Celo Core Contracts addresses, can be obtained by looking at the Registry contract. That's actually how BaseWrapper obtain them.

We expose the registry api, which can be accessed by:

gold_token_address = kit.base_wrapper.registry.load_contract_by_name('GoldToken')['address']

Adding new keys to the wallet

Wallet object by defaut generate some private key

But of course you can add your own already generated private key or generate new one

To add your own:

from celo_sdk.kit import Kit

kit = Kit('https://alfajores-forno.celo-testnet.org')
kit.wallet_add_new_key = '0xf2f48ee19680706196e2e339e5da3491186e0c4c5030670656b0e0164837257d'

To generate new one:

new_key = kit.generate_new_key()
kit.wallet_add_new_key = new_key

To see all the wallet accounts:

accounts = kit.wallet.accounts

And to switch between accounts:

kit.wallet_change_account = existing_account_address  # address of account has to be in wallet.__accounts dict

Signing messages with wallet

In addition to signing the transaction, the wallet can sign messages:

from celo_sdk.kit import Kit
from celo_sdk.celo_account.messages import encode_defunct

kit = Kit('https://alfajores-forno.celo-testnet.org')
message = kit.w3.soliditySha3(['address'], [signer]).hex()  # For example we want to sign someones address
message = encode_defunct(hexstr=message)
signature = kit.wallet.active_account.sign_message(message)