github.com/annchain/OG@v0.0.9/og_interface/address20.go (about)

     1  package og_interface
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"encoding/binary"
     6  	"fmt"
     7  	ogCrypto "github.com/annchain/OG/ogcrypto"
     8  	"github.com/annchain/commongo/hexutil"
     9  	"github.com/annchain/commongo/marshaller"
    10  	"github.com/annchain/commongo/math"
    11  	"github.com/annchain/commongo/utilfuncs"
    12  	"math/big"
    13  	"math/rand"
    14  )
    15  
    16  const (
    17  	Address20Length = 20
    18  )
    19  
    20  type Address20 struct {
    21  	hex string
    22  	b   [Address20Length]byte
    23  }
    24  
    25  func (a *Address20) AddressKey() AddressKey {
    26  	return AddressKey(a.hex)
    27  }
    28  
    29  func (a *Address20) AddressShortString() string {
    30  	return hexutil.ToHex(a.b[:10])
    31  }
    32  
    33  func (a *Address20) AddressString() string {
    34  	return a.hex
    35  }
    36  
    37  func (a *Address20) Bytes() []byte {
    38  	return a.b[:]
    39  }
    40  
    41  func (a *Address20) Big() *big.Int {
    42  	return new(big.Int).SetBytes(a.Bytes())
    43  }
    44  
    45  func (a *Address20) Hex() string {
    46  	return a.hex
    47  }
    48  
    49  func (a *Address20) Length() int {
    50  	return Address20Length
    51  }
    52  
    53  func (a *Address20) FromBytes(b []byte) {
    54  	a.hex = hexutil.ToHex(b)
    55  	copy(a.b[:], b)
    56  }
    57  
    58  func (a *Address20) FromHex(s string) (err error) {
    59  	bytes, err := hexutil.FromHex(s)
    60  	if err != nil {
    61  		return
    62  	}
    63  	a.hex = s
    64  	copy(a.b[:], bytes)
    65  	return
    66  }
    67  
    68  func (a *Address20) FromHexNoError(s string) {
    69  	err := a.FromHex(s)
    70  	utilfuncs.PanicIfError(err, "HexToAddress20")
    71  }
    72  
    73  func (a *Address20) Cmp(another FixLengthBytes) int {
    74  	return BytesCmp(a, another)
    75  }
    76  
    77  /**
    78  marshaller part
    79  */
    80  
    81  func (a *Address20) MarshalMsg() ([]byte, error) {
    82  	data := marshaller.InitIMarshallerBytes(a.MsgSize())
    83  	data, pos := marshaller.EncodeHeader(data, 0, a.MsgSize())
    84  
    85  	// add lead
    86  	data[pos] = FlagAddress20
    87  	// add hash data
    88  	copy(data[pos+1:], a.b[:])
    89  	return data, nil
    90  }
    91  
    92  func (a *Address20) UnmarshalMsg(b []byte) ([]byte, error) {
    93  	b, msgLen, err := marshaller.DecodeHeader(b)
    94  	if err != nil {
    95  		return b, fmt.Errorf("get marshaller header error: %v", err)
    96  	}
    97  
    98  	msgSize := a.MsgSize()
    99  	if len(b) < msgSize || msgLen != msgSize {
   100  		return b, fmt.Errorf("bytes not enough for hash32, should be: %d, get: %d, msgLen: %d", msgSize, len(b), msgLen)
   101  	}
   102  	lead := b[0]
   103  	if lead != FlagAddress20 {
   104  		return b, fmt.Errorf("hash lead error, should be: %x, get: %x", FlagAddress20, lead)
   105  	}
   106  	b = b[1:]
   107  
   108  	copy(a.b[:], b[:FlagAddress20])
   109  	return b[FlagAddress20:], nil
   110  }
   111  
   112  func (a *Address20) MsgSize() int {
   113  	return 1 + Address20Length
   114  }
   115  
   116  func BytesToAddress20(b []byte) *Address20 {
   117  	a := &Address20{}
   118  	a.FromBytes(b)
   119  	return a
   120  }
   121  
   122  func HexToAddress20(hex string) (*Address20, error) {
   123  	a := &Address20{}
   124  	err := a.FromHex(hex)
   125  	return a, err
   126  }
   127  
   128  func BigToAddress20(v *big.Int) *Address20 {
   129  	a := &Address20{}
   130  	a.FromBytes(v.Bytes())
   131  	return a
   132  }
   133  
   134  func RandomAddress20() *Address20 {
   135  	v := math.NewBigInt(rand.Int63())
   136  	adr := BigToAddress20(v.Value)
   137  	h := sha256.New()
   138  	data := []byte("abcd8342804fhddhfhisfdyr89")
   139  	h.Write(adr.b[:])
   140  	h.Write(data)
   141  	sum := h.Sum(nil)
   142  	adr.FromBytes(sum[:20])
   143  	return adr
   144  }
   145  
   146  // CreateAddress creates an address20 given the bytes and the nonce
   147  func CreateAddress20(b Address20, nonce uint64) Address20 {
   148  	bs := make([]byte, 8)
   149  	binary.LittleEndian.PutUint64(bs, nonce)
   150  	addr := BytesToAddress20(ogCrypto.Keccak256([]byte{0xff}, b.Bytes()[:], bs)[12:])
   151  	return *addr
   152  }
   153  
   154  // CreateAddress2 creates an address20 given the address bytes, initial
   155  // contract code hash and a salt.
   156  func CreateAddress20_2(b Address20, salt Hash32, inithash []byte) Address20 {
   157  	addr := BytesToAddress20(ogCrypto.Keccak256([]byte{0xff}, b.Bytes()[:], salt[:], inithash)[12:])
   158  	return *addr
   159  }