Created
November 5, 2018 07:47
-
-
Save qbig/c103efa1c24de58114e8e179eb02c329 to your computer and use it in GitHub Desktop.
Go-ethereum create utility functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package util | |
import ( | |
"math/big" | |
"reflect" | |
"regexp" | |
"strconv" | |
"github.com/ethereum/go-ethereum/common" | |
"github.com/ethereum/go-ethereum/common/hexutil" | |
"github.com/shopspring/decimal" | |
) | |
// IsValidAddress validate hex address | |
func IsValidAddress(iaddress interface{}) bool { | |
re := regexp.MustCompile("^0x[0-9a-fA-F]{40}$") | |
switch v := iaddress.(type) { | |
case string: | |
return re.MatchString(v) | |
case common.Address: | |
return re.MatchString(v.Hex()) | |
default: | |
return false | |
} | |
} | |
// IsZeroAddress validate if it's a 0 address | |
func IsZeroAddress(iaddress interface{}) bool { | |
var address common.Address | |
switch v := iaddress.(type) { | |
case string: | |
address = common.HexToAddress(v) | |
case common.Address: | |
address = v | |
default: | |
return false | |
} | |
zeroAddressBytes := common.FromHex("0x0000000000000000000000000000000000000000") | |
addressBytes := address.Bytes() | |
return reflect.DeepEqual(addressBytes, zeroAddressBytes) | |
} | |
// ToDecimal wei to decimals | |
func ToDecimal(ivalue interface{}, decimals int) decimal.Decimal { | |
value := new(big.Int) | |
switch v := ivalue.(type) { | |
case string: | |
value.SetString(v, 10) | |
case *big.Int: | |
value = v | |
} | |
mul := decimal.NewFromFloat(float64(10)).Pow(decimal.NewFromFloat(float64(decimals))) | |
num, _ := decimal.NewFromString(value.String()) | |
result := num.Div(mul) | |
return result | |
} | |
// ToWei decimals to wei | |
func ToWei(iamount interface{}, decimals int) *big.Int { | |
amount := decimal.NewFromFloat(0) | |
switch v := iamount.(type) { | |
case string: | |
amount, _ = decimal.NewFromString(v) | |
case float64: | |
amount = decimal.NewFromFloat(v) | |
case int64: | |
amount = decimal.NewFromFloat(float64(v)) | |
case decimal.Decimal: | |
amount = v | |
case *decimal.Decimal: | |
amount = *v | |
} | |
mul := decimal.NewFromFloat(float64(10)).Pow(decimal.NewFromFloat(float64(decimals))) | |
result := amount.Mul(mul) | |
wei := new(big.Int) | |
wei.SetString(result.String(), 10) | |
return wei | |
} | |
// CalcGasCost calculate gas cost given gas limit (units) and gas price (wei) | |
func CalcGasCost(gasLimit uint64, gasPrice *big.Int) *big.Int { | |
gasLimitBig := big.NewInt(int64(gasLimit)) | |
return gasLimitBig.Mul(gasLimitBig, gasPrice) | |
} | |
// SigRSV signatures R S V returned as arrays | |
func SigRSV(isig interface{}) ([32]byte, [32]byte, uint8) { | |
var sig []byte | |
switch v := isig.(type) { | |
case []byte: | |
sig = v | |
case string: | |
sig, _ = hexutil.Decode(v) | |
} | |
sigstr := common.Bytes2Hex(sig) | |
rS := sigstr[0:64] | |
sS := sigstr[64:128] | |
R := [32]byte{} | |
S := [32]byte{} | |
copy(R[:], common.FromHex(rS)) | |
copy(S[:], common.FromHex(sS)) | |
vStr := sigstr[128:130] | |
vI, _ := strconv.Atoi(vStr) | |
V := uint8(vI + 27) | |
return R, S, V | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package util | |
import ( | |
"math/big" | |
"testing" | |
"github.com/ethereum/go-ethereum/common" | |
"github.com/ethereum/go-ethereum/common/hexutil" | |
"github.com/shopspring/decimal" | |
) | |
func TestIsValidAddress(t *testing.T) { | |
t.Parallel() | |
validAddress := "0x323b5d4c32345ced77393b3530b1eed0f346429d" | |
invalidAddress := "0xabc" | |
invalidAddress2 := "323b5d4c32345ced77393b3530b1eed0f346429d" | |
{ | |
got := IsValidAddress(validAddress) | |
expected := true | |
if got != expected { | |
t.Errorf("Expected %v, got %v", expected, got) | |
} | |
} | |
{ | |
got := IsValidAddress(invalidAddress) | |
expected := false | |
if got != expected { | |
t.Errorf("Expected %v, got %v", expected, got) | |
} | |
} | |
{ | |
got := IsValidAddress(invalidAddress2) | |
expected := false | |
if got != expected { | |
t.Errorf("Expected %v, got %v", expected, got) | |
} | |
} | |
} | |
func TestIsZeroAddress(t *testing.T) { | |
t.Parallel() | |
validAddress := common.HexToAddress("0x323b5d4c32345ced77393b3530b1eed0f346429d") | |
zeroAddress := common.HexToAddress("0x0000000000000000000000000000000000000000") | |
{ | |
isZeroAddress := IsZeroAddress(validAddress) | |
if isZeroAddress { | |
t.Error("Expected to be false") | |
} | |
} | |
{ | |
isZeroAddress := IsZeroAddress(zeroAddress) | |
if !isZeroAddress { | |
t.Error("Expected to be true") | |
} | |
} | |
{ | |
isZeroAddress := IsZeroAddress(validAddress.Hex()) | |
if isZeroAddress { | |
t.Error("Expected to be false") | |
} | |
} | |
{ | |
isZeroAddress := IsZeroAddress(zeroAddress.Hex()) | |
if !isZeroAddress { | |
t.Error("Expected to be true") | |
} | |
} | |
} | |
func TestToWei(t *testing.T) { | |
t.Parallel() | |
amount := decimal.NewFromFloat(0.02) | |
got := ToWei(amount, 18) | |
expected := new(big.Int) | |
expected.SetString("20000000000000000", 10) | |
if got.Cmp(expected) != 0 { | |
t.Errorf("Expected %s, got %s", expected, got) | |
} | |
} | |
func TestToDecimal(t *testing.T) { | |
t.Parallel() | |
weiAmount := big.NewInt(0) | |
weiAmount.SetString("20000000000000000", 10) | |
ethAmount := ToDecimal(weiAmount, 18) | |
f64, _ := ethAmount.Float64() | |
expected := 0.02 | |
if f64 != expected { | |
t.Errorf("%v does not equal expected %v", ethAmount, expected) | |
} | |
} | |
func TestCalcGasLimit(t *testing.T) { | |
t.Parallel() | |
gasPrice := big.NewInt(0) | |
gasPrice.SetString("2000000000", 10) | |
gasLimit := uint64(21000) | |
expected := big.NewInt(0) | |
expected.SetString("42000000000000", 10) | |
gasCost := CalcGasCost(gasLimit, gasPrice) | |
if gasCost.Cmp(expected) != 0 { | |
t.Errorf("expected %s, got %s", gasCost, expected) | |
} | |
} | |
func TestSigRSV(t *testing.T) { | |
t.Parallel() | |
sig := "0x789a80053e4927d0a898db8e065e948f5cf086e32f9ccaa54c1908e22ac430c62621578113ddbb62d509bf6049b8fb544ab06d36f916685a2eb8e57ffadde02301" | |
r, s, v := SigRSV(sig) | |
expectedR := "789a80053e4927d0a898db8e065e948f5cf086e32f9ccaa54c1908e22ac430c6" | |
expectedS := "2621578113ddbb62d509bf6049b8fb544ab06d36f916685a2eb8e57ffadde023" | |
expectedV := uint8(28) | |
if hexutil.Encode(r[:])[2:] != expectedR { | |
t.FailNow() | |
} | |
if hexutil.Encode(s[:])[2:] != expectedS { | |
t.FailNow() | |
} | |
if v != expectedV { | |
t.FailNow() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment