github.com/onflow/flow-go@v0.33.17/fvm/evm/handler/addressAllocator.go (about) 1 package handler 2 3 import ( 4 "encoding/binary" 5 6 "github.com/onflow/atree" 7 8 "github.com/onflow/flow-go/fvm/evm/types" 9 "github.com/onflow/flow-go/model/flow" 10 ) 11 12 const ledgerAddressAllocatorKey = "AddressAllocator" 13 14 type AddressAllocator struct { 15 led atree.Ledger 16 flexAddress flow.Address 17 } 18 19 var _ types.AddressAllocator = &AddressAllocator{} 20 21 // NewAddressAllocator constructs a new statefull address allocator 22 func NewAddressAllocator(led atree.Ledger, flexAddress flow.Address) (*AddressAllocator, error) { 23 return &AddressAllocator{ 24 led: led, 25 flexAddress: flexAddress, 26 }, nil 27 } 28 29 // AllocateAddress allocates an address 30 func (aa *AddressAllocator) AllocateAddress() (types.Address, error) { 31 data, err := aa.led.GetValue(aa.flexAddress[:], []byte(ledgerAddressAllocatorKey)) 32 if err != nil { 33 return types.Address{}, err 34 } 35 // default value for uuid is 1 36 uuid := uint64(1) 37 if len(data) > 0 { 38 uuid = binary.BigEndian.Uint64(data) 39 } 40 41 target := types.Address{} 42 // first 12 bytes would be zero 43 // the next 8 bytes would be an increment of the UUID index 44 binary.BigEndian.PutUint64(target[12:], uuid) 45 46 // store new uuid 47 newData := make([]byte, 8) 48 binary.BigEndian.PutUint64(newData, uuid+1) 49 err = aa.led.SetValue(aa.flexAddress[:], []byte(ledgerAddressAllocatorKey), newData) 50 if err != nil { 51 return types.Address{}, err 52 } 53 54 return target, nil 55 }