6  Prática: Criando uma Rede Ethereum Privada: Clique

Clique

Resumo
Esta prática apresenta os passos para criarmos uma Rede Ethereum Privada Local que utilize o algoritmo de consenso clique que é um algoritmo de consenso baseado em reputação, Proof-of-Authority (PoA). Fornecemos um genesis block para inicializar a rede com as características desejadas e depois podemos executá-la para efeitos de testes de desenvolvimento ou se desejarmos ter um Rede privada funcionando.

6.1 Introdução

Podemos criar uma rede privada local utilizando o algoritmo de consenso clique que é do tipo Proof-of-Authority (PoA).

Proof-of-Authority é uma versão modificado do Proof-of-Stake (PoS) que é um algoritmo de consenso baseado em reputação em vez de um mecanismo baseado em aposta do PoS. O termo foi introduzido em 2017 por Gavin Wood, e este algoritmo de consenso tem sido usado em redes privadas, testnets e redes de desenvolvimento locais, pois supera a necessidade de recursos de alta qualidade como o PoW e resolve os problemas de escalabilidade com o PoS ao ter um pequeno subconjunto de nós armazenando o blockchain e produzindo blocos.

A Proof-of-Authority requer a confiança em um conjunto de assinantes autorizados definidos. Na maioria das implementações atuais, todos os assinantes autorizados mantêm poderes e privilégios iguais ao determinar o consenso da cadeia. A ideia por trás do staking de reputação é que todo validador autorizado seja bem conhecido de todos por meio de coisas como conheça seu cliente (KYC) ou por ter uma organização bem conhecida como o único validador - dessa forma, se um validador fizer algo errado, sua identidade será conhecida.

A rede Ethereum iniciou usando um mecanismo de consenso que envolve Proof-of-work (PoW). Entretanto, Ethereum depreciou o uso de Proof-of-Work em \(2022\) e iniciou o uso de Proof-of-Stake. Leia mais em Proof-of-Stake e staking.

6.2 Ferramentas e Versões

Para utilizarmos o algoritmo de consenso Proof-of-Authority (PoA), o clique. Para isso é necessário instalarmos o geth na versão 1.12.2, pois desde a versão v1.14 o clique foi depreciado. No link https://github.com/ethereum/go-ethereum/releases temos todas as versões, a versão Mawinor (v1.12.2).

Antes de baixarmos os fontes do geth da versão 1.12 precisaremos instalar o go. Para compilar os fontes do geth é necessário ter o go versão 1.21.1 instalado. Pode ser instalado o pacote do sistema (golang-go no Ubuntu ou go no Manjaro) ou baixando os binários de golang, go versão 1.21.1.

Se a versão do sistema não for a 1.21.*:

$ go version
go version go1.21.0 linux/amd64
$ 

Será necessário baixar e instalar a partir dos binários:

  1. Remova a instalação prévia do Go deletando o diretório /usr/local/go1.21.1, se existir, então extraia o arquivo baixado dentro do diretório /usr/local, criando uma subárvore em /usr/local/go1.21.1 ou caso não tenha permissão, crie dentro da pasta home do seu usuário:
$ cd /usr/local
$ wget https://go.dev/dl/go1.21.1.linux-amd64.tar.gz
$ rm -rf /usr/local/go1.21.1 && tar -C /usr/local -xzf go1.21.1.linux-amd64.tar.gz && mv go go1.21.1
$ ln -s go1.21.1 go

​(Você pode precisar executar o comando como root ou usando o sudo).

Não descompactar o arquivo dentro de uma subárvore /usr/local/go existente. Isso pode produzir instalações Go quebradas.

​2. Adicione /usr/local/go/bin para a variável de ambiente PATH. Você pode fazer isso adicionando a linha de comando para o seu $HOME/.profile ou /etc/profile (para uma instalação ampla no sistema):

export PATH=/usr/local/go/bin:$PATH

Nota: Mudanças feitas no arquivo de profile podem não ser aplicadas até a próxima vez que você fizer login no computador. Para aplicar as mudanças imediatamente, execute os comandos diretamente em um terminal ou execute eles do profile usando o comando source $HOME/.profile.

​3. Verifique que a versão correta do Go foi instalada:

$ go version          
  1. Confirme que o comando imprime a versão do Go instalado.

Para instalarmos o geth a partir do repositório a versão Mawinor (v1.12.2), basta acessarmos o repositório do Github e baixar na pasta do seu usuário:

$ git clone -b 'v1.12.2' --single-branch --depth 1 https://github.com/ethereum/go-ethereum.git go-ethereum-1.12.2

$ cd go-ethereum-1.12.2
[go-ethereum-1.12.2]$ make all

Após a compilação os binários estarão disponíveis no diretório go-ethereum-1.12.2/build/bin:

[go-ethereum-1.12.2]$ ls build/bin
abidump  abigen  bootnode  clef  devp2p  ethkey  evm  faucet  geth  p2psim  rlpdump
[go-ethereum-1.12.2]$

Sendo necessário considerar esse caminho dos binários para acessar os executáveis da versão correta nesta prática: $HOME/go-ethereum-1.12.2/build/bin.

6.3 Criando uma Rede Privada Local

Na prática Aula 05: Criando uma Rede Ethereum Privada - Ethash criamos uma rede privada que utiliza o algoritmo de consenso ethash.

Na versão 1.12.2 do geth não suporta algoritmo de consenso ethash, utiliza o clique. Sigamos os passos semelhantes aos da prática anterior para que entendam a diferença.

Para a criação de uma nova Rede Privada Local é necessário fazermos algumas configuraçãos. Precisamos criar um diretório mkdir ~/.etherprivate-clique para ser a base de armazenamento da nova rede. As configurações iniciais devem ser fornecidas em um genesis file. Então criamos o arquivo privategenesis.json em ~/.etherprivate-clique.

NotePassos
  1. Criar um diretório mkdir ~/.etherprivate-clique
  2. Criar um arquivo privategenesis.json em ~/.etherprivate-clique.

O conteúdo do arquivo privategenesis.json deve ser o listado no Código 6.I.

Listing 6.I: Genesis File
{
  "config": {
    "chainId": 786,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0,
    "istanbulBlock": 0,
    "berlinBlock": 0,
    "ethash": {}
  },  
  "nonce": "0x0000000000000042",
  "timestamp": "0x00",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x00",
  "gasLimit": "0x8000000",
  "difficulty": "0x0400",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x3333333333333333333333333333333333333333",
  "alloc": {}
}

Utilizando as configurações fornecidas no Código 6.I a rede será criada sem nenhum usuário, o "alloc": {} vazio indica isso. Será possível criar posteriormente conforme descrito na (Seção Section 5.6).

Uma outra forma de estabelecer a configuração inicial da rede com contas com valores alocados, é criando o usuário antes de inicializar a rede com as configurações do Genesis File, conforme o Código 6.II.

Listing 6.II: Criando Usuário para iniciar a rede
[~/.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --datadir ~/.etherprivate-clique/ account new
INFO [09-17|14:57:14.536] Maximum peer count                       ETH=50 LES=0 total=50
INFO [09-17|14:57:14.537] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
Your new account is locked with a password. Please give a password. Do not forget this password.
Password: 
Repeat password: 

Your new key was generated

Public address of the key:   0xBb36F26E6C16B3C7ED3D70bFB26F740336B4F976
Path of the secret key file: /home/rag/.etherprivate-clique/keystore/UTC--2024-09-17T17-57-24.818641852Z-- bb36f26e6c16b3c7ed3d70bfb26f740336b4f976

- You can share your public address with anyone. Others need it to interact with you.
- You must NEVER share the secret key with anyone! The key controls access to your funds!
- You must BACKUP your key file! Without the key, it's impossible to access account funds!
- You must REMEMBER your password! Without the password, it's impossible to decrypt the key!

[~/.etherprivate-clique]$

Com um id da conta criada (0xBb36F26E6C16B3C7ED3D70bFB26F740336B4F976) ou com ids de contas existentes (0x2db017e44b03b37755a4b15e14cd799f83de4c13) é possível completarmos algumas informações para inicializar a nova rede. Altere o conteúdo do arquivo privategenesis.json tal como listado no Código 6.III.

Listing 6.III: Genesis File Atualizado
{
  "config": {
    "chainId": 786,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0,
    "istanbulBlock": 0,
    "berlinBlock": 0,
    "ethash": {}
  },  
  "nonce": "0x0000000000000042",
  "timestamp": "0x00",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x00",
  "gasLimit": "0x8000000",
  "difficulty": "0x0400",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x2db017e44b03b37755a4b15e14cd799f83de4c13",
  "alloc": {
    "2db017e44b03b37755a4b15e14cd799f83de4c13": { "balance": "300000" },
    "bb36f26e6c16b3c7ed3d70bfb26f740336b4f976": { "balance": "400000" }
  }
}

Após a configuração inicial no Genesis File, o geth é utilizado para a criação e inicialização da nova Rede sendo executado com os parâmetros --datadir, indicando o diretório onde os dados da nova rede serão armazenados e com o init indicando o caminho para o Genesis File, conforme Código 5.IV.

{#@lst-init:etherprivate .bash lst-cap="Inicialização da Rede Privada Local"} [.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --identity "RAGEtherPrivate" --datadir ~/.etherprivate-clique init ~/.etherprivate-clique/privategenesis.json INFO [09-17|15:02:06.958] Maximum peer count ETH=50 LES=0 total=50 INFO [09-17|15:02:06.959] Smartcard socket not found, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory" INFO [09-17|15:02:06.962] Set global gas cap cap=50,000,000 INFO [09-17|15:02:06.962] Initializing the KZG library backend=gokzg INFO [09-17|15:02:06.987] Defaulting to pebble as the backing database INFO [09-17|15:02:06.987] Allocated cache and file handles database=/home/rag/.etherprivate-clique/geth/chaindata cache=16.00MiB handles=16 INFO [09-17|15:02:07.010] Opened ancient database database=/home/rag/.etherprivate-clique/geth/chaindata/ancient/chain readonly=false INFO [09-17|15:02:07.010] Writing custom genesis block INFO [09-17|15:02:07.011] Persisted trie from memory database nodes=1 size=143.00B time="700.524us" gcnodes=0 gcsize=0.00B gctime=0s livenodes=0 livesize=0.00B INFO [09-17|15:02:07.019] Successfully wrote genesis state database=chaindata hash=c4bd3f..d74cb0 INFO [09-17|15:02:07.019] Defaulting to pebble as the backing database INFO [09-17|15:02:07.019] Allocated cache and file handles database=/home/rag/.etherprivate-clique/geth/lightchaindata cache=16.00MiB handles=16 INFO [09-17|15:02:07.032] Opened ancient database database=/home/rag/.etherprivate-clique/geth/lightchaindata/ancient/chain readonly=false INFO [09-17|15:02:07.032] Writing custom genesis block INFO [09-17|15:02:07.032] Persisted trie from memory database nodes=1 size=143.00B time="668.676us" gcnodes=0 gcsize=0.00B gctime=0s livenodes=0 livesize=0.00B INFO [09-17|15:02:07.041] Successfully wrote genesis state database=lightchaindata hash=c4bd3f..d74cb0 [.etherprivate-clique]$ ls geth keystore privategenesis.json [.etherprivate-clique]$

Ao tentar executar o geth na versão 1.12.2 com o algoritmo de consenso ethash conforme o Código 6.IV, ocorre uma mensagem de erro.

Listing 6.IV: Execução da Rede Privada Local
[.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --identity "RAGEtherPrivate" --datadir ~/.etherprivate-clique
[.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --identity "RAGEtherPrivate" --datadir ~/.etherprivate-clique
INFO [09-17|15:07:36.179] Maximum peer count                       ETH=50 LES=0 total=50
INFO [09-17|15:07:36.180] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [09-17|15:07:36.182] Set global gas cap                       cap=50,000,000
INFO [09-17|15:07:36.182] Initializing the KZG library             backend=gokzg
INFO [09-17|15:07:36.212] Allocated trie memory caches             clean=154.00MiB dirty=256.00MiB
INFO [09-17|15:07:36.212] Using pebble as the backing database 
INFO [09-17|15:07:36.212] Allocated cache and file handles         database=/home/rag/.etherprivate-clique/geth/chaindata cache=512.00MiB handles=262,144
INFO [09-17|15:07:36.229] Opened ancient database                  database=/home/rag/.etherprivate-clique/geth/chaindata/ancient/chain readonly=false
Fatal: Failed to register the Ethereum service: ethash is only supported as a historical component of already merged networks
[.etherprivate-clique]$

No terminal de execução do geth aparece o erro:

Fatal: Failed to register the Ethereum service: ethash is only supported as a historical component of already merged networks

A mensagem de erro é sobre o encerramento do suporte ao algoritmo de consenso ethash que é da categoria Proof-of-Work. Procurando pela mensagem de erro encontramos uma resposta no link.

Ethash was the proof of work mining algorithm which seems to be turned off in the latest version. Try the 2nd latest release (Geth 1.12.2) and it should work.

from https://github.com/ethereum/go-ethereum/releases/tag/v1.12.0 :

The v1.12 release family drops support for proof-of-work, and thus can not be used any more on PoW-based private chains, or as an upstream library for projects depending on ethash PoW (#27178, #27147).

more info: https://ethereum.org/en/developers/docs/consensus-mechanisms/pow/mining-algorithms/ethash/

O link https://ethereum.org/en/developers/docs/consensus-mechanisms/pow/mining-algorithms/ethash/

Para criar uma rede privada que utilize o algoritmo de consenso clique será necessário que tenhamos duas contas pelo menos. Podemos aproveitar contas existentes que foram criadas no Código 6.II ou que podem ser recuperadas do diretório keystore de alguma prática anterior ou podemos criar duas contas com o comando:

[.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --datadir ~/.etherprivate-clique account new

Anote os ids das contas no momento da criação ou verifique quais contas estão disponíveis no diretório keystore:

[.etherprivate-clique]$ ls keystore/
UTC--2023-04-17T12-22-11.261468773Z--2db017e44b03b37755a4b15e14cd799f83de4c13
UTC--2024-09-17T17-57-24.818641852Z--bb36f26e6c16b3c7ed3d70bfb26f740336b4f976
UTC--2024-09-17T18-52-55.377570375Z--67a3a0eace0bb180b94948ae02b09b7f8948ca60

Iremos recriar o arquivo privategenesis.json com informações para o clique. Irei utilizar as contas 2db017e44b03b37755a4b15e14cd799f83de4c13 e bb36f26e6c16b3c7ed3d70bfb26f740336b4f976 na configuração de assinadores (signers) e serão contas que serão inicializadas com saldos. O Código 6.V apresenta o conteúdo atualizado.

Listing 6.V: Genesis File para Clique
{
  "config": {
    "chainId": 786,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0,
    "istanbulBlock": 0,
    "berlinBlock": 0,
    "clique": {
      "period": 5,
      "epoch": 30000
    }
  },
  "difficulty": "1",
  "gasLimit": "8000000",
  "extraData": "0x00000000000000000000000000000000000000000000000000000000000000002db017e44b03b37755a4b15e14cd799f83de4c13bb36f26e6c16b3c7ed3d70bfb26f740336b4f9760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "alloc": {
    "2db017e44b03b37755a4b15e14cd799f83de4c13": { "balance": "300000" },
    "bb36f26e6c16b3c7ed3d70bfb26f740336b4f976": { "balance": "400000" }
  }
}

No campo extraData temos que colocar os ids dos validadores/assinadores concatenados. Estou colocando os hashes das duas contas que criei primeiro. A codificação dos endereços dos signers no extradata é feita pela concatenação de \(32\) zero bytes (32 x 00), seguidos de todos os endereços dos assinadores (40 caracteres) e mais \(65\) zero bytes (65 x 00). Totalizando uma cadeia hexadecimal de 64 + 40 + 40 + … + 40 + 130. O resultado dessa concatenação é então usado como valor para o campo extradata no genesis file.

0x0000000000000000000000000000000000000000000000000000000000000000<hash conta 1><hash conta 2>0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Por exemplo, foram criadas as duas contas: 2db017e44b03b37755a4b15e14cd799f83de4c13 e bb36f26e6c16b3c7ed3d70bfb26f740336b4f976. A composição do valor do extradata será:

0x00000000000000000000000000000000000000000000000000000000000000002db017e44b03b37755a4b15e14cd799f83de4c13bb36f26e6c16b3c7ed3d70bfb26f740336b4f9760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Na prática, substitua no conteúdo do arquivo privategenesis.json, no campo extradata a cadeia 2db017e44b03b37755a4b15e14cd799f83de4c13bb36f26e6c16b3c7ed3d70bfb26f740336b4f976 pela cadeia formada pela concatenação dos hashes das contas que você quer como validadores.

No campo alloc coloque os hashes das contas e valores iniciais de saldo (balance) para cada conta.

Apague os dados da rede que iniciamos anteriormente, os dados estão no direório .etherprivate-clique/geth.

[.etherprivate-clique]$ rm geth -rf
[.etherprivate-clique]$ ls
keystore  privategenesis.json

Recrie a rede a partir do privategenesis.json alterado:

[.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --identity "RAGEtherPrivate" --datadir ~/.etherprivate-clique init ~/.etherprivate-clique/privategenesis.json
INFO [09-17|15:20:51.763] Maximum peer count                       ETH=50 LES=0 total=50
INFO [09-17|15:20:51.766] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [09-17|15:20:51.770] Set global gas cap                       cap=50,000,000
INFO [09-17|15:20:51.770] Initializing the KZG library             backend=gokzg
INFO [09-17|15:20:51.802] Defaulting to pebble as the backing database 
INFO [09-17|15:20:51.802] Allocated cache and file handles         database=/home/rag/.etherprivate-clique/geth/chaindata cache=16.00MiB handles=16
INFO [09-17|15:20:51.825] Opened ancient database                  database=/home/rag/.etherprivate-clique/geth/chaindata/ancient/chain readonly=false
INFO [09-17|15:20:51.825] Writing custom genesis block 
INFO [09-17|15:20:51.826] Persisted trie from memory database      nodes=3 size=399.00B time="708.278us" gcnodes=0 gcsize=0.00B gctime=0s livenodes=0 livesize=0.00B
INFO [09-17|15:20:51.834] Successfully wrote genesis state         database=chaindata hash=72f12c..ac1a0d
INFO [09-17|15:20:51.834] Defaulting to pebble as the backing database 
INFO [09-17|15:20:51.834] Allocated cache and file handles         database=/home/rag/.etherprivate-clique/geth/lightchaindata cache=16.00MiB handles=16
INFO [09-17|15:20:51.846] Opened ancient database                  database=/home/rag/.etherprivate-clique/geth/lightchaindata/ancient/chain readonly=false
INFO [09-17|15:20:51.846] Writing custom genesis block 
INFO [09-17|15:20:51.847] Persisted trie from memory database      nodes=3 size=399.00B time="780.216us" gcnodes=0 gcsize=0.00B gctime=0s livenodes=0 livesize=0.00B
INFO [09-17|15:20:51.856] Successfully wrote genesis state         database=lightchaindata hash=72f12c..ac1a0d
[.etherprivate-clique]$

6.4 Executando a nova Rede

O cliente geth pode ser iniciado, executando com base na nova rede criada, tenha certeza que está utilizando os dados do diretório .etherprivate-clique.

[.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --identity "RAGEtherPrivate" --datadir ~/.etherprivate-clique --syncmode full --allow-insecure-unlock --http --http.addr 127.0.0.1 --http.port 8559 --http.api "eth,net,web3,personal,engine,admin,debug" --keystore ~/.etherprivate-clique/keystore --authrpc.addr localhost --authrpc.port 8551 --authrpc.vhosts localhost --authrpc.jwtsecret ~/.etherprivate-clique/geth/jwtsecret --nodiscover --maxpeers 15
INFO [09-17|15:37:51.243] Maximum peer count                       ETH=15 LES=0 total=15
INFO [09-17|15:37:51.244] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [09-17|15:37:51.246] Set global gas cap                       cap=50,000,000
INFO [09-17|15:37:51.246] Initializing the KZG library             backend=gokzg
INFO [09-17|15:37:51.285] Allocated trie memory caches             clean=154.00MiB dirty=256.00MiB
INFO [09-17|15:37:51.286] Using pebble as the backing database 
INFO [09-17|15:37:51.286] Allocated cache and file handles         database=/home/rag/.etherprivate-clique/geth/chaindata cache=512.00MiB handles=262,144
INFO [09-17|15:37:51.300] Opened ancient database                  database=/home/rag/.etherprivate-clique/geth/chaindata/ancient/chain readonly=false
INFO [09-17|15:37:51.300] Initialising Ethereum protocol           network=786 dbversion=8
INFO [09-17|15:37:51.301]  
INFO [09-17|15:37:51.301] --------------------------------------------------------------------------------------------------------------------------------------------------------- 
INFO [09-17|15:37:51.301] Chain ID:  786 (unknown) 
INFO [09-17|15:37:51.301] Consensus: Clique (proof-of-authority) 
INFO [09-17|15:37:51.301]  
INFO [09-17|15:37:51.301] Pre-Merge hard forks (block based): 
INFO [09-17|15:37:51.301]  - Homestead:                   #0        (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet- upgrades/homestead.md) 
INFO [09-17|15:37:51.301]  - Tangerine Whistle (EIP 150): #0        (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet- upgrades/tangerine-whistle.md) 
INFO [09-17|15:37:51.301]  - Spurious Dragon/1 (EIP 155): #0        (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet- upgrades/spurious-dragon.md) 
INFO [09-17|15:37:51.301]  - Spurious Dragon/2 (EIP 158): #0        (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet- upgrades/spurious-dragon.md) 
INFO [09-17|15:37:51.301]  - Byzantium:                   #0        (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet- upgrades/byzantium.md) 
INFO [09-17|15:37:51.301]  - Constantinople:              #0        (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet- upgrades/constantinople.md) 
INFO [09-17|15:37:51.301]  - Petersburg:                  #0        (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet- upgrades/petersburg.md) 
INFO [09-17|15:37:51.301]  - Istanbul:                    #0        (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet- upgrades/istanbul.md) 
INFO [09-17|15:37:51.301]  - Berlin:                      #0        (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet- upgrades/berlin.md) 
INFO [09-17|15:37:51.301]  - London:                      #<nil> (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet- upgrades/london.md) 
INFO [09-17|15:37:51.301]  
INFO [09-17|15:37:51.301] The Merge is not yet available for this network! 
INFO [09-17|15:37:51.301]  - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet- upgrades/paris.md 
INFO [09-17|15:37:51.301]  
INFO [09-17|15:37:51.301] Post-Merge hard forks (timestamp based): 
INFO [09-17|15:37:51.301]  
INFO [09-17|15:37:51.301] --------------------------------------------------------------------------------------------------------------------------------------------------------- 
INFO [09-17|15:37:51.301]  
INFO [09-17|15:37:51.301] Loaded most recent local block           number=0 hash=72f12c..ac1a0d td=1 age=55y6mo3d
INFO [09-17|15:37:51.301] Loaded local transaction journal         transactions=0 dropped=0
INFO [09-17|15:37:51.301] Regenerated local transaction journal    transactions=0 accounts=0
INFO [09-17|15:37:51.309] Gasprice oracle is ignoring threshold set threshold=2
WARN [09-17|15:37:51.312] Engine API enabled                       protocol=eth
WARN [09-17|15:37:51.312] Engine API started but chain not configured for merge yet 
INFO [09-17|15:37:51.312] Starting peer-to-peer node               instance=Geth/RAGEtherPrivate/v1.12.2-stable-bed84606/linux-amd64/go1.21.1
INFO [09-17|15:37:51.321] IPC endpoint opened                      url=/home/rag/.etherprivate-clique/geth.ipc
INFO [09-17|15:37:51.321] New local node record                    seq=1,726,597,460,539 id=3f75d3400f44179e ip=127.0.0.1 udp=0 tcp=30303
INFO [09-17|15:37:51.321] Started P2P networking                   self="enode://781f3633c94cb09dd45b2db4b4ba5e44e568dc34e64c2edfc3eed9504909656cca90fe 85b8f11f5b1d5df0328bbe4b0243821fc0ef765801c13657131a860bd0@127.0.0.1:30303?discport=0"
INFO [09-17|15:37:51.321] Loaded JWT secret file                   path=/home/rag/.etherprivate-clique/geth/jwtsecret crc32=0x67433537
INFO [09-17|15:37:51.321] HTTP server started                      endpoint=127.0.0.1:8559 auth=false prefix= cors= vhosts=localhost
INFO [09-17|15:37:51.323] WebSocket enabled                        url=ws://127.0.0.1:8551
INFO [09-17|15:37:51.323] HTTP server started                      endpoint=127.0.0.1:8551 auth=true  prefix= cors=localhost vhosts=localhost
WARN [09-17|15:37:58.696] Served eth_coinbase                      reqid=3 duration="78.644us" err="etherbase must be explicitly specified"

No terminal onde o cliente de execução apareceu um novo warning: "WARN [09-17|15:37:58.696] Served eth_coinbase reqid=3 duration="78.644us" err="etherbase must be explicitly specified". Basta fornecer a conta principal no parâmetro etherbase=0x2db017e44b03b37755a4b15e14cd799f83de4c13.

[.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --identity "RAGEtherPrivate" --datadir ~/.etherprivate-clique --syncmode full --allow-insecure-unlock --http --http.addr 127.0.0.1 --http.port 8559 --http.api "eth,net,web3,personal,engine,admin,debug" --keystore ~/.etherprivate-clique/keystore --authrpc.addr localhost --authrpc.port 8551 --authrpc.vhosts localhost --authrpc.jwtsecret ~/.etherprivate-clique/geth/jwtsecret --nodiscover --maxpeers 15 --miner.etherbase=0x2db017e44b03b37755a4b15e14cd799f83de4c13

6.5 Interagindo com a Nova Rede

O console pode ser utilizado na interação com a instância da nova rede em execução.

[.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth attach ~/.etherprivate-clique/geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/RAGEtherPrivate/v1.12.2-stable-bed84606/linux-amd64/go1.21.1
at block: 0 (Wed Dec 31 1969 21:00:00 GMT-0300 (-03))
 datadir: /home/rag/.etherprivate-clique
 modules: admin:1.0 clique:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0

To exit, press ctrl-d or type exit
> eth.accounts
["0x2db017e44b03b37755a4b15e14cd799f83de4c13", "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976"]
> eth.getBalance("0x2db017e44b03b37755a4b15e14cd799f83de4c13")
300000
> eth.getBalance("0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976")
400000
> 

6.6 Verificando quem são os Signers

Configuramos as duas contas como signers, para conferir se deu tudo certo na configuração, em um console JavaScript, utilize o a função clique.getSigners() que listará as contas configuradas como assinadores.

 [rogerio@ryzen-nitro .etherprivate-clique]$ ~/go-ethereum-1.12.2/build/bin/geth attach /home/rag/.etherprivate-clique/geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/RAGEtherPrivate/v1.12.2-stable-bed84606/linux-amd64/go1.21.1
coinbase: 0x2db017e44b03b37755a4b15e14cd799f83de4c13
at block: 0 (Wed Dec 31 1969 21:00:00 GMT-0300 (-03))
 datadir: /home/rag/.etherprivate-clique
 modules: admin:1.0 clique:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0

To exit, press ctrl-d or type exit
> clique.getSigners()
["0x2db017e44b03b37755a4b15e14cd799f83de4c13", "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976"]
> 

6.7 Criando contas na Nova Rede

O objetivo é termos pelo menos duas contas para testes na nova rede. Caso já não tenha duas contas de práticas anteriores é recomendado utilizar o clef com o parâmetro newaccount. É importante indicar o diretório keystore do .etherprivate-clique. Utilizaremos para fins de teste a senha “admin12345”.

Se seguimos a opção de criar uma conta antes para configurar o genesis file nossa base já terá uma conta. Essa conta pode ser verificada utilizando o $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --datadir ~/.etherprivate-clique/ account list ou o comando do clef.

[.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --datadir ~/.etherprivate-clique/ account list
INFO [09-17|15:49:53.739] Maximum peer count                       ETH=50 LES=0 total=50
INFO [09-17|15:49:53.740] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
Account #0: {2db017e44b03b37755a4b15e14cd799f83de4c13} keystore:///home/rag/.etherprivate-clique/keystore/UTC--2023-04-17T12-22-11.261468 773Z--2db017e44b03b37755a4b15e14cd799f83de4c13
Account #1: {bb36f26e6c16b3c7ed3d70bfb26f740336b4f976} keystore:///home/rag/.etherprivate-clique/keystore/UTC--2024-09-17T17-57-24.818641 852Z--bb36f26e6c16b3c7ed3d70bfb26f740336b4f976
[.etherprivate-clique]$

Como o clef:

$ [.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/clef list-accounts --keystore ~/.etherprivate-clique/keystore

WARNING!

Clef is an account management tool. It may, like any software, contain bugs.

Please take care to
- backup your keystore files,
- verify that the keystore(s) can be opened with your password.

Clef is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.

Enter 'ok' to proceed:
> ok

0x2db017E44b03B37755A4b15e14Cd799f83DE4c13 (keystore:///home/rag/.etherprivate-clique/keystore/UTC--2023-04-17T12-22-11. 261468773Z--2db017e44b03b37755a4b15e14cd799f83de4c13)
0xBb36F26E6C16B3C7ED3D70bFB26F740336B4F976 (keystore:///home/rag/.etherprivate-clique/keystore/UTC--2024-09-17T17-57-24. 818641852Z--bb36f26e6c16b3c7ed3d70bfb26f740336b4f976)
[.etherprivate-clique]$

A conta 0x2db017E44b03B37755A4b15e14Cd799f83DE4c13 que foi gerada anteriormente, utilizei a senha admin12345. Vamos criar mais uma conta com o comando:

[.etherprivate-clique]$ /home/rag/go-ethereum-1.12.2/build/bin/clef --keystore ~/.etherprivate-clique/keystore newaccount

WARNING!

Clef is an account management tool. It may, like any software, contain bugs.

Please take care to
- backup your keystore files,
- verify that the keystore(s) can be opened with your password.

Clef is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.

Enter 'ok' to proceed:
> ok

\#\# New account password

Please enter a password for the new account to be created (attempt 0 of 3)
> 
-----------------------
INFO [09-17|15:52:56.566] Your new key was generated               address=0x67a3A0EACe0bB180B94948ae02b09b7F8948ca60
WARN [09-17|15:52:56.567] Please backup your key file!             path=/home/rag/.etherprivate-clique/keystore/UTC--2024-09-17T18-52-55 .377570375Z--67a3a0eace0bb180b94948ae02b09b7f8948ca60
WARN [09-17|15:52:56.567] Please remember your password! 
Generated account 0x67a3A0EACe0bB180B94948ae02b09b7F8948ca60
[.etherprivate-clique]$

A conta 0x67a3A0EACe0bB180B94948ae02b09b7F8948ca60 foi criada. No meu caso, listando pelo clef tenho as contas:

[.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --datadir ~/.etherprivate-clique/ account list
INFO [09-17|15:56:07.023] Maximum peer count                       ETH=50 LES=0 total=50
INFO [09-17|15:56:07.024] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
Account #0: {2db017e44b03b37755a4b15e14cd799f83de4c13} keystore:///home/rag/.etherprivate-clique/keystore/UTC--2023-04-17T12-22-11. 261468773Z--2db017e44b03b37755a4b15e14cd799f83de4c13
Account #1: {bb36f26e6c16b3c7ed3d70bfb26f740336b4f976} keystore:///home/rag/.etherprivate-clique/keystore/UTC--2024-09-17T17-57-24. 818641852Z--bb36f26e6c16b3c7ed3d70bfb26f740336b4f976
Account #2: {67a3a0eace0bb180b94948ae02b09b7f8948ca60} keystore:///home/rag/.etherprivate-clique/keystore/UTC--2024-09-17T18-52-55. 377570375Z--67a3a0eace0bb180b94948ae02b09b7f8948ca60
[.etherprivate-clique]$ 

Para os testes utilizarei as duas contas 0x2db017E44b03B37755A4b15e14Cd799f83DE4c13 e 0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976, ambas com a senha admin12345.

Verifiquemos no console JavaScript se elas são listadas:

[.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth attach ~/.etherprivate-clique/geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/RAGEtherPrivate/v1.12.2-stable-bed84606/linux-amd64/go1.21.1
coinbase: 0x2db017e44b03b37755a4b15e14cd799f83de4c13
at block: 0 (Wed Dec 31 1969 21:00:00 GMT-0300 (-03))
 datadir: /home/rag/.etherprivate-clique
 modules: admin:1.0 clique:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0

To exit, press ctrl-d or type exit
> eth.accounts
["0x2db017e44b03b37755a4b15e14cd799f83de4c13", "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976", "0x67a3a0eace0bb180b94948ae02b09b7f8948ca60"]
> 

6.8 Informações do Nó

Para obter informações do nó criado com a execução do geth, basta usar o atributo admin.nodeInfo no console JavaScript.

[.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth attach ~/.etherprivate-clique/geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/RAGEtherPrivate/v1.12.2-stable-bed84606/linux-amd64/go1.21.1
coinbase: 0x2db017e44b03b37755a4b15e14cd799f83de4c13
at block: 0 (Wed Dec 31 1969 21:00:00 GMT-0300 (-03))
 datadir: /home/rag/.etherprivate-clique
 modules: admin:1.0 clique:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0

To exit, press ctrl-d or type exit
> admin.nodeInfo
{
  enode: "enode://91156ab43ada3646a9822152d4b010279cec9a92b5ab2d10b9ac53525f67f2f63f6d997da2967cc7d3732466449a6c667842b85649f61a8035e7305889231347@127.0.0.1:30303?discport=0",
  enr: "enr:-Jy4QLIsAUUHel4lfANVQzPA9XglJ3RDOWxxJI3Kro4_VwtpBqSmlscUPmVmgrLBYlEfFjHMEWNXVv40uKg0N7RK02aGAZIBa1M4g2V0aMfGhLr9cZ2AgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQORFWq0Oto2RqmCIVLUsBAnnOyakrWrLRC5rFNSX2fy9oRzbmFwwIN0Y3CCdl8",
  id: "87c2a44bb5d9ffe7b756c4821067b3eba5c260a1edce91cd59ea8c6925d874e2",
  ip: "127.0.0.1",
  listenAddr: "[::]:30303",
  name: "Geth/RAGEtherPrivate/v1.12.2-stable-bed84606/linux-amd64/go1.21.1",
  ports: {
    discovery: 0,
    listener: 30303
  },
  protocols: {
    eth: {
      config: {
        berlinBlock: 0,
        byzantiumBlock: 0,
        chainId: 786,
        clique: {...},
        constantinopleBlock: 0,
        eip150Block: 0,
        eip155Block: 0,
        eip158Block: 0,
        homesteadBlock: 0,
        istanbulBlock: 0,
        petersburgBlock: 0
      },
      difficulty: 1,
      genesis: "0xbf9a39b82450012680f16cac3affb16326902ed947099baf2aba3f62f0af3926",
      head: "0xbf9a39b82450012680f16cac3affb16326902ed947099baf2aba3f62f0af3926",
      network: 786
    },
    snap: {}
  }
}
>

6.9 Verificando o Saldo das Contas

Vamos verificar os valores em cada uma das contas:

[.etherprivate-clique]$ ~/go-ethereum-1.12.2/build/bin/geth attach ~/.etherprivate-clique/geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/RAGEtherPrivate/v1.12.2-stable-bed84606/linux-amd64/go1.21.1
coinbase: 0x2db017e44b03b37755a4b15e14cd799f83de4c13
at block: 0 (Wed Dec 31 1969 21:00:00 GMT-0300 (-03))
 datadir: /home/rag/.etherprivate-clique
 modules: admin:1.0 clique:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0

To exit, press ctrl-d or type exit
> eth.accounts
["0x2db017e44b03b37755a4b15e14cd799f83de4c13", "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976", "0x67a3a0eace0bb180b94948ae02b09b7f8948ca60"]
> web3.fromWei(eth.getBalance("0x2db017e44b03b37755a4b15e14cd799f83de4c13"), "ether")
3e-13
> web3.fromWei(eth.getBalance("0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976"), "ether")
4e-13
> 

Se criamos a primeira conta antes da configuração do genesis file, alocamos para ela \(300000\) então a consulta de valores iniciais poderá ter resultado diferente dependendo de como criou as contas.

eth.accounts
["0x2db017e44b03b37755a4b15e14cd799f83de4c13", "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976", "0x67a3a0eace0bb180b94948ae02b09b7f8948ca60"]
> web3.fromWei(eth.getBalance("0x2db017e44b03b37755a4b15e14cd799f83de4c13"), "ether")
3e-13
> web3.fromWei(eth.getBalance("0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976"), "ether")
4e-13
> eth.getBalance(eth.accounts[0])
300000
> eth.getBalance(eth.accounts[1])
400000
> 

6.10 Transferências entre as Carteiras

Vamos enviar \(100\) ethers de uma carteira para outra. Se utilizarmos uma conta que não tem saldo suficiente, seremos avisados.

> eth.accounts
["0x2db017e44b03b37755a4b15e14cd799f83de4c13", "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976", "0x67a3a0eace0bb180b94948ae02b09b7f8948ca60"]
> eth.estimateGas({from: "0x2db017e44b03b37755a4b15e14cd799f83de4c13", to: "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f970", value: 100})
21000
> eth.estimateGas({from: "0x2db017e44b03b37755a4b15e14cd799f83de4c13", to: "0x67a3a0eace0bb180b94948ae02b09b7f8948ca60", value: 100})
21000
> eth.sendTransaction({from: "0x67a3a0eace0bb180b94948ae02b09b7f8948ca60", to: "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976", value: 100})
Error: insufficient funds for transfer
        at web3.js:6365:9(39)
        at send (web3.js:5099:62(29))
        at <eval>:1:20(9)
> 

Fazendo uma transferência de uma conta com saldo. Se o erro Error: gas required exceeds allowance (0) ocorrer:

> eth.sendTransaction({from: "0x2db017e44b03b37755a4b15e14cd799f83de4c13", to: "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976", value: 100})
Error: gas required exceeds allowance (0)
        at web3.js:6365:9(39)
        at send (web3.js:5099:62(29))
        at <eval>:1:20(9)

> 

No terminal de execução do geth irá aparecer a mensagem de erro:

WARN [09-17|16:39:16.283] Gas estimation capped by limited funds   original=8,007,811 balance=300,000 sent=100 maxFeePerGas=1,000,000,000 fundable=0
WARN [09-17|16:39:16.283] Served eth_sendTransaction               reqid=10 duration="297.6us"   err="gas required exceeds allowance (0)"

Utilize o parâmetro --miner.gasprice para alterar o gasprice para \(1\).

[.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --identity "RAGEtherPrivate" --datadir ~/.etherprivate-clique --syncmode full --allow-insecure-unlock --http --http.addr 127.0.0.1 --http.port 8559 --http.api "eth,net,web3,personal,engine,admin,debug" --keystore ~/.etherprivate-clique/keystore --authrpc.addr localhost --authrpc.port 8551 --authrpc.vhosts localhost --authrpc.jwtsecret ~/.etherprivate-clique/geth/jwtsecret --nodiscover --maxpeers 15 --miner.etherbase=0x2db017e44b03b37755a4b15e14cd799f83de4c13 --miner.gasprice "1"

O erro Error: authentication needed: password or unlock ocorre porque é necessário autenticação para a realização de transações, precisamos autorizar a transação.

> eth.sendTransaction({from: "0x2db017e44b03b37755a4b15e14cd799f83de4c13", to: "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976", value: 100})
"0xfeb0a7dd835eceb30b14b4f3e5bd8cc906d3aa33af5dbec5b941deaa8f91971b"
> eth.sendTransaction({from: "0x2db017e44b03b37755a4b15e14cd799f83de4c13", to: "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976", value: 100})
Error: authentication needed: password or unlock
        at web3.js:6365:9(39)
        at send (web3.js:5099:62(29))
        at <eval>:1:20(9)

> 

No terminal de execução do geth irá aparecer o aviso.

WARN [09-17|18:58:31.625] Served eth_sendTransaction               reqid=33 duration="754.024us" err="authentication needed: password or unlock"

Na versão utilizada é preciso utilizar o clef para fazer a autenticação em um terminal. Inicie a instância do clef com o comando:

[.etherprivate]$ /home/rag/go-ethereum-1.12.2/build/bin/clef --chainid 786 --keystore ~/.etherprivate-clique/keystore --configdir ~/.etherprivate-clique/clef --http

WARNING!

Clef is an account management tool. It may, like any software, contain bugs.

Please take care to
- backup your keystore files,
- verify that the keystore(s) can be opened with your password.

Clef is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.

Enter 'ok' to proceed:
> ok

INFO [04-17|10:23:09.630] Using CLI as UI-channel 
INFO [04-17|10:23:10.050] Loaded 4byte database                    embeds=268,621 locals=0 local=./4byte-custom.json
WARN [04-17|10:23:10.050] Failed to open master, rules disabled    err="failed stat on /home/rag/.etherprivate-clique/clef/masterseed.json: stat /home/rag/.etherprivate-clique/clef/masterseed.json: no such file or directory"
INFO [04-17|10:23:10.050] Starting signer                          chainid=786 keystore=/home/rag/.etherprivate-clique/keystore light-kdf=false advanced=false
INFO [04-17|10:23:10.052] Smartcard socket file missing, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [04-17|10:23:10.052] Audit logs configured                    file=audit.log
INFO [04-17|10:23:10.053] HTTP endpoint opened                     url=http://127.0.0.1:8550/
INFO [04-17|10:23:10.053] IPC endpoint opened                      url=/home/rag/.etherprivate-clique/clef/clef.ipc

------- Signer info -------
* extapi_version : 6.1.0
* extapi_http : http://127.0.0.1:8550/
* extapi_ipc : /home/rag/.etherprivate-clique/clef/clef.ipc
* intapi_version : 7.0.1

------- Available accounts -------
0. 0x2db017E44b03B37755A4b15e14Cd799f83DE4c13 at keystore:///home/rag/.etherprivate-clique/keystore/UTC--2023-04-17T12-22-11.261468773Z--2db017e44b03b37755a4b15e14cd799f83de4c13
1. 0x7A7686aD451d2865A2246E239B674aeFd4c6c27c at keystore:///home/rag/.etherprivate-clique/keystore/UTC--2023-04-17T12-28-54.934614755Z--7a7686ad451d2865a2246e239b674aefd4c6c27c
-------- List Account request--------------
A request has been made to list all accounts. 
You can select which accounts the caller can see
  [x] 0x2db017E44b03B37755A4b15e14Cd799f83DE4c13
    URL: keystore:///home/rag/.etherprivate-clique/keystore/UTC--2023-04-17T12-22-11.261468773Z--2db017e44b03b37755a4b15e14cd799f83de4c13
  [x] 0x7A7686aD451d2865A2246E239B674aeFd4c6c27c
    URL: keystore:///home/rag/.etherprivate-clique/keystore/UTC--2023-04-17T12-28-54.934614755Z--7a7686ad451d2865a2246e239b674aefd4c6c27c
-------------------------------------------

E volte ao terminal de execução do geth e indique que as autentificações serão via clef com o parâmetro --signer=/home/rag/.etherprivate-clique/clef/clef.ipc passando o caminho dado pelo clef.

[.etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --identity "RAGEtherPrivate" --datadir ~/.etherprivate-clique --syncmode full --allow-insecure-unlock --http --http.addr 127.0.0.1 --http.port 8559 --http.api "eth,net,web3,personal,engine,admin,debug" --keystore ~/.etherprivate-clique/keystore --authrpc.addr localhost --authrpc.port 8551 --authrpc.vhosts localhost --authrpc.jwtsecret ~/.etherprivate-clique/geth/jwtsecret --nodiscover --maxpeers 15 --miner.etherbase=0x2db017e44b03b37755a4b15e14cd799f83de4c13 --miner.gasprice "1" --signer=/home/rag/.etherprivate-clique/clef/clef.ipc

Cada transação executada no console JavaScript deverá ser autorizada no console do clef.

> eth.accounts

["0x2db017e44b03b37755a4b15e14cd799f83de4c13", "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976", "0x67a3a0eace0bb180b94948ae02b09b7f8948ca60"]
> clique.getSigners()

["0x2db017e44b03b37755a4b15e14cd799f83de4c13", "0xb9083d7e2371944fe035ce99af680d89e2c4d73a", "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976", "0xca01dbfc1bd2fd94dc421209441a754f79c4a4ec"]
> eth.getBalance("0x67a3a0eace0bb180b94948ae02b09b7f8948ca60")
0
> eth.getBalance("0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976")
400000
> eth.getBalance("0x2db017e44b03b37755a4b15e14cd799f83de4c13")
300000
> eth.sendTransaction({from: "0x2db017e44b03b37755a4b15e14cd799f83de4c13", to: "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976", value: 100})
"0xf9dba156ca7aec18836ff354263b4032209250009c323e29406334a13f34a21f"

No console do clef é possível autorizar e ver a transação assinada com hash: 0xb579cc595601e4aca546ce4e46bdcded7841bd7f50a0a78c505e839dd039b8b9 que é o mesmo id devolvido no console JavaScript.

[.etherprivate-clique]$ /home/rag/go-ethereum-1.12.2/build/bin/clef --chainid 786 --keystore ~/.etherprivate-clique/keystore --configdir ~/.etherprivate-clique/clef --http

WARNING!

Clef is an account management tool. It may, like any software, contain bugs.

Please take care to
- backup your keystore files,
- verify that the keystore(s) can be opened with your password.

Clef is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.

Enter 'ok' to proceed:
> ok

INFO [09-17|21:21:54.581] Using CLI as UI-channel 
INFO [09-17|21:21:54.927] Loaded 4byte database                    embeds=268,621 locals=0 local=./4byte-custom.json
WARN [09-17|21:21:54.927] Failed to open master, rules disabled    err="failed stat on /home/rag/.etherprivate-clique/clef/masterseed.json: stat /home/rag/.etherprivate-clique/clef/masterseed.json: no such file or directory"
INFO [09-17|21:21:54.927] Starting signer                          chainid=786 keystore=/home/rag/.etherprivate-clique/keystore light-kdf=false advanced=false
INFO [09-17|21:21:54.930] Smartcard socket file missing, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [09-17|21:21:54.930] Audit logs configured                    file=audit.log
INFO [09-17|21:21:54.931] HTTP endpoint opened                     url=http://127.0.0.1:8550/
INFO [09-17|21:21:54.932] IPC endpoint opened                      url=/home/rag/.etherprivate-clique/clef/clef.ipc

------- Signer info -------
* intapi_version : 7.0.1
* extapi_version : 6.1.0
* extapi_http : http://127.0.0.1:8550/
* extapi_ipc : /home/rag/.etherprivate-clique/clef/clef.ipc

------- Available accounts -------
0. 0x2db017E44b03B37755A4b15e14Cd799f83DE4c13 at keystore:///home/rag/.etherprivate-clique/keystore/UTC--2023-04-17T12-22-11.261468773Z--2db017e44b03b37755a4b15e14cd799f83de4c13
1. 0xBb36F26E6C16B3C7ED3D70bFB26F740336B4F976 at keystore:///home/rag/.etherprivate-clique/keystore/UTC--2024-09-17T17-57-24.818641852Z--bb36f26e6c16b3c7ed3d70bfb26f740336b4f976
2. 0x67a3A0EACe0bB180B94948ae02b09b7F8948ca60 at keystore:///home/rag/.etherprivate-clique/keystore/UTC--2024-09-17T18-52-55.377570375Z--67a3a0eace0bb180b94948ae02b09b7f8948ca60
-------- List Account request--------------
A request has been made to list all accounts. 
You can select which accounts the caller can see
  [x] 0x2db017E44b03B37755A4b15e14Cd799f83DE4c13
    URL: keystore:///home/rag/.etherprivate-clique/keystore/UTC--2023-04-17T12-22-11.261468773Z--2db017e44b03b37755a4b15e14cd799f83de4c13
  [x] 0xBb36F26E6C16B3C7ED3D70bFB26F740336B4F976
    URL: keystore:///home/rag/.etherprivate-clique/keystore/UTC--2024-09-17T17-57-24.818641852Z--bb36f26e6c16b3c7ed3d70bfb26f740336b4f976
  [x] 0x67a3A0EACe0bB180B94948ae02b09b7F8948ca60
    URL: keystore:///home/rag/.etherprivate-clique/keystore/UTC--2024-09-17T18-52-55.377570375Z--67a3a0eace0bb180b94948ae02b09b7f8948ca60
-------------------------------------------
Request context:
        NA -> ipc -> NA

Additional HTTP header data, provided by the external caller:
        User-Agent: ""
        Origin: ""
Approve? [y/N]:
> y
--------- Transaction request-------------
to:    0xBb36F26E6C16B3C7ED3D70bFB26F740336B4F976
from:               0x2db017E44b03B37755A4b15e14Cd799f83DE4c13 [chksum ok]
value:              100 wei
gas:                0x5208 (21000)
gasprice: 1 wei
nonce:    0x0 (0)
chainid:  0x312

Request context:
        NA -> ipc -> NA

Additional HTTP header data, provided by the external caller:
        User-Agent: ""
        Origin: ""
-------------------------------------------
Approve? [y/N]:
> y
\#\# Account password

Please enter the password for account 0x2db017E44b03B37755A4b15e14Cd799f83DE4c13
> 
-----------------------
Transaction signed:
 {
    "type": "0x0",
    "chainId": "0x312",
    "nonce": "0x0",
    "to": "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976",
    "gas": "0x5208",
    "gasPrice": "0x1",
    "maxPriorityFeePerGas": null,
    "maxFeePerGas": null,
    "value": "0x64",
    "input": "0x",
    "v": "0x647",
    "r": "0x88b5dcb76a2b3afb4cf16f2a0d67320e8cf3f6711d4001812357e7dde86a5d21",
    "s": "0x12b5cb7118d7b2f777035d4de0c2ccf8facdca5a1dab46bc8e8f8eb28614a95",
    "hash": "0xf9dba156ca7aec18836ff354263b4032209250009c323e29406334a13f34a21f"
  }
-------- Sign data request--------------
Account:  0x2db017E44b03B37755A4b15e14Cd799f83DE4c13 [chksum ok]
messages:
  Clique header [clique]: "clique header 1 [0xb3e3cd9869adf0c80864715bbc84d13e7bcc394d8e8c68342b5fb498e3415882]"
raw data:  
        "\xf9\x02\x16\xa0\xf5\x9eV\x96\xa1*r_\xa5\x00\xf7\xf8\xb1\xef\xbb\xe8l\xd9\x05G\x17z\x91\x11m\xd0**\xa3\xccM\xe8\xde\xc7]z\xab\x85\xb5g\xb6\xcc\xd4\x1a\xd3\x12E\x1b\x94\x8at\x13\xf0\xa1B\xfdG\x94\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0B\xb1y\\U:r\x850|\x8bx\xf3M\xb9]e\x18\xa4\x9b\xdfQ\xe4\xc1\x87\x9d\x01\xa1{\xa0\xdfF\xc7\xf3\xc5B\xbc\xb2h7r\n\xae\xb1\xd9\xe9&Z\x04\xe8\xe8#6!\xb6^U\xb0\x97\xe2\a\xa0\xa0\x05k#\xfb\xbaH\x06\x96\xb6_\x8f!H\xa1)\x91\x03\xc4\xf5}\xf89#:\xf2\xcfL\xa2\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x83z0\x83\x82R\b\x84f\xea\x1dk\xa0\u0603\x01\f\x02\x84geth\x88go1.21.1\x85linux\x00\x00\x00\x00\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\x00\x00\x00\x00\x00\x00\x00\x00"
data hash:  0x95c84367fee5668f5b6571712467e56e8bace022ec24ba761cb7e62d51164581
-------------------------------------------
Request context:
        NA -> ipc -> NA

Additional HTTP header data, provided by the external caller:
        User-Agent: ""
        Origin: ""
Approve? [y/N]:
> y
\#\# Password for signing

Please enter password for signing data with account 0x2db017E44b03B37755A4b15e14Cd799f83DE4c13
> 
-----------------------

No terminal de execução do geth vai aparecer que a transação 0xf9dba156ca7aec18836ff354263b4032209250009c323e29406334a13f34a21f foi submetida:

WARN [09-17|21:22:43.166] Gas estimation capped by limited funds   original=8,007,811 balance=300,000 sent=100 maxFeePerGas=1 fundable=299,900
INFO [09-17|21:22:50.751] Setting new local account                address=0x2db017E44b03B37755A4b15e14Cd799f83DE4c13
INFO [09-17|21:22:50.752] Submitted transaction                    hash=0xf9dba156ca7aec18836ff354263b4032209250009c323e29406334a13f34a21f from=0x2db017E44b03B37755A4b15e14Cd799f83DE4c13 nonce=0 recipient=0xBb36F26E6C16B3C7ED3D70bFB26F740336B4F976 value=100
INFO [09-17|21:23:07.055] Legacy pool tip threshold updated        tip=1
INFO [09-17|21:23:07.056] Commit new sealing work                  number=1 sealhash=95c843..164581 txs=1 gas=21000 fees=2.1e-14 elapsed="508.177us"
INFO [09-17|21:23:13.936] Successfully sealed new block            number=1 sealhash=95c843..164581 hash=8c6143..92674c elapsed=6.879s
INFO [09-17|21:23:13.936] Commit new sealing work                  number=2 sealhash=feb862..1ac97a txs=0 gas=0     fees=0       elapsed="699.477us"
WARN [09-17|21:23:13.936] Block sealing failed                     err="signed recently, must wait for others"

No console JavaScript é possível recuperar o recibo da transação:

> eth.sendTransaction({from: "0x2db017e44b03b37755a4b15e14cd799f83de4c13", to: "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976", value: 100})
"0xf9dba156ca7aec18836ff354263b4032209250009c323e29406334a13f34a21f"
> eth.getTransactionReceipt("0xf9dba156ca7aec18836ff354263b4032209250009c323e29406334a13f34a21f")
null

O recibo ainda é null porque a transação não foi processada. É preciso minerar para a transação ser efetivada:

> miner.start()
null
> miner.stop()
> eth.getTransactionReceipt("0xf9dba156ca7aec18836ff354263b4032209250009c323e29406334a13f34a21f")
{
  blockHash: "0x8c6143968850c76ac5fd6bdbd1e24edffb5b1aaeb01430c94a5753f12692674c",
  blockNumber: 1,
  contractAddress: null,
  cumulativeGasUsed: 21000,
  effectiveGasPrice: 1,
  from: "0x2db017e44b03b37755a4b15e14cd799f83de4c13",
  gasUsed: 21000,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  status: "0x1",
  to: "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976",
  transactionHash: "0xf9dba156ca7aec18836ff354263b4032209250009c323e29406334a13f34a21f",
  transactionIndex: 0,
  type: "0x0"
}

O saldo das contas também foi alterado conforme a transferência executada:

> eth.getBalance("0x2db017e44b03b37755a4b15e14cd799f83de4c13")
299900
> eth.getBalance("0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976")
400100
> eth.getBalance("0x67a3a0eace0bb180b94948ae02b09b7f8948ca60")
0
> 

Ao enviar outra quantidade para a segunda conta é preciso autorizar a transação no console do clef e minerar novamente para ela ser efetivada.

> eth.sendTransaction({from: "0x2db017e44b03b37755a4b15e14cd799f83de4c13", to: "0x67a3A0EACe0bB180B94948ae02b09b7F8948ca60", value: 100})
"0x4d60fdb557de763b557ed6f487d882caa3d639af02c9ef04e88afb8cc3ed7969"
> eth.getTransactionReceipt("0x4d60fdb557de763b557ed6f487d882caa3d639af02c9ef04e88afb8cc3ed7969")
null
> miner.start()
null
> eth.getTransactionReceipt("0x4d60fdb557de763b557ed6f487d882caa3d639af02c9ef04e88afb8cc3ed7969")
{
  blockHash: "0x31eba241518f12f89fec5958c58ae38cd7ec2c5c85b5f6f59755cd9b0e210fbf",
  blockNumber: 1,
  contractAddress: null,
  cumulativeGasUsed: 21000,
  effectiveGasPrice: 1,
  from: "0x2db017e44b03b37755a4b15e14cd799f83de4c13",
  gasUsed: 21000,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  status: "0x1",
  to: "0x67a3a0eace0bb180b94948ae02b09b7f8948ca60",
  transactionHash: "0x4d60fdb557de763b557ed6f487d882caa3d639af02c9ef04e88afb8cc3ed7969",
  transactionIndex: 0,
  type: "0x0"
}
> miner.stop()

Console do clef para a segunda transação:

[rogerio@ryzen-nitro .etherprivate-clique]$ /home/rag/go-ethereum-1.12.2/build/bin/clef --chainid 786 --keystore ~/.etherprivate-clique/keystore --configdir ~/.etherprivate-clique/clef --http

WARNING!

Clef is an account management tool. It may, like any software, contain bugs.

Please take care to
- backup your keystore files,
- verify that the keystore(s) can be opened with your password.

Clef is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.

Enter 'ok' to proceed:
> ok

INFO [09-18|20:37:10.231] Using CLI as UI-channel 
INFO [09-18|20:37:10.545] Loaded 4byte database                    embeds=268,621 locals=0 local=./4byte-custom.json
WARN [09-18|20:37:10.545] Failed to open master, rules disabled    err="failed stat on /home/rag/.etherprivate-clique/clef/masterseed.json: stat /home/rag/.etherprivate-clique/clef/masterseed.json: no such file or directory"
INFO [09-18|20:37:10.545] Starting signer                          chainid=786 keystore=/home/rag/.etherprivate-clique/keystore light-kdf=false advanced=false
INFO [09-18|20:37:10.547] Smartcard socket file missing, disabling err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [09-18|20:37:10.548] Audit logs configured                    file=audit.log
INFO [09-18|20:37:10.549] HTTP endpoint opened                     url=http://127.0.0.1:8550/
INFO [09-18|20:37:10.549] IPC endpoint opened                      url=/home/rag/.etherprivate-clique/clef/clef.ipc

------- Signer info -------
* extapi_ipc : /home/rag/.etherprivate-clique/clef/clef.ipc
* intapi_version : 7.0.1
* extapi_version : 6.1.0
* extapi_http : http://127.0.0.1:8550/

------- Available accounts -------
0. 0x2db017E44b03B37755A4b15e14Cd799f83DE4c13 at keystore:///home/rag/.etherprivate-clique/keystore/UTC--2023-04-17T12-22-11.261468773Z--2db017e44b03b37755a4b15e14cd799f83de4c13
1. 0xBb36F26E6C16B3C7ED3D70bFB26F740336B4F976 at keystore:///home/rag/.etherprivate-clique/keystore/UTC--2024-09-17T17-57-24.818641852Z--bb36f26e6c16b3c7ed3d70bfb26f740336b4f976
2. 0x67a3A0EACe0bB180B94948ae02b09b7F8948ca60 at keystore:///home/rag/.etherprivate-clique/keystore/UTC--2024-09-17T18-52-55.377570375Z--67a3a0eace0bb180b94948ae02b09b7f8948ca60
-------- List Account request--------------
A request has been made to list all accounts. 
You can select which accounts the caller can see
  [x] 0x2db017E44b03B37755A4b15e14Cd799f83DE4c13
    URL: keystore:///home/rag/.etherprivate-clique/keystore/UTC--2023-04-17T12-22-11.261468773Z--2db017e44b03b37755a4b15e14cd799f83de4c13
  [x] 0xBb36F26E6C16B3C7ED3D70bFB26F740336B4F976
    URL: keystore:///home/rag/.etherprivate-clique/keystore/UTC--2024-09-17T17-57-24.818641852Z--bb36f26e6c16b3c7ed3d70bfb26f740336b4f976
  [x] 0x67a3A0EACe0bB180B94948ae02b09b7F8948ca60
    URL: keystore:///home/rag/.etherprivate-clique/keystore/UTC--2024-09-17T18-52-55.377570375Z--67a3a0eace0bb180b94948ae02b09b7f8948ca60
-------------------------------------------
Request context:
        NA -> ipc -> NA

Additional HTTP header data, provided by the external caller:
        User-Agent: ""
        Origin: ""
Approve? [y/N]:
> y
--------- Transaction request-------------
to:    0x67a3A0EACe0bB180B94948ae02b09b7F8948ca60
from:               0x2db017E44b03B37755A4b15e14Cd799f83DE4c13 [chksum ok]
value:              100 wei
gas:                0x5208 (21000)
gasprice: 1 wei
nonce:    0x0 (0)
chainid:  0x312

Request context:
        NA -> ipc -> NA

Additional HTTP header data, provided by the external caller:
        User-Agent: ""
        Origin: ""
-------------------------------------------
Approve? [y/N]:
> y
\#\# Account password

Please enter the password for account 0x2db017E44b03B37755A4b15e14Cd799f83DE4c13
> 
-----------------------
Transaction signed:
 {
    "type": "0x0",
    "chainId": "0x312",
    "nonce": "0x0",
    "to": "0x67a3a0eace0bb180b94948ae02b09b7f8948ca60",
    "gas": "0x5208",
    "gasPrice": "0x1",
    "maxPriorityFeePerGas": null,
    "maxFeePerGas": null,
    "value": "0x64",
    "input": "0x",
    "v": "0x647",
    "r": "0x4138a9d11ae034aef924a2a38402242c801c2a69e272eeae45aa75ddf674c833",
    "s": "0x5d8e6bca5bb1312561531be5a45c5e020d541c3aa5dea6ff94dfea2b8cc49982",
    "hash": "0x4d60fdb557de763b557ed6f487d882caa3d639af02c9ef04e88afb8cc3ed7969"
  }
-------- Sign data request--------------
Account:  0x2db017E44b03B37755A4b15e14Cd799f83DE4c13 [chksum ok]
messages:
  Clique header [clique]: "clique header 1 [0x550a6aed64dfa48a1523d995874eff7817f6e879d3c1c6ccb11f503245ce316e]"
raw data:  
        "\xf9\x02\x16\xa0?2N\x14\n+S\x97\xaa\xbe\xf5I\x97*\x05\"\x86&68G\xc1\xe0\x98\x8c\xb4\xf9\x90\xfd\x1d\x0f\xa0\x1d\xccM\xe8\xde\xc7]z\xab\x85\xb5g\xb6\xcc\xd4\x1a\xd3\x12E\x1b\x94\x8at\x13\xf0\xa1B\xfd@*G\x94\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\xa3~L&\x11\b\xda6\xb8\xc6\xf5\x9b\x13\x99\xc7\xfa8\xe8l\xad\x9f(=\xd6x\x81\xa1\x18jH\x81\x83\xa0e\xeb\xe1I\x85\xef\x8d,!f\xd2u\xab\xdaCm\xf9*\x89\xdd\xeb/G\xd3/u*\xa1\xebt\xb*\x05k\xfb\xbaH\x06\x96\xb6_*\x8f!H\xa1)\x91\x03\xc4\xf5}\xf89*:\xf2\xcfL\xa2*\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x83z0\x83\x82R\b\x84f\xeb}:\xa0\u0603\x01\f\x02\x84geth\x88go1.21.1\x85linux\x00\x00\x00\x00\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\x00\x00\x00\x00\x00\x00\x00\x00"
data hash:  0xe781cd5dde130b38dc1ac7882b0affd10b37ff1de94c39e07cbd601b83ec0eb6
-------------------------------------------
Request context:
        NA -> ipc -> NA

Additional HTTP header data, provided by the external caller:
        User-Agent: ""
        Origin: ""
Approve? [y/N]:
> y
\#\# Password for signing

Please enter password for signing data with account 0x2db017E44b03B37755A4b15e14Cd799f83DE4c13
> 
-----------------------

A transação 0x4d60fdb557de763b557ed6f487d882caa3d639af02c9ef04e88afb8cc3ed7969 foi autorizada, porém no terminal de execução do geth aparece uma mensagem:

WARN [09-18|22:34:34.004] Block sealing failed                     err="signed recently, must wait for others"

Se verificarmos os saldos da carteira, podemos verificar que a transação ainda não foi efetivada.

> eth.getBalance("0x2db017e44b03b37755a4b15e14cd799f83de4c13")
299900
> eth.getBalance("0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976")
400100
> eth.getBalance("0x67a3a0eace0bb180b94948ae02b09b7f8948ca60")
0
> 

Pela mensagem é provável que tenhamos que executar dois nós da rede, indicando cada um como signer das contas de assinadores que configuramos.

6.11 Configurando um Segundo Node

Criando o genesis block para o node-1:

[rogerio@ryzen-nitro .etherprivate-clique]$  $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --identity "RAGEtherPrivate" --datadir ~/.etherprivate-clique/node1 init ~/.etherprivate-clique/privategenesis.json
INFO [09-18|23:03:33.713] Maximum peer count                       ETH=50 LES=0 total=50
INFO [09-18|23:03:33.714] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [09-18|23:03:33.716] Set global gas cap                       cap=50,000,000
INFO [09-18|23:03:33.717] Initializing the KZG library             backend=gokzg
INFO [09-18|23:03:33.737] Defaulting to pebble as the backing database 
INFO [09-18|23:03:33.737] Allocated cache and file handles         database=/home/rag/.etherprivate-clique/node1/geth/chaindata cache=16.00MiB handles=16
INFO [09-18|23:03:33.760] Opened ancient database                  database=/home/rag/.etherprivate-clique/node1/geth/chaindata/ancient/chain readonly=false
INFO [09-18|23:03:33.760] Writing custom genesis block 
INFO [09-18|23:03:33.761] Persisted trie from memory database      nodes=3 size=399.00B time="636.339us" gcnodes=0 gcsize=0.00B gctime=0s livenodes=0 livesize=0.00B
INFO [09-18|23:03:33.769] Successfully wrote genesis state         database=chaindata hash=3f324e..fd1d0f
INFO [09-18|23:03:33.769] Defaulting to pebble as the backing database 
INFO [09-18|23:03:33.769] Allocated cache and file handles         database=/home/rag/.etherprivate-clique/node1/geth/lightchaindata cache=16.00MiB handles=16
INFO [09-18|23:03:33.783] Opened ancient database                  database=/home/rag/.etherprivate-clique/node1/geth/lightchaindata/ancient/chain readonly=false
INFO [09-18|23:03:33.783] Writing custom genesis block 
INFO [09-18|23:03:33.784] Persisted trie from memory database      nodes=3 size=399.00B time="662.32us"  gcnodes=0 gcsize=0.00B gctime=0s livenodes=0 livesize=0.00B
INFO [09-18|23:03:33.793] Successfully wrote genesis state         database=lightchaindata hash=3f324e..fd1d0f

Criando o genesis block para o node-2:

[rogerio@ryzen-nitro .etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --identity "RAGEtherPrivate" --datadir ~/.etherprivate-clique/node2 init ~/.etherprivate-clique/privategenesis.json
INFO [09-18|23:03:58.607] Maximum peer count                       ETH=50 LES=0 total=50
INFO [09-18|23:03:58.608] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [09-18|23:03:58.610] Set global gas cap                       cap=50,000,000
INFO [09-18|23:03:58.610] Initializing the KZG library             backend=gokzg
INFO [09-18|23:03:58.638] Defaulting to pebble as the backing database 
INFO [09-18|23:03:58.638] Allocated cache and file handles         database=/home/rag/.etherprivate-clique/node2/geth/chaindata cache=16.00MiB handles=16
INFO [09-18|23:03:58.662] Opened ancient database                  database=/home/rag/.etherprivate-clique/node2/geth/chaindata/ancient/chain readonly=false
INFO [09-18|23:03:58.662] Writing custom genesis block 
INFO [09-18|23:03:58.663] Persisted trie from memory database      nodes=3 size=399.00B time="672.238us" gcnodes=0 gcsize=0.00B gctime=0s livenodes=0 livesize=0.00B
INFO [09-18|23:03:58.672] Successfully wrote genesis state         database=chaindata hash=3f324e..fd1d0f
INFO [09-18|23:03:58.672] Defaulting to pebble as the backing database 
INFO [09-18|23:03:58.672] Allocated cache and file handles         database=/home/rag/.etherprivate-clique/node2/geth/lightchaindata cache=16.00MiB handles=16
INFO [09-18|23:03:58.685] Opened ancient database                  database=/home/rag/.etherprivate-clique/node2/geth/lightchaindata/ancient/chain readonly=false
INFO [09-18|23:03:58.685] Writing custom genesis block 
INFO [09-18|23:03:58.686] Persisted trie from memory database      nodes=3 size=399.00B time="644.371us" gcnodes=0 gcsize=0.00B gctime=0s livenodes=0 livesize=0.00B
INFO [09-18|23:03:58.694] Successfully wrote genesis state         database=lightchaindata hash=3f324e..fd1d0f

Estrutura dos diretórios:

Estrutura de Diretórios para 2 nodes

Criando chave com o bootnode:

[rogerio@ryzen-nitro .etherprivate-clique]$ bootnode -genkey boot.key
[rogerio@ryzen-nitro .etherprivate-clique]$ ls
audit.log  clef     keystore  node2
boot.key   history  node1     privategenesis.json
[rogerio@ryzen-nitro .etherprivate-clique]$ cat boot.key 
40a32d64cff18496ae6426bd7746b220f0f90dd7458c2a8ef3187cbdb5865349

Gerando um enode:

[rogerio@ryzen-nitro .etherprivate-clique]$ bootnode -nodekey boot.key -addr :30305
enode://d918c47d1d47ee9b309622038282167b675e81dfda21d7ad0b7467f08f379a694e43fbf09f9e9c70e6b2343c11dab5d34ee07a71e5fb588cdf329f58fca157b1@127.0.0.1:0?discport=30305
Note: you're using cmd/bootnode, a developer tool.
We recommend using a regular node as bootstrap node for production deployments.
INFO [09-18|23:06:45.222] New local node record                    seq=1,726,711,605,221 id=96f33241c1e9dd68 ip="invalid IP" udp=0 tcp=0

Iniciando o node-1:

$HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --identity "RAGEtherPrivate" --datadir ~/.etherprivate-clique/node1 --port 30306 --bootnodes enode://d918c47d1d47ee9b309622038282167b675e81dfda21d7ad0b7467f08f379a694e43fbf09f9e9c70e6b2343c11dab5d34ee07a71e5fb588cdf329f58fca157b1@127.0.0.1:0?discport=30305 --unlock 0x2db017e44b03b37755a4b15e14cd799f83de4c13 --miner.etherbase=0x2db017e44b03b37755a4b15e14cd799f83de4c13 --syncmode full --allow-insecure-unlock --http --http.addr 127.0.0.1 --http.port 8560 --http.api "eth,net,web3,personal,engine,admin,debug,admin,miner,txpool" --keystore ~/.etherprivate-clique/keystore --authrpc.addr localhost --authrpc.port 8552 --authrpc.vhosts localhost --nodiscover --maxpeers 15  --miner.gasprice "1" --signer=/home/rag/.etherprivate-clique/clef/clef.ipc

Iniciando o node-2:

$HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --identity "RAGEtherPrivate" --datadir ~/.etherprivate-clique/node2 --port 30307 --bootnodes enode://d918c47d1d47ee9b309622038282167b675e81dfda21d7ad0b7467f08f379a694e43fbf09f9e9c70e6b2343c11dab5d34ee07a71e5fb588cdf329f58fca157b1@127.0.0.1:0?discport=30305  --unlock 0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976 --miner.etherbase=0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976 --syncmode full --allow-insecure-unlock --http --http.addr 127.0.0.1 --http.port 8561 --http.api "eth,net,web3,personal,engine,admin,debug,admin,miner,txpool" --keystore ~/.etherprivate-clique/keystore --authrpc.addr localhost --authrpc.port 8553 --authrpc.vhosts localhost --nodiscover --maxpeers 15  --miner.gasprice "1" --signer=/home/rag/.etherprivate-clique/clef/clef.ipc

Conecte em cada node com um console JavaScript e consulte o saldo das carteiras e recibo da transação:

[rogerio@ryzen-nitro .etherprivate-clique]$ ~/go-ethereum-1.12.2/build/bin/geth attach /home/rag/.etherprivate-clique/node1/geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/RAGEtherPrivate/v1.12.2-stable-bed84606/linux-amd64/go1.21.1
coinbase: 0x2db017e44b03b37755a4b15e14cd799f83de4c13
at block: 13 (Thu Sep 19 2024 00:38:09 GMT-0300 (-03))
 datadir: /home/rag/.etherprivate-clique/node1
 modules: admin:1.0 clique:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0

To exit, press ctrl-d or type exit
> > eth.getBalance("0x2db017e44b03b37755a4b15e14cd799f83de4c13")

299900
> eth.getBalance("0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976")

400100
> eth.getBalance("0x67a3a0eace0bb180b94948ae02b09b7f8948ca60")

0
> eth.getTransactionReceipt("0xf9dba156ca7aec18836ff354263b4032209250009c323e29406334a13f34a21f")
{
  blockHash: "0xb1071e241e9311171f60cf7ba40f39ece17b35301d7a07c3db8ef83ae3a8390b",
  blockNumber: 2,
  contractAddress: null,
  cumulativeGasUsed: 21000,
  effectiveGasPrice: 1,
  from: "0x2db017e44b03b37755a4b15e14cd799f83de4c13",
  gasUsed: 21000,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  status: "0x1",
  to: "0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976",
  transactionHash: "0xf9dba156ca7aec18836ff354263b4032209250009c323e29406334a13f34a21f",
  transactionIndex: 0,
  type: "0x0"
}
> 

No node2 ainda não aparecia os mesmos dados e nem informações sobre pares admin.peers retornava vazio:

[rogerio@ryzen-nitro .etherprivate-clique]$ ~/go-ethereum-1.12.2/build/bin/geth attach /home/rag/.etherprivate-clique/node2/geth.ipc 
Welcome to the Geth JavaScript console!

instance: Geth/RAGEtherPrivate/v1.12.2-stable-bed84606/linux-amd64/go1.21.1
coinbase: 0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976
at block: 13 (Thu Sep 19 2024 00:38:09 GMT-0300 (-03))
 datadir: /home/rag/.etherprivate-clique/node2
 modules: admin:1.0 clique:1.0 debug:1.0 engine:1.0 eth:1.0 miner:1.0 net:1.0 rpc:1.0 txpool:1.0 web3:1.0

To exit, press ctrl-d or type exit
> > eth.getBalance("0x2db017e44b03b37755a4b15e14cd799f83de4c13")
300000
> eth.getBalance("0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976")
400000
> admin.peers
[]

Tentei adicionar o enode como par e nada:

> admin.addPeer("enode://d918c47d1d47ee9b309622038282167b675e81dfda21d7ad0b7467f08f379a694e43fbf09f9e9c70e6b2343c11dab5d34ee07a71e5fb588cdf329f58fca157b1@127.0.0.1:0?discport=30305")
true
> admin.peers
[]
> eth.getTransactionReceipt("0xf9dba156ca7aec18836ff354263b4032209250009c323e29406334a13f34a21f")
null
> eth.getBalance("0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976")
400000
> miner.start()
null

Adicionar o node1 como par do node2, recupere o código enr no console JavaScript conectado ao node1:

> admin.nodeInfo.enr
"enr:-Jy4QNIeBFYOCqu4XwFp9IH4slO75F4oRtQsnClncm82wDbrTDJxlXm_EG3KAUNevf9-hS_6esq3F1111q86KNT3MBaGAZIIJEzng2V0aMfGhDf_6yKAgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQIczpJdu-Q78j5Oue6jql8WNGVdMI6d9Is-guHgDqx1ZIRzbmFwwIN0Y3CCdmI"
> 

E adicione ele como par no console JavaScript conectado ao node2:

> admin.addPeer("enr:-Jy4QNIeBFYOCqu4XwFp9IH4slO75F4oRtQsnClncm82wDbrTDJxlXm_EG3KAUNevf9-hS_6esq3F1111q86KNT3MBaGAZIIJEzng2V0aMfGhDf_6yKAgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQIczpJdu-Q78j5Oue6jql8WNGVdMI6d9Is-guHgDqx1ZIRzbmFwwIN0Y3CCdmI")
true
> admin.peers
[{
    caps: ["eth/66", "eth/67", "eth/68", "snap/1"],
    enode: "enode://1cce925dbbe43bf23e4eb9eea3aa5f1634655d308e9df48b3e82e1e00eac7564217836aa5d2d717496be48747fc01a7e2f3a640c32c17e6670de83dabae77236@127.0.0.1:30306?discport=0",
    enr: "enr:-Jy4QNIeBFYOCqu4XwFp9IH4slO75F4oRtQsnClncm82wDbrTDJxlXm_EG3KAUNevf9-hS_6esq3F1111q86KNT3MBaGAZIIJEzng2V0aMfGhDf_6yKAgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQIczpJdu-Q78j5Oue6jql8WNGVdMI6d9Is-guHgDqx1ZIRzbmFwwIN0Y3CCdmI",
    id: "4968f9e3d9869eeb2dd3a2d908f49580a3078bda6064394dd598a937db55b4a9",
    name: "Geth/RAGEtherPrivate/v1.12.2-stable-bed84606/linux-amd64/go1.21.1",
    network: {
      inbound: false,
      localAddress: "127.0.0.1:48198",
      remoteAddress: "127.0.0.1:30306",
      static: true,
      trusted: false
    },
    protocols: {
      eth: {
        version: 68
      },
      snap: {
        version: 1
      }
    }
}]

Recuperando os saldos no console JavaScript conectado ao node2 agora sim aparece os dados sincronizados:

> eth.getBalance("0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976")

400100
> eth.getBalance("0x2db017e44b03b37755a4b15e14cd799f83de4c13")

299900

Mais detalhes de como implantar uma rede privada local do Ethereum podem ser visto em Private Networks.

6.12 Comandos Finais

A Figura 9.I apresenta os comandos para cada um dos terminais.

Figure 6.I: Terminais

O comando para o terminal de execução do clef:

[rogerio@ryzen-nitro .etherprivate-clique]$ /home/rag/go-ethereum-1.12.2/build/bin/clef --chainid 786 --keystore ~/.etherprivate-clique/keystore --configdir ~/.etherprivate-clique/clef --http

O comando para o terminal de execução do geth node1:

[rogerio@ryzen-nitro .etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --identity "RAGEtherPrivate" --datadir ~/.etherprivate-clique/node1 --port 30306 --bootnodes enode://d918c47d1d47ee9b309622038282167b675e81dfda21d7ad0b7467f08f379a694e43fbf09f9e9c70e6b2343c11dab5d34ee07a71e5fb588cdf329f58fca157b1@127.0.0.1:0?discport=30305 --unlock 0x2db017e44b03b37755a4b15e14cd799f83de4c13 --miner.etherbase=0x2db017e44b03b37755a4b15e14cd799f83de4c13 --syncmode full --allow-insecure-unlock --http --http.addr 127.0.0.1 --http.port 8560 --http.api "eth,net,web3,personal,engine,admin,debug,admin,miner,txpool" --keystore ~/.etherprivate-clique/keystore --authrpc.addr localhost --authrpc.port 8552 --authrpc.vhosts localhost --nodiscover --maxpeers 15  --miner.gasprice "1" --signer=/home/rag/.etherprivate-clique/clef/clef.ipc

O comando para o terminal de execução do geth node2:

[rogerio@ryzen-nitro .etherprivate-clique]$ $HOME/go-ethereum-1.12.2/build/bin/geth --networkid 786 --identity "RAGEtherPrivate" --datadir ~/.etherprivate-clique/node2 --port 30307 --bootnodes enode://d918c47d1d47ee9b309622038282167b675e81dfda21d7ad0b7467f08f379a694e43fbf09f9e9c70e6b2343c11dab5d34ee07a71e5fb588cdf329f58fca157b1@127.0.0.1:0?discport=30305  --unlock 0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976 --miner.etherbase=0xbb36f26e6c16b3c7ed3d70bfb26f740336b4f976 --syncmode full --allow-insecure-unlock --http --http.addr 127.0.0.1 --http.port 8561 --http.api "eth,net,web3,personal,engine,admin,debug,admin,miner,txpool" --keystore ~/.etherprivate-clique/keystore --authrpc.addr localhost --authrpc.port 8553 --authrpc.vhosts localhost --nodiscover --maxpeers 15  --miner.gasprice "1" --signer=/home/rag/.etherprivate-clique/clef/clef.ipc

O comando para o console JavaScript conectado ao node1:

[rogerio@ryzen-nitro .etherprivate-clique]$ ~/go-ethereum-1.12.2/build/bin/geth attach /home/rag/.etherprivate-clique/node1/geth.ipc

O comando para o console JavaScript conectado ao node2:

[rogerio@ryzen-nitro .etherprivate-clique]$ ~/go-ethereum-1.12.2/build/bin/geth attach /home/rag/.etherprivate-clique/node2/geth.ipc

A Figura 6.II apresenta os terminais com a execução dos respectivos comandos.

Figure 6.II: Terminais

6.13 Leitura Recomendada

7 Referências

8 Word Cloud

8.1 Referências