test (does not work !!)

pull/333/head
Will Song 5 years ago
parent 35319e8d5d
commit 413f97266b
  1. BIN
      examples/basic_multicontract/.export.json.swp
  2. 22
      examples/basic_multicontract/LICENSE
  3. 1360
      examples/basic_multicontract/build/contracts/Bar.json
  4. 1380
      examples/basic_multicontract/build/contracts/Foo.json
  5. 1400
      examples/basic_multicontract/build/contracts/Migrations.json
  6. 1
      examples/basic_multicontract/contracts/.placeholder
  7. 10
      examples/basic_multicontract/contracts/Bar.sol
  8. 25
      examples/basic_multicontract/contracts/Foo.sol
  9. 23
      examples/basic_multicontract/contracts/Migrations.sol
  10. 2
      examples/basic_multicontract/echidna_config.yaml
  11. 17
      examples/basic_multicontract/export.json
  12. 5
      examples/basic_multicontract/migrations/1_initial_migration.js
  13. 8
      examples/basic_multicontract/migrations/2_deploy_contracts.js
  14. 1
      examples/basic_multicontract/test/.placeholder
  15. 26
      examples/basic_multicontract/truffle-config.js
  16. 280
      lib/Echidna/RPC.hs
  17. 8
      lib/Echidna/Solidity.hs
  18. 2
      package.yaml

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2018 Truffle
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1 @@
This is a placeholder file to ensure the parent directory in the git repository. Feel free to remove.

@ -0,0 +1,10 @@
pragma solidity >=0.4.25 <0.6.0;
contract Bar {
constructor() public {}
function test() public pure returns (uint) {
return 1;
}
}

@ -0,0 +1,25 @@
pragma solidity >=0.4.25 <0.6.0;
contract Bar {
function test() public pure returns (uint) {}
}
contract Foo {
Bar bar;
uint isOne;
constructor(address _bar) public {
bar = Bar(_bar);
//bar = new Bar();
isOne = 0;
}
function callBar() public {
isOne = bar.test();
}
function echidna_test() public view returns (bool) {
bar.test();
return isOne == 0;
}
}

@ -0,0 +1,23 @@
pragma solidity >=0.4.25 <0.6.0;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
constructor() public {
owner = msg.sender;
}
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) public restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}

@ -0,0 +1,2 @@
contractAddr: "0x12342"
initialize: "./examples/basic_multicontract/export.json"

@ -0,0 +1,17 @@
[
{"event": "AccountCreated", "address": "9bc0895dc163e5dc83f9654186c9ee60b7736f1a"},
{"event": "AccountCreated", "address": "b4a07ad03011e7afa37e80890cfbab65960988b6"},
{"event": "AccountCreated", "address": "b0d71bcbcca8d1c4c2cb0ab4bae6d951f035e577"},
{"event": "AccountCreated", "address": "e498baf98383a8c0cb2a3ff8002cf4ca6c5295b8"},
{"event": "AccountCreated", "address": "907128412912321ea7a01ef1d1196588b01cb98b"},
{"event": "AccountCreated", "address": "93a3cda86dbb1b5dccd6f6719e5030dd65b267b4"},
{"event": "AccountCreated", "address": "7a3a17fbebbaa1a9576845f31a07ef5be353f71d"},
{"event": "AccountCreated", "address": "7fae60090e87dd649074938432e1d0af3f8fbcf9"},
{"event": "AccountCreated", "address": "45d33bed8871017e7b1fbd22a1dd47faeb1d914a"},
{"event": "AccountCreated", "address": "57da5aaf5de3ff574ffbd8cb3a4885238a926616"},
{"event": "ContractCreated", "from": "0x9bc0895dc163e5dc83f9654186c9ee60b7736f1a", "contract_address": "0xf02e7bc30fdcc89826547b09303a253c85a68784", "gas_used": "0x43bd6", "gas_price": "0x4a817c800", "data": "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102f8806100606000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100aa5780638da5cb5b146100d5578063fdacd5761461012c575b600080fd5b34801561007357600080fd5b506100a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610159565b005b3480156100b657600080fd5b506100bf610241565b6040518082815260200191505060405180910390f35b3480156100e157600080fd5b506100ea610247565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561013857600080fd5b506101576004803603810190808035906020019092919050505061026c565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561023d578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b505050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102c957806001819055505b505600a165627a7a72305820b27f3ee844fe76b108178ff61c03c5e1962752f695e0f1a3d1dc51c983c241310029", "value": "0x0"},
{"event": "FunctionCall", "from": "0x9bc0895dc163e5dc83f9654186c9ee60b7736f1a", "to": "0xf02e7bc30fdcc89826547b09303a253c85a68784", "gas_used": "0xa418", "gas_price": "0x4a817c800", "data": "0xfdacd5760000000000000000000000000000000000000000000000000000000000000001", "value": "0x0"},
{"event": "ContractCreated", "from": "0x9bc0895dc163e5dc83f9654186c9ee60b7736f1a", "contract_address": "0x2b1a87cac755d503e968296e19ccbd21da46462f", "gas_used": "0x171ed", "gas_price": "0x4a817c800", "data": "0x6080604052348015600f57600080fd5b50609d8061001e6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063f8a8fd6d146044575b600080fd5b348015604f57600080fd5b506056606c565b6040518082815260200191505060405180910390f35b6000905600a165627a7a72305820fc76e4cc480ddc19670a05f11d40cca4bc0d260e9defbadaca10785b81cd16b60029", "value": "0x0"},
{"event": "ContractCreated", "from": "0x9bc0895dc163e5dc83f9654186c9ee60b7736f1a", "contract_address": "0xc7a351e329e286f3b46dc8ab9ad82db6dc27daa1", "gas_used": "0x3b31c", "gas_price": "0x4a817c800", "data": "0x608060405234801561001057600080fd5b506040516020806102e483398101806040528101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600181905550506102598061008b6000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806317bf8bac14610051578063acffee6b14610080575b600080fd5b34801561005d57600080fd5b50610066610097565b604051808215151515815260200191505060405180910390f35b34801561008c57600080fd5b50610095610165565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f8a8fd6d6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561011e57600080fd5b505af1158015610132573d6000803e3d6000fd5b505050506040513d602081101561014857600080fd5b810190808051906020019092919050505050600060015414905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f8a8fd6d6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156101ea57600080fd5b505af11580156101fe573d6000803e3d6000fd5b505050506040513d602081101561021457600080fd5b81019080805190602001909291905050506001819055505600a165627a7a7230582064bd2903f96a9a349e15dd6aad759df3d037ca5f5f2eb800af9a5467a935fa0900290000000000000000000000002b1a87cac755d503e968296e19ccbd21da46462f", "value": "0x0"},
{"event": "FunctionCall", "from": "0x9bc0895dc163e5dc83f9654186c9ee60b7736f1a", "to": "0xf02e7bc30fdcc89826547b09303a253c85a68784", "gas_used": "0x6980", "gas_price": "0x4a817c800", "data": "0xfdacd5760000000000000000000000000000000000000000000000000000000000000002", "value": "0x0"}
]

@ -0,0 +1,5 @@
const Migrations = artifacts.require("Migrations");
module.exports = function(deployer) {
deployer.deploy(Migrations);
};

@ -0,0 +1,8 @@
const Foo = artifacts.require("Foo");
const Bar = artifacts.require("Bar");
module.exports = function(deployer) {
deployer.deploy(Bar).then(function() {
return deployer.deploy(Foo, Bar.address);
});
};

@ -0,0 +1 @@
This is a placeholder file to ensure the parent directory in the git repository. Feel free to remove.

@ -0,0 +1,26 @@
module.exports = {
// Uncommenting the defaults below
// provides for an easier quick-start with Ganache.
// You can also follow this format for other networks;
// see <http://truffleframework.com/docs/advanced/configuration>
// for more details on how to specify configuration options!
/*
networks: {
development: {
host: "127.0.0.1",
port: 7545,
network_id: "*"
},
test: {
host: "127.0.0.1",
port: 7545,
network_id: "*"
}
}
*/
compilers: {
solc: {
version: "0.4.25"
},
},
};

@ -1,117 +1,181 @@
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Echidna.RPC where
import Prelude hiding (Word)
import Control.Exception (Exception)
import Control.Lens
import Control.Monad (foldM)
import Control.Monad.Catch (MonadThrow, throwM)
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.State.Strict (MonadState, execState, execStateT, get, put, runState)
import Data.Aeson (FromJSON(..), defaultOptions, eitherDecodeFileStrict, genericParseJSON, omitNothingFields)
import Data.ByteString (ByteString, empty)
import Data.Has (Has(..))
import Data.List (partition)
import Data.Text.Encoding (encodeUtf8)
import EVM
import EVM.Concrete (w256)
import EVM.Exec (exec, vmForEthrunCreation)
import EVM.Types (Addr, W256)
import GHC.Generics
import qualified Control.Monad.State.Strict as S (state)
import qualified Data.Text as T
import Echidna.Exec
import Echidna.Transaction
-- | During initialization we can either call a function or create an account or contract
data EthenoEvent = AccountCreated | ContractCreated | FunctionCall deriving(Eq, Show, Generic)
instance FromJSON EthenoEvent
-- | A single initialization event
data Etheno = Etheno { _event :: !EthenoEvent
, _address :: !Addr
, _from :: !Addr
, _to :: !Addr
, _contractAddr :: !Addr
, _gasUsed :: !Integer
, _gasPrice :: !Integer
, _initCode :: !T.Text
, _value :: !W256
} deriving (Eq, Show, Generic)
makeLenses ''Etheno
instance FromJSON Etheno where
parseJSON = genericParseJSON $ defaultOptions{omitNothingFields = True}
-- | Handler for parsing errors
data EthenoException = EthenoException String
instance Show EthenoException where
show (EthenoException e) = "Error parsing Etheno initialization file: " ++ e
instance Exception EthenoException
-- | Main function: takes a filepath where the initialization sequence lives and returns
-- | the initialized VM along with a list of Addr's to put in GenConf
loadEthenoBatch :: (MonadThrow m, MonadIO m) => ByteString -> FilePath -> m (VM, [Addr])
loadEthenoBatch echidnaInit fp = do
bs <- liftIO $ eitherDecodeFileStrict fp
case bs of
(Left e) -> throwM $ EthenoException e
(Right ethenoInit) -> do
-- | Separate out account creation txns to use later for config
let (accounts, txs) = partition (\t -> t ^. event == AccountCreated) ethenoInit
knownAddrs = map (\e -> e ^. address) accounts
-- | Execute contract creations and initial transactions,
let blank = vmForEthrunCreation empty
initVM = foldM (execEthenoTxs echidnaInit) 0x0 txs >>= liftSH . loadContract
vm <- execStateT initVM blank
import Prelude hiding (Word)
import Debug.Trace (traceShow, trace)
import Control.Exception (Exception)
import Control.Lens
import Control.Monad (foldM)
import Control.Monad.Catch (MonadThrow, throwM)
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.State.Strict (MonadState, execState, execStateT, runStateT, get, put, runState)
import Data.Aeson (FromJSON(..), (.:), withObject, eitherDecodeFileStrict)
import Data.ByteString.Char8 (ByteString, empty, unpack)
import Data.Has (Has(..))
import Data.List (partition)
import Data.Map (fromList)
import Data.Text.Encoding (encodeUtf8)
import EVM
import EVM.Concrete (w256)
import EVM.Exec (exec, vmForEthrunCreation)
import EVM.Types (Addr, W256)
import qualified Control.Monad.Fail as M (MonadFail(..))
import qualified Control.Monad.State.Strict as S (state)
import qualified Data.ByteString.Base16 as BS16 (decode, encode)
import qualified Data.Text as T (Text, drop)
import Echidna.Exec
import Echidna.Transaction
-- | During initialization we can either call a function or create an account or contract
--data EthenoEvent = AccountCreated | ContractCreated | FunctionCall deriving(Eq, Show, Generic)
--instance FromJSON EthenoEvent
-- | A single initialization event
--data Etheno = Etheno { _event :: !EthenoEvent
-- , _address :: Maybe Addr
-- , _from :: Maybe Addr
-- , _to :: Maybe Addr
-- , _contractAddr :: Maybe Addr
-- , _gasUsed :: Maybe Integer
-- , _gasPrice :: Maybe Integer
-- , _initCode :: Maybe T.Text
-- , _value :: Maybe W256
-- } deriving (Eq, Show, Generic)
data Etheno = AccountCreated Addr
| ContractCreated Addr Addr Integer Integer ByteString W256
| FunctionCall Addr Addr Integer Integer ByteString W256
deriving (Eq, Show)
--makeLenses ''Etheno
instance FromJSON Etheno where
-- parseJSON = genericParseJSON $ defaultOptions {fieldLabelModifier = tail, omitNothingFields = True}
parseJSON = withObject "Etheno" $ \v -> do
(ev :: String) <- v .: "event"
case ev of
"AccountCreated" -> AccountCreated <$> v .: "address"
"ContractCreated" -> ContractCreated <$> v .: "from"
<*> v .: "contract_address"
<*> (read <$> (v .: "gas_used"))
<*> (read <$> (v .: "gas_price"))
<*> (decode <$> (v .: "data"))
<*> v .: "value"
"FunctionCall" -> FunctionCall <$> v .: "from"
<*> v .: "to"
<*> (read <$> (v .: "gas_used"))
<*> (read <$> (v .: "gas_price"))
<*> (decode <$> (v .: "data"))
<*> v .: "value"
_ -> M.fail "event should be one of \"AccountCreated\", \"ContractCreated\", or \"FunctionCall\""
where decode :: T.Text -> ByteString
decode = decodeHex . encodeUtf8 . T.drop 2
decodeHex = fst . BS16.decode
-- | Handler for parsing errors
data EthenoException = EthenoException String
instance Show EthenoException where
show (EthenoException e) = "Error parsing Etheno initialization file: " ++ e
instance Exception EthenoException
-- | Main function: takes a filepath where the initialization sequence lives and returns
-- | the initialized VM along with a list of Addr's to put in GenConf
loadEthenoBatch :: (MonadThrow m, MonadIO m) => [T.Text] -> FilePath -> m (VM, [Addr])
loadEthenoBatch ts fp = do
bs <- liftIO $ eitherDecodeFileStrict fp
case bs of
(Left e) -> throwM $ EthenoException e
(Right ethenoInit) -> do
-- | Separate out account creation txns to use later for config
let (accounts, txs) = partition (\case { AccountCreated{} -> True; _ -> False; }) ethenoInit
knownAddrs = map (\(AccountCreated a) -> a) accounts
-- | Execute contract creations and initial transactions,
let blank = vmForEthrunCreation empty & env . contracts .~ fromList []
cs = blank ^. env . contracts
initVM = foldM (execEthenoTxs ts) Nothing txs
liftIO $ print (length cs)
-- liftIO $ print $ view contractcode <$> cs
liftIO $ putStrLn "---"
(addr, vm') <- runStateT initVM blank
let cs' = vm' ^. env . contracts
liftIO $ print (length cs')
-- liftIO $ print $ view contractcode <$> cs'
liftIO $ putStrLn "done loading"
liftIO $ print ts
case addr of
Nothing -> throwM $ EthenoException "Could not find contract with echidna tests"
Just a -> do
liftIO $ putStrLn $ "found echidna at " ++ show addr
vm <- execStateT (liftSH . loadContract $ a) vm'
return (vm, knownAddrs)
-- | Takes a list of Etheno transactions and loads them into the VM, returning the
-- | address containing echidna tests
execEthenoTxs :: (MonadState x m, Has VM x, MonadThrow m) => ByteString -> Addr -> Etheno -> m Addr
execEthenoTxs bs addr t = do
og <- get
setupEthenoTx t
res <- liftSH exec
case (res, t ^. event == ContractCreated) of
(Reversion, _) -> put og
(VMFailure x, _) -> vmExcept x
(VMSuccess bc, True) -> hasLens %= execState ( replaceCodeOfSelf (RuntimeCode bc)
>> loadContract (t ^. contractAddr))
_ -> pure ()
-- See if current contract is the same as echidna test
if t ^. event == ContractCreated && encodeUtf8 (t ^. initCode) == bs
then return (t ^. contractAddr)
else return addr
-- | For an etheno txn, set up VM to execute txn
setupEthenoTx :: (MonadState x m, Has VM x) => Etheno -> m ()
setupEthenoTx (Etheno e _ f t c _ _ d v) = S.state . runState . zoom hasLens . sequence_ $
[ result .= Nothing, state . pc .= 0, state . stack .= mempty, state . gas .= 0xffffffff
, tx . origin .= f, state . caller .= f, state . callvalue .= w256 v, setup] where
bc = encodeUtf8 d
setup = case e of
AccountCreated -> pure ()
ContractCreated -> assign (env . contracts . at c) (Just . initialContract . RuntimeCode $ bc) >> loadContract c
FunctionCall -> loadContract t >> state . calldata .= bc
-- | Takes a list of Etheno transactions and loads them into the VM, returning the
-- | address containing echidna tests
execEthenoTxs :: (MonadState x m, Has VM x, MonadThrow m) => [T.Text] -> Maybe Addr -> Etheno -> m (Maybe Addr)
execEthenoTxs ts addr t = do
og <- get
setupEthenoTx t
res <- liftSH exec
case (res, t) of
(Reversion, _) -> throwM $ EthenoException "Encountered reversion while setting up Etheno transactions"
(VMFailure x, _) -> vmExcept x >> return addr
(VMSuccess bc,
ContractCreated _ ca _ _ _ _) ->
-- See if current contract is the same as echidna test
case addr of
Just m -> return $ Just m
Nothing -> let txs = ts <&> \t -> Tx (Left (t, [])) ca ca 0
go [] = return $ Just ca
go (x:xs) = execTx x >>= \case
Reversion -> return Nothing
_ -> go xs in
go txs
-- hasLens %= execState (replaceCodeOfSelf (RuntimeCode bc) >> loadContract ca)
_ -> return addr
--if t ^. event == ContractCreated && encodeUtf8 (fromJustt (t ^. initCode)) == bs
-- then return (fromJust (t ^. contractAddr))
-- else return addr
-- | For an etheno txn, set up VM to execute txn
setupEthenoTx :: (MonadState x m, Has VM x) => Etheno -> m ()
setupEthenoTx (AccountCreated _) = pure ()
setupEthenoTx (ContractCreated f c _ _ d v) = S.state . runState . zoom hasLens . sequence_ $
[ result .= Nothing, state . pc .= 0, state . stack .= mempty, state . gas .= 0xffffffff
, tx . origin .= f, state . caller .= f, state . callvalue .= w256 v, setup]
where setup = assign (env . contracts . at (traceShow c c)) (Just . initialContract . RuntimeCode $ trace ("bc: " ++ (unpack $ BS16.encode d)) d)
--setup = do
-- env . contracts . at c .= Just . initialContract . RuntimeCode . encodeUtf8 $ d
-- loadContract c
setupEthenoTx (FunctionCall f t _ _ d v) = S.state . runState . zoom hasLens . sequence_ $
[ result .= Nothing, state . pc .= 0, state . stack .= mempty, state . gas .= 0xffffffff
, tx . origin .= f, state . caller .= f, state . callvalue .= w256 v, setup]
where setup = loadContract (traceShow t t) >> state . calldata .= d
--setupEthenoTx FunctionCall{} = pure ()
--setupEthenoTx (Etheno e _ f t c _ _ d v) = S.state . runState . zoom hasLens . sequence_ $
-- [ result .= Nothing, state . pc .= 0, state . stack .= mempty, state . gas .= 0xffffffff
-- , tx . origin .= fromJust f, state . caller .= fromJust f, state . callvalue .= w256 v, setup] where
-- bc = encodeUtf8 (fromJust d)
-- setup = case e of
-- AccountCreated -> pure ()
-- ContractCreated -> assign (env . contracts . at c) (Just . initialContract . RuntimeCode $ bc) >> loadContract (fromJust c)
-- FunctionCall -> loadContract (fromJust t) >> state . calldata .= bc

@ -45,6 +45,7 @@ import EVM.Concrete (w256)
import qualified Data.ByteString as BS
import qualified Data.HashMap.Strict as M
import qualified Data.Text as T
import qualified EVM as E (contracts)
-- | Things that can go wrong trying to load a Solidity file for Echidna testing. Read the 'Show'
-- instance for more detailed explanations.
@ -142,12 +143,13 @@ loadSpecified name cs = let ensure l e = if l == mempty then throwM e else pure
-- Local variables
(SolConf ca d ads bala balc pref _ libs _ fp) <- view hasLens
let bc = c ^. creationCode
abi = liftM2 (,) (view methodName) (fmap snd . view methodInputs) <$> toList (c ^. abiMap)
(tests, funs) = partition (isPrefixOf pref . fst) abi
-- Set up initial VM, either with chosen contract or Etheno initialization file
-- need to use snd to add to ABI dict
(blank', _) <- maybe (pure (vmForEthrunCreation bc, [])) (loadEthenoBatch bc) fp
(blank', _) <- maybe (pure (vmForEthrunCreation bc, [])) (loadEthenoBatch (fst <$> tests)) fp
liftIO . print $ blank' ^. env . E.contracts . to length
let blank = populateAddresses (ads |> d) bala blank'
abi = liftM2 (,) (view methodName) (fmap snd . view methodInputs) <$> toList (c ^. abiMap)
(tests, funs) = partition (isPrefixOf pref . fst) abi
-- Select libraries
ls <- mapM (choose cs . Just . pack) libs

@ -11,6 +11,7 @@ dependencies:
- base
- ansi-terminal
- brick
- base16-bytestring
- bytestring >= 0.10.8 && < 0.11
- containers >= 0.5.7 && < 0.6
- data-dword >= 0.3.1 && < 0.4
@ -26,6 +27,7 @@ dependencies:
- mtl >= 2.2.1 && < 2.3
- optparse-applicative >= 0.13.0 && < 0.15
- process >= 1.4.3 && < 1.7
- split
- stm
- temporary >= 1.2.1 && < 1.4
- text >= 1.2.2 && < 1.3

Loading…
Cancel
Save