TrueBlocks / trueblocks-core

The main repository for the TrueBlocks system
https://trueblocks.io
GNU General Public License v3.0
1.04k stars 194 forks source link

state: add send functionality #3788

Open dszlachta opened 2 weeks ago

dszlachta commented 2 weeks ago

Send functionality allows chifra state to write to the chain. We already have calling syntax, e.g. chifra state --call afunction(aParam) myContract which seems to fit here as well.

To handle account keys and signing, we can use go-ethereum built-in account management: https://geth.ethereum.org/docs/developers/dapp-developer/native-accounts. The page describes two authorization patterns: single and multiple. For chifra, single is enough. But for updating Unchained Index, we'd most likely want multiple. Multiple authorizations are not that safe if an attacker has access to the filesystem, but: a. if they have access, they probably know the password already; b. any account with keys stored on disk should be considered vulnerable. We can mitigate the risks by using Safe account with a daily spending limit or account with no ETH, abstracting gas to another one (and maybe this one is Safe account too with daily limit set to only be able to update Unchained Index).

For both authorization methods we need to read the password. I suggest we read it from environment variable.

When it comes to executing the transaction, go-ethereum just runs eth_sendRawTransaction under the hood, which means we have to take care of setting the gas: https://github.com/ethereum/go-ethereum/blob/v1.14.5/ethclient/ethclient.go#L624. Because we don't want the responsibility, we should require that the user sets max_priority_fee_per_gas, max_fee_per_gas or both. We can store a predefined values for e.g. updating UnchainedIndex contract.

Another thing is that we should have a way for the user to review the transaction before paying any ETH. As we don't want any interactive prompts, one possible solution is to have "dry run" mode as the default one. It would print transaction details, but send nothing. The user can send the transaction by running the same command with --run appended. In Go (internally and in the SDK), we can have a type that stores transaction details with Send method that executes the transaction. We can check if the current types.Transaction fits here.