Skip to content
Snippets Groups Projects
Commit e0ca8e1d authored by Miguel Montes's avatar Miguel Montes
Browse files

Eliminación del paquete util

parent d9d05bc0
No related branches found
No related tags found
No related merge requests found
...@@ -4,7 +4,7 @@ import ( ...@@ -4,7 +4,7 @@ import (
"encoding/json" "encoding/json"
"flag" "flag"
"fmt" "fmt"
"io/ioutil" "io"
"log" "log"
"math/big" "math/big"
"os" "os"
...@@ -14,8 +14,9 @@ import ( ...@@ -14,8 +14,9 @@ import (
"strings" "strings"
"time" "time"
"github.com/ethereum/go-ethereum/common"
"gitlab.bfa.ar/miguel/bfa/internal/bfa" "gitlab.bfa.ar/miguel/bfa/internal/bfa"
"gitlab.bfa.ar/miguel/bfa/internal/util" "gitlab.bfa.ar/miguel/bfa/internal/cond"
) )
const ( const (
...@@ -58,6 +59,24 @@ var ( ...@@ -58,6 +59,24 @@ var (
} }
) )
func PrintJson(s interface{}) {
v, err := json.MarshalIndent(s, "", " ")
cond.Check(err)
fmt.Println(string(v))
}
func IsValidAddress(address string) bool {
if !common.IsHexAddress(address) {
return false
}
// is mixed case hex address
if strings.ContainsAny(address, "abcdef") && strings.ContainsAny(address, "ABCDEF") {
return common.HexToAddress(address).Hex() == address
} else {
return true
}
}
func setFlags() { func setFlags() {
flags.BoolVar(&jsonOutput, "json", false, "Produce salida en formato json") flags.BoolVar(&jsonOutput, "json", false, "Produce salida en formato json")
flags.StringVar(&url, "url", "", "URL para conexión con geth. Ejemplo: '/home/bfa/bfa/network/node/geth.ipc' o 'http://localhost:8545'") flags.StringVar(&url, "url", "", "URL para conexión con geth. Ejemplo: '/home/bfa/bfa/network/node/geth.ipc' o 'http://localhost:8545'")
...@@ -93,7 +112,7 @@ func updateURL(url string) (updated string) { ...@@ -93,7 +112,7 @@ func updateURL(url string) (updated string) {
} }
func usage(errorCode int) { func usage(errorCode int) {
util.Require(len(os.Args) > 1, "not enough arguments") cond.Require(len(os.Args) > 1, "not enough arguments")
_, _ = fmt.Fprintf(os.Stderr, "Uso: %v %v [opciones] %v\n%v\n", os.Args[0], os.Args[1], otherArgs, description) _, _ = fmt.Fprintf(os.Stderr, "Uso: %v %v [opciones] %v\n%v\n", os.Args[0], os.Args[1], otherArgs, description)
flags.PrintDefaults() flags.PrintDefaults()
os.Exit(errorCode) os.Exit(errorCode)
...@@ -101,7 +120,7 @@ func usage(errorCode int) { ...@@ -101,7 +120,7 @@ func usage(errorCode int) {
func parseFlags(allowAdditionalArgs bool) { func parseFlags(allowAdditionalArgs bool) {
err := flags.Parse(os.Args[2:]) err := flags.Parse(os.Args[2:])
util.Check(err) cond.Check(err)
if help { if help {
usage(0) usage(0)
} }
...@@ -119,12 +138,12 @@ func proposals() { ...@@ -119,12 +138,12 @@ func proposals() {
parseFlags(false) parseFlags(false)
url = updateURL(url) url = updateURL(url)
node, err := bfa.Dial(url) node, err := bfa.Dial(url)
util.Check(err) cond.Check(err)
defer node.Close() defer node.Close()
blockNumber = node.BlockNumberInRange(blockNumber) blockNumber = node.BlockNumberInRange(blockNumber)
votes := node.Votes(blockNumber) votes := node.Votes(blockNumber)
if jsonOutput { if jsonOutput {
util.PrintJson(votes) PrintJson(votes)
return return
} }
fmt.Printf("Bloque: %d\nPropuestas en curso: %d\n", votes.BlockNumber, len(votes.Proposals)) fmt.Printf("Bloque: %d\nPropuestas en curso: %d\n", votes.BlockNumber, len(votes.Proposals))
...@@ -179,7 +198,7 @@ func parseFormatString(s string) (format string) { ...@@ -179,7 +198,7 @@ func parseFormatString(s string) (format string) {
func printSealers(sealers []bfa.Address) { func printSealers(sealers []bfa.Address) {
bfa.SortAddresses(sealers) bfa.SortAddresses(sealers)
if jsonOutput { if jsonOutput {
util.PrintJson(sealers) PrintJson(sealers)
} else { } else {
for _, sealer := range sealers { for _, sealer := range sealers {
fmt.Println(sealer.Hex()) fmt.Println(sealer.Hex())
...@@ -226,15 +245,15 @@ func sealers() { ...@@ -226,15 +245,15 @@ func sealers() {
flags.StringVar(&unit, "unit", "wei", "Unidades en la que se expresa el balance. Posibles valores: wei, Kwei, kilowei, Mwei, megawei, Gwei, gigawei, microether, milliether, ether, babbage, lovelace, shannon, szabo, finney.") flags.StringVar(&unit, "unit", "wei", "Unidades en la que se expresa el balance. Posibles valores: wei, Kwei, kilowei, Mwei, megawei, Gwei, gigawei, microether, milliether, ether, babbage, lovelace, shannon, szabo, finney.")
parseFlags(false) parseFlags(false)
if blockNumber == 0 { if blockNumber == 0 {
util.Error("El bloque génesis no tiene firmantes\n") log.Fatal("El bloque génesis no tiene firmantes\n")
} }
unit = strings.ToLower(unit) unit = strings.ToLower(unit)
if _, ok := units[unit]; !ok { if _, ok := units[unit]; !ok {
util.Error("Unidad '%v' desconocida\n", unit) log.Fatalf("Unidad '%v' desconocida\n", unit)
} }
url = updateURL(url) url = updateURL(url)
node, err := bfa.Dial(url) node, err := bfa.Dial(url)
util.Check(err) cond.Check(err)
defer node.Close() defer node.Close()
blockNumber = node.BlockNumberInRange(blockNumber) blockNumber = node.BlockNumberInRange(blockNumber)
extended := lastBlock || timestamp || difficulty || balance || len(formatStr) > 0 extended := lastBlock || timestamp || difficulty || balance || len(formatStr) > 0
...@@ -246,7 +265,7 @@ func sealers() { ...@@ -246,7 +265,7 @@ func sealers() {
sealers := node.SealersStatus(blockNumber) sealers := node.SealersStatus(blockNumber)
if jsonOutput { if jsonOutput {
util.PrintJson(sealers) PrintJson(sealers)
return return
} }
...@@ -282,7 +301,7 @@ func sealers() { ...@@ -282,7 +301,7 @@ func sealers() {
formatStr = "%42v" formatStr = "%42v"
if lastBlock { if lastBlock {
formatStr += " %[2]*[3]v" formatStr += " %[2]*[3]v"
lastBlockLen = util.Max(2, int64(len(strconv.FormatInt(sealers[list[0]].LastBlock, 10)))) lastBlockLen = max(2, int64(len(strconv.FormatInt(sealers[list[0]].LastBlock, 10))))
} }
if timestamp { if timestamp {
formatStr += " %[4]*[5]v" formatStr += " %[4]*[5]v"
...@@ -303,7 +322,7 @@ func sealers() { ...@@ -303,7 +322,7 @@ func sealers() {
lastBlockLen, fmt.Sprintf("%*v", -lastBlockLen/2-2, "Last"), lastBlockLen, fmt.Sprintf("%*v", -lastBlockLen/2-2, "Last"),
timestampLen, fmt.Sprintf("%*v", -timestampLen/2-2, "Time"), timestampLen, fmt.Sprintf("%*v", -timestampLen/2-2, "Time"),
"Dif", "Dif",
balanceLen, fmt.Sprintf("%*v", -(int(balanceLen)+len(unit))/2-1, strings.Title(unit))) balanceLen, fmt.Sprintf("%*v", -(int(balanceLen)+len(unit))/2-1, unit))
} }
} }
formatStr += "\n" formatStr += "\n"
...@@ -335,22 +354,22 @@ func autovote() { ...@@ -335,22 +354,22 @@ func autovote() {
flags.IntVar(&threshold, "threshold", voteThreshold, "Cantidad mínima de votos en una propuesta para habilitar el voto automático.") flags.IntVar(&threshold, "threshold", voteThreshold, "Cantidad mínima de votos en una propuesta para habilitar el voto automático.")
setFlags() setFlags()
parseFlags(false) parseFlags(false)
util.Ensure(threshold >= voteThreshold, "No se puede especificar una cantidad de votos inferior a %v.", voteThreshold) cond.Ensure(threshold >= voteThreshold, "No se puede especificar una cantidad de votos inferior a %v.", voteThreshold)
url = updateURL(url) url = updateURL(url)
node, err := bfa.Dial(url) node, err := bfa.Dial(url)
util.Check(err) cond.Check(err)
defer node.Close() defer node.Close()
util.Ensure(node.IsSealer(bfa.Self), "Solo los selladores pueden votar") cond.Ensure(node.IsSealer(bfa.Self), "Solo los selladores pueden votar")
votes := node.Votes(latest) votes := node.Votes(latest)
genesisSigners := node.SealersAtBlock(0) genesisSigners := node.SealersAtBlock(0)
self, err := node.Coinbase() self, err := node.Coinbase()
util.Check(err) cond.Check(err)
for _, tally := range votes.Tally { for _, tally := range votes.Tally {
if tally.False >= threshold { // We are trying to remove a sealer if tally.False >= threshold { // We are trying to remove a sealer
removedSealers++ removedSealers++
} }
} }
util.Ensure(len(votes.Signers)-removedSealers >= minSigners, "No se puede emitir un voto automático que reduzca la cantidad de selladores por debajo de %v.", minSigners) cond.Ensure(len(votes.Signers)-removedSealers >= minSigners, "No se puede emitir un voto automático que reduzca la cantidad de selladores por debajo de %v.", minSigners)
for _, proposal := range votes.Proposals { for _, proposal := range votes.Proposals {
isSealer := proposal.In(votes.Signers) isSealer := proposal.In(votes.Signers)
switch { switch {
...@@ -375,7 +394,7 @@ func autovote() { ...@@ -375,7 +394,7 @@ func autovote() {
} }
} }
if jsonOutput { if jsonOutput {
util.PrintJson(voted) PrintJson(voted)
} }
} }
...@@ -391,22 +410,22 @@ func propose() { ...@@ -391,22 +410,22 @@ func propose() {
parseFlags(true) parseFlags(true)
url = updateURL(url) url = updateURL(url)
node, err := bfa.Dial(url) node, err := bfa.Dial(url)
util.Check(err) cond.Check(err)
defer node.Close() defer node.Close()
util.Ensure(node.IsSealer(bfa.Self), "Solo los selladores pueden votar") cond.Ensure(node.IsSealer(bfa.Self), "Solo los selladores pueden votar")
votes := node.Votes(latest) votes := node.Votes(latest)
util.Ensure(flags.NArg() > 0, "No se especificaron candidatos por los cuales votar\n") cond.Ensure(flags.NArg() > 0, "No se especificaron candidatos por los cuales votar\n")
for i := 0; i < flags.NArg(); i++ { for i := 0; i < flags.NArg(); i++ {
addr := flags.Arg(i) addr := flags.Arg(i)
util.Ensure(util.IsValidAddress(addr), "'%v' no es una dirección válida\n", addr) cond.Ensure(IsValidAddress(addr), "'%v' no es una dirección válida\n", addr)
address := bfa.HexToAddress(addr) address := bfa.HexToAddress(addr)
if _, ok := votes.Tally[address]; !ok { if _, ok := votes.Tally[address]; !ok {
isSealer := address.In(votes.Signers) isSealer := address.In(votes.Signers)
switch { // address is not in a proposal, we only allow removing signers or adding non signers switch { // address is not in a proposal, we only allow removing signers or adding non signers
case isSealer && authorize: case isSealer && authorize:
util.Error("'%v' ya es un sellador\n", address) log.Fatalf("'%v' ya es un sellador\n", address)
case !isSealer && !authorize: case !isSealer && !authorize:
util.Error("'%v' no es un sellador\n", address) log.Fatalf("'%v' no es un sellador\n", address)
} }
} }
node.Propose(address, authorize) node.Propose(address, authorize)
...@@ -417,7 +436,7 @@ func propose() { ...@@ -417,7 +436,7 @@ func propose() {
} }
} }
if jsonOutput { if jsonOutput {
util.PrintJson(voted) PrintJson(voted)
} }
} }
...@@ -447,7 +466,7 @@ func status() { ...@@ -447,7 +466,7 @@ func status() {
parseFlags(false) parseFlags(false)
url = updateURL(url) url = updateURL(url)
node, err := bfa.Dial(url) node, err := bfa.Dial(url)
util.Check(err) cond.Check(err)
defer node.Close() defer node.Close()
for _, account := range node.Accounts() { for _, account := range node.Accounts() {
nodeStatus.Accounts[account] = node.Balance(account) nodeStatus.Accounts[account] = node.Balance(account)
...@@ -475,7 +494,7 @@ func status() { ...@@ -475,7 +494,7 @@ func status() {
nodeStatus.BFAGenesis = bfa.Genesis(nodeStatus.Genesis).String() nodeStatus.BFAGenesis = bfa.Genesis(nodeStatus.Genesis).String()
nodeStatus.BFANetwork = bfa.Network(nodeStatus.Network).String() nodeStatus.BFANetwork = bfa.Network(nodeStatus.Network).String()
nodeStatus.PeerCount = node.PeerCount() nodeStatus.PeerCount = node.PeerCount()
util.PrintJson(nodeStatus) PrintJson(nodeStatus)
} }
func block() { func block() {
...@@ -488,11 +507,11 @@ func block() { ...@@ -488,11 +507,11 @@ func block() {
parseFlags(false) parseFlags(false)
url = updateURL(url) url = updateURL(url)
node, err := bfa.Dial(url) node, err := bfa.Dial(url)
util.Check(err) cond.Check(err)
defer node.Close() defer node.Close()
blockNumber = node.BlockNumberInRange(blockNumber) blockNumber = node.BlockNumberInRange(blockNumber)
block := node.BlockByNumber(blockNumber) block := node.BlockByNumber(blockNumber)
util.PrintJson(block) PrintJson(block)
} }
func snapshot() { func snapshot() {
...@@ -503,11 +522,11 @@ func snapshot() { ...@@ -503,11 +522,11 @@ func snapshot() {
parseFlags(false) parseFlags(false)
url = updateURL(url) url = updateURL(url)
node, err := bfa.Dial(url) node, err := bfa.Dial(url)
util.Check(err) cond.Check(err)
defer node.Close() defer node.Close()
blockNumber = node.BlockNumberInRange(blockNumber) blockNumber = node.BlockNumberInRange(blockNumber)
snapshot := node.SnapshotAtBlock(blockNumber) snapshot := node.SnapshotAtBlock(blockNumber)
util.PrintJson(snapshot) PrintJson(snapshot)
} }
func transfers() { func transfers() {
...@@ -528,13 +547,13 @@ func transfers() { ...@@ -528,13 +547,13 @@ func transfers() {
parseFlags(true) parseFlags(true)
url = updateURL(url) url = updateURL(url)
node, err := bfa.Dial(url) node, err := bfa.Dial(url)
util.Check(err) cond.Check(err)
defer node.Close() defer node.Close()
set := make(map[bfa.Address]bool) set := make(map[bfa.Address]bool)
txs := make([]Transfer, 0) txs := make([]Transfer, 0)
for i := 0; i < flags.NArg(); i++ { for i := 0; i < flags.NArg(); i++ {
address := flags.Arg(i) address := flags.Arg(i)
util.Ensure(util.IsValidAddress(address), "'%v' no es una dirección válida\n", address) cond.Ensure(IsValidAddress(address), "'%v' no es una dirección válida\n", address)
set[bfa.HexToAddress(address)] = true set[bfa.HexToAddress(address)] = true
} }
latest := node.BlockNumber() latest := node.BlockNumber()
...@@ -576,7 +595,7 @@ func transfers() { ...@@ -576,7 +595,7 @@ func transfers() {
} }
} }
if jsonOutput { if jsonOutput {
util.PrintJson(txs) PrintJson(txs)
} }
} }
...@@ -621,7 +640,7 @@ func calculateSealerStats(url string, first int64, last int64, factor int64) (se ...@@ -621,7 +640,7 @@ func calculateSealerStats(url string, first int64, last int64, factor int64) (se
lastBlock, end int64 lastBlock, end int64
) )
node, err := bfa.Dial(url) node, err := bfa.Dial(url)
util.Check(err) cond.Check(err)
defer node.Close() defer node.Close()
sealerStats = make(map[bfa.Address]*Stats) sealerStats = make(map[bfa.Address]*Stats)
latest := node.BlockNumber() latest := node.BlockNumber()
...@@ -746,12 +765,12 @@ func calculateSealerStats(url string, first int64, last int64, factor int64) (se ...@@ -746,12 +765,12 @@ func calculateSealerStats(url string, first int64, last int64, factor int64) (se
func readStatsFromFile(filename string) (sealerStats map[bfa.Address]*Stats) { func readStatsFromFile(filename string) (sealerStats map[bfa.Address]*Stats) {
file, err := os.Open(filename) file, err := os.Open(filename)
util.Check(err) cond.Check(err)
defer file.Close() defer file.Close()
byteBuffer, err := ioutil.ReadAll(file) byteBuffer, err := io.ReadAll(file)
util.Check(err) cond.Check(err)
err = json.Unmarshal(byteBuffer, &sealerStats) err = json.Unmarshal(byteBuffer, &sealerStats)
util.Check(err) cond.Check(err)
return return
} }
...@@ -775,7 +794,7 @@ func sealerstats() { ...@@ -775,7 +794,7 @@ func sealerstats() {
} else { } else {
sealerStats = calculateSealerStats(url, first, last, factor) sealerStats = calculateSealerStats(url, first, last, factor)
} }
util.PrintJson(sealerStats) PrintJson(sealerStats)
} }
func main() { func main() {
...@@ -794,6 +813,7 @@ func main() { ...@@ -794,6 +813,7 @@ func main() {
validCommands []string validCommands []string
command func() command func()
) )
log.SetFlags(0)
for cmd := range commands { for cmd := range commands {
validCommands = append(validCommands, cmd) validCommands = append(validCommands, cmd)
} }
...@@ -801,6 +821,6 @@ func main() { ...@@ -801,6 +821,6 @@ func main() {
if len(os.Args) > 1 { if len(os.Args) > 1 {
command = commands[os.Args[1]] command = commands[os.Args[1]]
} }
util.Ensure(command != nil, "Uso: %v <%v> [opciones]\nPara ayuda: %v <command> -h\n", path.Base(os.Args[0]), strings.Join(validCommands, "|"), path.Base(os.Args[0])) cond.Ensure(command != nil, "Uso: %v <%v> [opciones]\nPara ayuda: %v <command> -h\n", path.Base(os.Args[0]), strings.Join(validCommands, "|"), path.Base(os.Args[0]))
command() command()
} }
package util package main
import ( import (
"strings" "strings"
......
...@@ -11,7 +11,7 @@ import ( ...@@ -11,7 +11,7 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"gitlab.bfa.ar/miguel/bfa/internal/util" "gitlab.bfa.ar/miguel/bfa/internal/cond"
) )
type BigInt struct { type BigInt struct {
...@@ -50,7 +50,7 @@ func (b Bytes) MarshalJSON() ([]byte, error) { ...@@ -50,7 +50,7 @@ func (b Bytes) MarshalJSON() ([]byte, error) {
} }
func (b *Bytes) UnmarshalJSON(src []byte) (err error) { func (b *Bytes) UnmarshalJSON(src []byte) (err error) {
util.Require(len(src) >= 4 && bytes.Equal(src[1:3], []byte("0x")), "invalid json string") cond.Require(len(src) >= 4 && bytes.Equal(src[1:3], []byte("0x")), "invalid json string")
dest := make([]byte, hex.DecodedLen(len(src)-4)) dest := make([]byte, hex.DecodedLen(len(src)-4))
_, err = hex.Decode(dest, src[3:len(src)-1]) _, err = hex.Decode(dest, src[3:len(src)-1])
if err == nil { if err == nil {
......
package bfa package bfa
import ( import (
"fmt"
"strconv" "strconv"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -8,7 +9,7 @@ import ( ...@@ -8,7 +9,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/consensus/clique"
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"gitlab.bfa.ar/miguel/bfa/internal/util" "gitlab.bfa.ar/miguel/bfa/internal/cond"
) )
type Node rpc.Client type Node rpc.Client
...@@ -87,7 +88,7 @@ func (genesis Genesis) String() string { ...@@ -87,7 +88,7 @@ func (genesis Genesis) String() string {
var Self = Address{} // Empty address to represent the address of the caller var Self = Address{} // Empty address to represent the address of the caller
func (node *Node) Call(result interface{}, method string, args ...interface{}) { func (node *Node) Call(result interface{}, method string, args ...interface{}) {
util.Check((*rpc.Client)(node).Call(result, method, args...)) cond.Check((*rpc.Client)(node).Call(result, method, args...))
} }
func (node *Node) CallWithError(result interface{}, method string, args ...interface{}) error { func (node *Node) CallWithError(result interface{}, method string, args ...interface{}) error {
...@@ -142,7 +143,7 @@ func (node *Node) BlockNumberInRange(number int64) (blockNumber int64) { ...@@ -142,7 +143,7 @@ func (node *Node) BlockNumberInRange(number int64) (blockNumber int64) {
case number == -1, number > latest: case number == -1, number > latest:
blockNumber = latest blockNumber = latest
case number < 0: case number < 0:
blockNumber = util.Max(0, latest+1+number) blockNumber = max(0, latest+1+number)
default: default:
blockNumber = number blockNumber = number
} }
...@@ -210,7 +211,7 @@ func (node *Node) SealersAtBlock(blockNumber int64) (signers []Address) { ...@@ -210,7 +211,7 @@ func (node *Node) SealersAtBlock(blockNumber int64) (signers []Address) {
if blockNumber == -1 { if blockNumber == -1 {
return node.Sealers() return node.Sealers()
} }
node.Call(&signers, "clique_getSigners", util.Int64ToHex(blockNumber)) node.Call(&signers, "clique_getSigners", fmt.Sprintf("0x%x", blockNumber))
return return
} }
...@@ -315,7 +316,7 @@ func (node *Node) SealersStatus(blockNumber int64) (status map[Address]*SealerSt ...@@ -315,7 +316,7 @@ func (node *Node) SealersStatus(blockNumber int64) (status map[Address]*SealerSt
notSeen := int64(len(status)) notSeen := int64(len(status))
block := node.HeaderByNumber(blockNumber) block := node.HeaderByNumber(blockNumber)
blockNumber = block.Number.Int64() blockNumber = block.Number.Int64()
until := util.Max(1, blockNumber-SealerRounds*notSeen) until := max(1, blockNumber-SealerRounds*notSeen)
for notSeen > 0 { for notSeen > 0 {
signer := node.BlockSigner(blockNumber) signer := node.BlockSigner(blockNumber)
if _, ok := status[signer]; !ok { if _, ok := status[signer]; !ok {
......
package cond
import (
"log"
"runtime"
)
func Ensure(condition bool, format string, args ...interface{}) {
if !condition {
log.Fatalf(format, args...)
}
}
func Check(err error) {
Ensure(err == nil, "%v\n", err)
}
func Require(condition bool, msg string) {
if !condition {
ptr, _, _, _ := runtime.Caller(1)
log.Panicf("%v in %v", msg, runtime.FuncForPC(ptr).Name())
}
}
package util
import (
"encoding/json"
"fmt"
"log"
"os"
"runtime"
"strconv"
"strings"
"github.com/ethereum/go-ethereum/common"
)
func Contains(slice []string, s string) bool {
for _, x := range slice {
if x == s {
return true
}
}
return false
}
func Error(format string, args ...interface{}) {
_, _ = fmt.Fprintf(os.Stderr, format, args...)
os.Exit(1)
}
func Ensure(condition bool, format string, args ...interface{}) {
if !condition {
Error(format, args...)
}
}
func Check(err error) {
Ensure(err == nil, "%v\n", err)
}
func Int64ToHex(n int64) string {
return "0x" + strconv.FormatInt(n, 16)
}
func Require(condition bool, msg string) {
if !condition {
ptr, _, _, _ := runtime.Caller(1)
log.Panicf("%v in %v", msg, runtime.FuncForPC(ptr).Name())
}
}
func Min(a, b int64) int64 {
if a < b {
return a
}
return b
}
func Max(a, b int64) int64 {
if a > b {
return a
}
return b
}
func PrintJson(s interface{}) {
v, err := json.MarshalIndent(s, "", " ")
Check(err)
fmt.Println(string(v))
}
func isMixedCase(address string) bool {
return strings.ContainsAny(address, "abcdef") && strings.ContainsAny(address, "ABCDEF")
}
func IsValidAddress(address string) bool {
if !common.IsHexAddress(address) {
return false
}
if isMixedCase(address) {
return common.HexToAddress(address).Hex() == address
} else {
return true
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment