{-# Language DataKinds #-}
module EVM.Concrete where
import Prelude hiding (Word)
import EVM.RLP
import EVM.Types
import Data.ByteString (ByteString)
import Data.ByteString qualified as BS
import Witch (unsafeInto, into)
byteStringSliceWithDefaultZeroes :: Int -> Int -> ByteString -> ByteString
byteStringSliceWithDefaultZeroes :: Int -> Int -> ByteString -> ByteString
byteStringSliceWithDefaultZeroes Int
offset Int
size ByteString
bs =
if Int
size Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then ByteString
""
else
let bs' :: ByteString
bs' = Int -> ByteString -> ByteString
BS.take Int
size (Int -> ByteString -> ByteString
BS.drop Int
offset ByteString
bs)
in ByteString
bs' ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> Int -> Word8 -> ByteString
BS.replicate (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
BS.length ByteString
bs') Word8
0
sliceMemory :: W256 -> W256 -> ByteString -> ByteString
sliceMemory :: W256 -> W256 -> ByteString -> ByteString
sliceMemory W256
o W256
s =
Int -> Int -> ByteString -> ByteString
byteStringSliceWithDefaultZeroes (W256 -> Int
forall target source.
(HasCallStack, TryFrom source target, Show source, Typeable source,
Typeable target) =>
source -> target
unsafeInto W256
o) (W256 -> Int
forall target source.
(HasCallStack, TryFrom source target, Show source, Typeable source,
Typeable target) =>
source -> target
unsafeInto W256
s)
writeMemory :: ByteString -> W256 -> W256 -> W256 -> ByteString -> ByteString
writeMemory :: ByteString -> W256 -> W256 -> W256 -> ByteString -> ByteString
writeMemory ByteString
bs1 W256
n W256
src W256
dst ByteString
bs0 =
let
(ByteString
a, ByteString
b) = Int -> ByteString -> (ByteString, ByteString)
BS.splitAt (W256 -> Int
forall target source.
(HasCallStack, TryFrom source target, Show source, Typeable source,
Typeable target) =>
source -> target
unsafeInto W256
dst) ByteString
bs0
a' :: ByteString
a' = Int -> Word8 -> ByteString
BS.replicate (W256 -> Int
forall target source.
(HasCallStack, TryFrom source target, Show source, Typeable source,
Typeable target) =>
source -> target
unsafeInto W256
dst Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
BS.length ByteString
a) Word8
0
c :: ByteString
c = if W256
src W256 -> W256 -> Bool
forall a. Ord a => a -> a -> Bool
> Int -> W256
forall target source.
(HasCallStack, TryFrom source target, Show source, Typeable source,
Typeable target) =>
source -> target
unsafeInto (ByteString -> Int
BS.length ByteString
bs1)
then Int -> Word8 -> ByteString
BS.replicate (W256 -> Int
forall target source.
(HasCallStack, TryFrom source target, Show source, Typeable source,
Typeable target) =>
source -> target
unsafeInto W256
n) Word8
0
else W256 -> W256 -> ByteString -> ByteString
sliceMemory W256
src W256
n ByteString
bs1
b' :: ByteString
b' = Int -> ByteString -> ByteString
BS.drop (W256 -> Int
forall target source.
(HasCallStack, TryFrom source target, Show source, Typeable source,
Typeable target) =>
source -> target
unsafeInto W256
n) ByteString
b
in
ByteString
a ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
a' ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
c ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
b'
createAddress :: Addr -> W64 -> Expr EAddr
createAddress :: Addr -> W64 -> Expr 'EAddr
createAddress Addr
a W64
n = Addr -> Expr 'EAddr
LitAddr (Addr -> Expr 'EAddr) -> ([RLP] -> Addr) -> [RLP] -> Expr 'EAddr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. W256 -> Addr
forall target source.
(HasCallStack, TryFrom source target, Show source, Typeable source,
Typeable target) =>
source -> target
unsafeInto (W256 -> Addr) -> ([RLP] -> W256) -> [RLP] -> Addr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> W256
keccak' (ByteString -> W256) -> ([RLP] -> ByteString) -> [RLP] -> W256
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [RLP] -> ByteString
rlpList ([RLP] -> Expr 'EAddr) -> [RLP] -> Expr 'EAddr
forall a b. (a -> b) -> a -> b
$ [Addr -> RLP
rlpAddrFull Addr
a, W256 -> RLP
rlpWord256 (W64 -> W256
forall target source. From source target => source -> target
into W64
n)]
create2Address :: Addr -> W256 -> ByteString -> Expr EAddr
create2Address :: Addr -> W256 -> ByteString -> Expr 'EAddr
create2Address Addr
a W256
s ByteString
b = Addr -> Expr 'EAddr
LitAddr (Addr -> Expr 'EAddr) -> Addr -> Expr 'EAddr
forall a b. (a -> b) -> a -> b
$ W256 -> Addr
forall target source.
(HasCallStack, TryFrom source target, Show source, Typeable source,
Typeable target) =>
source -> target
unsafeInto (W256 -> Addr) -> W256 -> Addr
forall a b. (a -> b) -> a -> b
$ ByteString -> W256
keccak' (ByteString -> W256) -> ByteString -> W256
forall a b. (a -> b) -> a -> b
$ [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
[Word8 -> ByteString
BS.singleton Word8
0xff, Addr -> ByteString
word160Bytes Addr
a, W256 -> ByteString
word256Bytes W256
s, W256 -> ByteString
word256Bytes (W256 -> ByteString) -> W256 -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> W256
keccak' ByteString
b]