Uma implementação simples de blockchain/criptomoeda comp propósitos educacionais.
UCLCoin é distribuido via PyPI, está disponível para Linux/macOS e Windows e suporta Python 3.6+.
$ pip install -U uclcoin
Nos exemplos abaixo assume-se que as dendencias necessárias foram previamente importadas.
>>> from uclcoin import KeyPair, Transaction, Block, BlockChain
A chave privada é usada para assinar suas transações e a chave pública é o seu endereço para receber moedas e recompensas de mineração.
Você pode gerar um novo par de chaves instanciando a classe KeyPair
>>> carteira = KeyPair()
>>> endereco = carteira.public_key
>>> endereco
'03d70f9a58c9bc6d8fdc47f96d6931f14a7abb0d72cd76886ee05047023fd49471'
No futuro instancie a classe KeyPair usando sua chave privada carteira.private_key
.
>>> carteira = KeyPair('sua-chave-privada')
Crie uma BlockChain vazia para realizar seus testes:
>>> blockchain = BlockChain()
Sua blockchain
contem apenas o bloco Gênesis. A blockchain está pronta para aceitar
transações, mas você não poderá enviar valores com saldo zerado.
>>> blockchain.get_balance(carteira.public_key)
0
Obtenha um bloco a ser minerado à blockchain.
>>> novo_bloco = blockchain.get_minable_block(carteira.public_key)
A blockchain retorna um novo bloco com o próximo índice válido contendo as transações pendentes e uma transação coinbase (de recompensa) destinada à sua chave publica (carteira.public_key)
A prova de trabalho na UCLCoin consiste em alterar o nonce
do bloco até
produzir um hash iniciando com N zeros, onde N é a dificuldade configurada
na blockchain. A dificuldade atual pode ser obtida pelo metodo calculate_hash_difficulty
>>> N = blockchain.calculate_hash_difficulty()
Um método simples para minerar o bloco é incrementar o nonce até produzir um hash válido
>>> while novo_bloco.current_hash[:N].count('0') < N:
... novo_bloco.nonce +=1
... novo_bloco.recalculate_hash()
Esta operação vai bloquear enquanto hash é calculado. Após minerado submeta o novo bloco. Se ele for aceito seu saldo será atualizado.
>>> blockchain.add_block(novo_bloco)
True
>>> blockchain.get_balance(carteira.public_key)
10
Agora você pode gastar suas moedas.
>>> destinatario = 'chave_publica_do_destinatario'
>>> gasto = carteira.create_transaction(destinatario, 2)
>>> blockchain.add_transaction(gasto)
True
Sua transação agora está pendente. Ela só será confirmada após ser incluída em um bloco minerado.
>>> blockchain.get_balance(carteira.public_key)
10
Você pode verificar seu saldo incluindo as transações não confirmadas, se desejar.
>>> blockchain.get_balance_pending(carteira.public_key)
8