Переглянути джерело

Decouple data account from contract in the Solana mock VM (#1468)

As we start representing contracts by their program id (#1430), we bump
into an incompatibility in our VM. The program id and the contract's
data account are tightly coupled!

In order for us to decouple them from Solang as whole, we need to
refactor the VM so that it accepts contracts without a data account.

Signed-off-by: Lucas Steuernagel <lucas.tnagel@gmail.com>
Lucas Steuernagel 2 роки тому
батько
коміт
9ce88f2bb9
36 змінених файлів з 4298 додано та 2337 видалено
  1. 199 210
      tests/solana.rs
  2. 34 9
      tests/solana_tests/abi.rs
  3. 235 58
      tests/solana_tests/abi_decode.rs
  4. 162 48
      tests/solana_tests/abi_encode.rs
  5. 94 42
      tests/solana_tests/accessor.rs
  6. 18 14
      tests/solana_tests/account_access.rs
  7. 65 33
      tests/solana_tests/account_info.rs
  8. 31 34
      tests/solana_tests/account_serialization.rs
  9. 396 249
      tests/solana_tests/arrays.rs
  10. 179 100
      tests/solana_tests/balance.rs
  11. 12 3
      tests/solana_tests/base58_encoding.rs
  12. 105 34
      tests/solana_tests/builtin.rs
  13. 280 103
      tests/solana_tests/call.rs
  14. 18 4
      tests/solana_tests/constant.rs
  15. 312 125
      tests/solana_tests/create_contract.rs
  16. 46 11
      tests/solana_tests/destructure.rs
  17. 14 4
      tests/solana_tests/events.rs
  18. 91 50
      tests/solana_tests/expressions.rs
  19. 64 12
      tests/solana_tests/hash.rs
  20. 381 259
      tests/solana_tests/mappings.rs
  21. 61 53
      tests/solana_tests/math.rs
  22. 29 13
      tests/solana_tests/metas.rs
  23. 12 3
      tests/solana_tests/modifiers.rs
  24. 384 306
      tests/solana_tests/primitives.rs
  25. 79 23
      tests/solana_tests/rational.rs
  26. 100 22
      tests/solana_tests/returns.rs
  27. 80 53
      tests/solana_tests/runtime_errors.rs
  28. 45 25
      tests/solana_tests/signature_verify.rs
  29. 143 85
      tests/solana_tests/simple.rs
  30. 277 121
      tests/solana_tests/storage.rs
  31. 46 29
      tests/solana_tests/strings.rs
  32. 5 2
      tests/solana_tests/structs.rs
  33. 23 5
      tests/solana_tests/unused_variable_elimination.rs
  34. 39 9
      tests/solana_tests/using.rs
  35. 9 2
      tests/solana_tests/vector_to_slice.rs
  36. 230 184
      tests/solana_tests/yul.rs

+ 199 - 210
tests/solana.rs

@@ -1,9 +1,10 @@
 // SPDX-License-Identifier: Apache-2.0
 
 use crate::borsh_encoding::{decode_at_offset, encode_arguments, BorshToken};
-use anchor_syn::idl::Idl;
+use anchor_syn::idl::{Idl, IdlAccountItem};
 use base58::{FromBase58, ToBase58};
 use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
+use itertools::Itertools;
 use libc::c_char;
 use rand::Rng;
 use serde::{Deserialize, Serialize};
@@ -17,12 +18,9 @@ use solana_rbpf::{
     verifier::{RequisiteVerifier, TautologyVerifier},
     vm::{BuiltinProgram, Config, ContextObject, EbpfVm, ProgramResult, StableResult},
 };
+use solang::abi::anchor::discriminator;
 use solang::{
-    abi::anchor::{discriminator, generate_anchor_idl},
-    compile,
-    file_resolver::FileResolver,
-    sema::ast,
-    Target,
+    abi::anchor::generate_anchor_idl, compile, file_resolver::FileResolver, sema::ast, Target,
 };
 use std::{
     cell::{RefCell, RefMut},
@@ -80,9 +78,8 @@ type CallParametersCheck = fn(vm: &VirtualMachine, instr: &Instruction, pda: &[P
 
 struct VirtualMachine {
     account_data: HashMap<Account, AccountState>,
-    origin: Account,
-    programs: Vec<Contract>,
-    stack: Vec<Contract>,
+    programs: Vec<Program>,
+    stack: Vec<Program>,
     logs: String,
     events: Vec<Vec<Vec<u8>>>,
     return_data: Option<(Account, Vec<u8>)>,
@@ -90,10 +87,9 @@ struct VirtualMachine {
 }
 
 #[derive(Clone)]
-struct Contract {
-    program: Account,
+struct Program {
+    id: Account,
     idl: Option<Idl>,
-    data: Account,
 }
 
 #[derive(Serialize)]
@@ -186,21 +182,9 @@ fn build_solidity(src: &str) -> VirtualMachine {
             },
         );
 
-        let data = account_new();
-
-        account_data.insert(
-            data,
-            AccountState {
-                data: [0u8; 4096].to_vec(),
-                owner: Some(program),
-                lamports: 0,
-            },
-        );
-
-        programs.push(Contract {
-            program,
+        programs.push(Program {
+            id: program,
             idl: Some(idl),
-            data,
         });
     }
 
@@ -228,22 +212,12 @@ fn build_solidity(src: &str) -> VirtualMachine {
         },
     );
 
-    let cur = programs.last().unwrap().clone();
+    account_data.insert([0; 32], AccountState::default());
 
-    let origin = account_new();
-
-    account_data.insert(
-        origin,
-        AccountState {
-            data: Vec::new(),
-            owner: None,
-            lamports: 0,
-        },
-    );
+    let cur = programs.last().unwrap().clone();
 
     VirtualMachine {
         account_data,
-        origin,
         programs,
         stack: vec![cur],
         logs: String::new(),
@@ -365,7 +339,7 @@ fn serialize_parameters(
     v.write_all(input).unwrap();
 
     // program id
-    v.write_all(&vm.stack[0].program).unwrap();
+    v.write_all(&vm.stack[0].id).unwrap();
 
     (v, refs)
 }
@@ -835,7 +809,7 @@ fn sol_set_return_data(
         if len == 0 {
             vm.return_data = None;
         } else {
-            vm.return_data = Some((vm.stack[0].program, buf.to_vec()));
+            vm.return_data = Some((vm.stack[0].id, buf.to_vec()));
         }
 
         *result = ProgramResult::Ok(0);
@@ -1163,7 +1137,7 @@ fn sol_invoke_signed_c(
                         })
                         .collect();
 
-                let pda = create_program_address(&vm.stack[0].program, &seeds);
+                let pda = create_program_address(&vm.stack[0].id, &seeds);
 
                 println!(
                     "pda: {} seeds {}",
@@ -1281,10 +1255,9 @@ fn sol_invoke_signed_c(
                         },
                     );
 
-                    vm.programs.push(Contract {
-                        program: create_account.program_id,
+                    vm.programs.push(Program {
+                        id: create_account.program_id,
                         idl: None,
-                        data: new_address,
                     });
                 }
                 8 => {
@@ -1323,25 +1296,18 @@ fn sol_invoke_signed_c(
                 instruction => panic!("instruction {instruction} not supported"),
             }
         } else {
-            let data_id: Account = instruction.accounts[0].pubkey.0;
-
             println!(
-                "calling {} program_id {}",
-                data_id.to_base58(),
+                "calling program_id {}",
                 instruction.program_id.0.to_base58()
             );
 
-            assert_eq!(data_id, instruction.accounts[0].pubkey.0);
-
-            let mut p = vm
+            let p = vm
                 .programs
                 .iter()
-                .find(|p| p.program == instruction.program_id.0)
+                .find(|p| p.id == instruction.program_id.0)
                 .unwrap()
                 .clone();
 
-            p.data = data_id;
-
             vm.stack.insert(0, p);
 
             let res = vm.execute(&instruction.accounts, &instruction.data);
@@ -1427,10 +1393,10 @@ impl VirtualMachine {
             .unwrap();
 
         // program.program
-        println!("program: {}", program.program.to_base58());
+        println!("program: {}", program.id.to_base58());
 
         let executable = Executable::<TautologyVerifier, SyscallContext>::from_elf(
-            &self.account_data[&program.program].data,
+            &self.account_data[&program.id].data,
             Arc::new(loader),
         )
         .expect("should work");
@@ -1465,8 +1431,6 @@ impl VirtualMachine {
 
         deserialize_parameters(&parameter_bytes, &refs, &mut self.account_data);
 
-        self.validate_account_data_heap();
-
         if let Some((_, return_data)) = &self.return_data {
             println!("return: {}", hex::encode(return_data));
         }
@@ -1474,163 +1438,29 @@ impl VirtualMachine {
         res
     }
 
-    fn constructor(&mut self, args: &[BorshToken]) {
-        let default_metas = self.default_metas();
-        self.constructor_expected(0, &default_metas, args)
-    }
-
-    fn constructor_expected(&mut self, expected: u64, metas: &[AccountMeta], args: &[BorshToken]) {
-        self.return_data = None;
-
-        let program = &self.stack[0];
-        println!("constructor for {}", hex::encode(program.data));
-
-        let mut calldata = discriminator("global", "new");
-        if program
-            .idl
-            .as_ref()
-            .unwrap()
-            .instructions
-            .iter()
-            .any(|instr| instr.name == "new")
-        {
-            let mut encoded_data = encode_arguments(args);
-            calldata.append(&mut encoded_data);
-        };
-
-        let res = self.execute(metas, &calldata);
-
-        if let ProgramResult::Ok(res) = res {
-            assert_eq!(res, expected);
-        } else {
-            panic!("{res:?}");
-        }
-        if let Some((_, return_data)) = &self.return_data {
-            assert_eq!(return_data.len(), 0);
-        }
-    }
-
-    fn function(&mut self, name: &str, args: &[BorshToken]) -> Option<BorshToken> {
-        let default_metas = self.default_metas();
-
-        self.function_metas(name, &default_metas, args)
-    }
-
-    fn function_metas(
-        &mut self,
-        name: &str,
-        metas: &[AccountMeta],
-        args: &[BorshToken],
-    ) -> Option<BorshToken> {
-        self.return_data = None;
-        let program = &self.stack[0];
-
-        println!("function {} for {}", name, hex::encode(program.data));
-
-        let mut calldata = discriminator("global", name);
-
-        let instruction = if let Some(instr) = program
+    fn function(&mut self, name: &str) -> VmFunction {
+        let idx = if let Some((idx, _)) = self.stack[0]
             .idl
             .as_ref()
             .unwrap()
             .instructions
             .iter()
-            .find(|item| item.name == name)
+            .find_position(|instr| instr.name == name)
         {
-            instr.clone()
-        } else {
-            panic!("Function '{name}' not found");
-        };
-
-        let mut encoded_args = encode_arguments(args);
-        calldata.append(&mut encoded_args);
-
-        println!("input: {}", hex::encode(&calldata));
-
-        let res = self.execute(metas, &calldata);
-        match res {
-            ProgramResult::Ok(0) => (),
-            ProgramResult::Ok(error_code) => panic!("unexpected return {error_code:#x}"),
-            ProgramResult::Err(e) => panic!("error: {e:?}"),
-        };
-
-        let return_data = if let Some((_, return_data)) = &self.return_data {
-            return_data.as_slice()
+            idx
         } else {
-            &[]
+            panic!("Function not found")
         };
 
-        if let Some(ret) = &instruction.returns {
-            let mut offset: usize = 0;
-            let decoded = decode_at_offset(
-                return_data,
-                &mut offset,
-                ret,
-                &self.stack[0].idl.as_ref().unwrap().types,
-            );
-            assert_eq!(offset, return_data.len());
-            Some(decoded)
-        } else {
-            assert_eq!(return_data.len(), 0);
-            None
-        }
-    }
-
-    fn function_must_fail(&mut self, name: &str, args: &[BorshToken]) -> ProgramResult {
-        let program = &self.stack[0];
-
-        println!("function for {}", hex::encode(program.data));
-
-        let mut calldata = Vec::new();
-
-        if !self.stack[0]
-            .idl
-            .as_ref()
-            .unwrap()
-            .instructions
-            .iter()
-            .any(|item| item.name == name)
-        {
-            panic!("Function '{name}' not found");
-        }
-
-        let selector = discriminator("global", name);
-        calldata.extend_from_slice(&selector);
-        let mut encoded = encode_arguments(args);
-        calldata.append(&mut encoded);
-
-        let default_metas = self.default_metas();
-
-        println!("input: {}", hex::encode(&calldata));
-
-        self.execute(&default_metas, &calldata)
-    }
-
-    fn default_metas(&self) -> Vec<AccountMeta> {
-        // Just include everything
-        let mut accounts = vec![AccountMeta {
-            pubkey: Pubkey(self.stack[0].data),
-            is_writable: true,
-            is_signer: false,
-        }];
-
-        for acc in self.account_data.keys() {
-            if *acc != accounts[0].pubkey.0 {
-                accounts.push(AccountMeta {
-                    pubkey: Pubkey(*acc),
-                    is_signer: false,
-                    is_writable: true,
-                });
-            }
+        VmFunction {
+            vm: self,
+            idx,
+            expected: 0,
+            accounts: Vec::new(),
+            has_remaining: false,
+            arguments: None,
+            data_account: None,
         }
-
-        accounts
-    }
-
-    fn data(&self) -> &Vec<u8> {
-        let program = &self.stack[0];
-
-        &self.account_data[&program.data].data
     }
 
     fn set_program(&mut self, no: usize) {
@@ -1671,15 +1501,14 @@ impl VirtualMachine {
             },
         );
 
-        self.programs.push(Contract {
-            program: *program_id,
+        self.programs.push(Program {
+            id: *program_id,
             idl: None,
-            data: *account,
         });
     }
 
-    fn validate_account_data_heap(&self) -> usize {
-        if let Some(acc) = self.account_data.get(&self.stack[0].data) {
+    fn validate_account_data_heap(&self, account: &Pubkey) -> usize {
+        if let Some(acc) = self.account_data.get(&account.0) {
             let data = &acc.data;
 
             let mut count = 0;
@@ -1748,6 +1577,20 @@ impl VirtualMachine {
             0
         }
     }
+
+    fn initialize_data_account(&mut self) -> Account {
+        let address = account_new();
+        self.account_data.insert(
+            address,
+            AccountState {
+                lamports: 0,
+                data: vec![0; 4096],
+                owner: Some(self.stack[0].id),
+            },
+        );
+
+        address
+    }
 }
 
 pub fn parse_and_resolve(src: &'static str, target: Target) -> ast::Namespace {
@@ -1757,3 +1600,149 @@ pub fn parse_and_resolve(src: &'static str, target: Target) -> ast::Namespace {
 
     solang::parse_and_resolve(OsStr::new("test.sol"), &mut cache, target)
 }
+
+struct VmFunction<'a, 'b> {
+    vm: &'a mut VirtualMachine,
+    idx: usize,
+    expected: u64,
+    accounts: Vec<AccountMeta>,
+    has_remaining: bool,
+    arguments: Option<&'b [BorshToken]>,
+    data_account: Option<usize>,
+}
+
+impl<'a, 'b> VmFunction<'a, 'b> {
+    fn accounts(&mut self, accounts: Vec<(&str, Account)>) -> &mut Self {
+        let accounts = accounts.into_iter().collect::<HashMap<&str, Account>>();
+        let mut metas: Vec<AccountMeta> = Vec::new();
+
+        for account in &self.vm.stack[0].idl.as_ref().unwrap().instructions[self.idx].accounts {
+            match account {
+                IdlAccountItem::IdlAccount(account) => {
+                    if account.name == "dataAccount" {
+                        self.data_account = Some(metas.len());
+                    }
+
+                    metas.push(AccountMeta {
+                        pubkey: Pubkey(
+                            accounts
+                                .get(account.name.as_str())
+                                .cloned()
+                                .expect("an account is missing"),
+                        ),
+                        is_writable: account.is_mut,
+                        is_signer: account.is_signer,
+                    });
+                }
+                IdlAccountItem::IdlAccounts(_) => unimplemented!("Solang does not use IdlAccounts"),
+            }
+        }
+
+        self.accounts = metas;
+        self
+    }
+
+    fn remaining_accounts(&mut self, accounts: &[AccountMeta]) -> &mut Self {
+        self.has_remaining = true;
+        self.accounts.extend_from_slice(accounts);
+        self
+    }
+
+    fn expected(&mut self, expected: u64) -> &mut Self {
+        self.expected = expected;
+        self
+    }
+
+    fn arguments(&mut self, args: &'b [BorshToken]) -> &mut Self {
+        self.arguments = Some(args);
+        self
+    }
+
+    fn call(&mut self) -> Option<BorshToken> {
+        self.vm.return_data = None;
+        let idl_instr = self.vm.stack[0].idl.as_ref().unwrap().instructions[self.idx].clone();
+        let mut calldata = discriminator("global", &idl_instr.name);
+
+        if !self.has_remaining {
+            assert_eq!(
+                idl_instr.accounts.len(),
+                self.accounts.len(),
+                "Incorrect number of accounts"
+            );
+        }
+
+        println!(
+            "function {} for {}",
+            idl_instr.name,
+            self.vm.stack[0].id.to_base58()
+        );
+
+        if let Some(args) = self.arguments {
+            let mut encoded_data = encode_arguments(args);
+            calldata.append(&mut encoded_data);
+        }
+
+        println!("input: {}", hex::encode(&calldata));
+
+        let res = self.vm.execute(&self.accounts, &calldata);
+
+        if let Some(idx) = self.data_account {
+            self.vm
+                .validate_account_data_heap(&self.accounts[idx].pubkey);
+        }
+
+        match res {
+            ProgramResult::Ok(num) if num == self.expected => (),
+            ProgramResult::Ok(num) => panic!("unexpected return {num:#x}"),
+            ProgramResult::Err(e) => panic!("error {e:?}"),
+        }
+
+        let return_data = if let Some((_, return_data)) = &self.vm.return_data {
+            return_data.as_slice()
+        } else {
+            &[]
+        };
+
+        if let Some(ret) = &idl_instr.returns {
+            let mut offset = 0;
+            let decoded = decode_at_offset(
+                return_data,
+                &mut offset,
+                ret,
+                &self.vm.stack[0].idl.as_ref().unwrap().types,
+            );
+            assert_eq!(offset, return_data.len());
+            Some(decoded)
+        } else {
+            assert_eq!(return_data.len(), 0);
+            None
+        }
+    }
+
+    fn must_fail(&mut self) -> ProgramResult {
+        self.vm.return_data = None;
+        let idl_instr = self.vm.stack[0].idl.as_ref().unwrap().instructions[self.idx].clone();
+        if !self.has_remaining {
+            assert_eq!(
+                idl_instr.accounts.len(),
+                self.accounts.len(),
+                "Incorrect number of accounts"
+            );
+        }
+
+        let mut calldata = discriminator("global", &idl_instr.name);
+        if let Some(args) = self.arguments {
+            let mut encoded_data = encode_arguments(args);
+            calldata.append(&mut encoded_data);
+        }
+
+        let result = self.vm.execute(&self.accounts, &calldata);
+
+        if let Some(idx) = self.data_account {
+            self.vm
+                .validate_account_data_heap(&self.accounts[idx].pubkey);
+        }
+
+        result
+    }
+}

+ 34 - 9
tests/solana_tests/abi.rs

@@ -45,12 +45,27 @@ fn packed() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let account = vm.initialize_data_account();
 
-    vm.function("test", &[]);
-    vm.function("test2", &[]);
-    vm.function("test3", &[]);
-    vm.function("test4", &[]);
+    vm.function("new")
+        .accounts(vec![("dataAccount", account)])
+        .call();
+
+    vm.function("test")
+        .accounts(vec![("dataAccount", account)])
+        .call();
+
+    vm.function("test2")
+        .accounts(vec![("dataAccount", account)])
+        .call();
+
+    vm.function("test3")
+        .accounts(vec![("dataAccount", account)])
+        .call();
+
+    vm.function("test4")
+        .accounts(vec![("dataAccount", account)])
+        .call();
 }
 
 #[test]
@@ -65,9 +80,14 @@ fn inherited() {
         contract bar is foo { }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function("test", &[]);
+    vm.function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let mut vm = build_solidity(
         r#"
@@ -78,7 +98,12 @@ fn inherited() {
             contract bar is foo { }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function("test", &[]);
+    vm.function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }

+ 235 - 58
tests/solana_tests/abi_decode.rs

@@ -67,7 +67,10 @@ fn integers_bool_enum() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let input = Res1 {
         a: 45,
         b: 9965956609890,
@@ -78,7 +81,10 @@ fn integers_bool_enum() {
         h: false,
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("decodeTest1", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("decodeTest1")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 
     let input = Res2 {
         item_1: WeekDay::Sunday,
@@ -86,7 +92,10 @@ fn integers_bool_enum() {
         item_3: WeekDay::Friday,
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("decodeTest2", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("decodeTest2")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 }
 
 #[test]
@@ -110,13 +119,21 @@ fn decode_address() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
     let input = Data {
-        address: vm.programs[0].data,
-        this: vm.programs[0].data,
+        address: data_account,
+        this: data_account,
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("testAddress", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("testAddress")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }
 
 #[test]
@@ -140,13 +157,20 @@ fn string_and_bytes() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let data = Data {
         a: "coffee".to_string(),
         b: b"tea".to_vec(),
     };
     let encoded = data.try_to_vec().unwrap();
-    let _ = vm.function("testStringAndBytes", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("testStringAndBytes")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }
 
 #[test]
@@ -194,10 +218,16 @@ fn primitive_struct() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let data = NoPadStruct { a: 1238, b: 87123 };
     let encoded = data.try_to_vec().unwrap();
-    let _ = vm.function("testNoPadStruct", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("testNoPadStruct")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 
     let mut elem = b"tea_is_good".to_vec();
     elem.append(&mut vec![0; 21]);
@@ -207,7 +237,10 @@ fn primitive_struct() {
         c: <[u8; 32]>::try_from(&elem[0..32]).unwrap(),
     };
     let encoded = data.try_to_vec().unwrap();
-    let _ = vm.function("testPaddedStruct", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("testPaddedStruct")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 }
 
 #[test]
@@ -227,13 +260,18 @@ fn returned_string() {
     }
         "#,
     );
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let data = Input {
         rr: "cortado".to_string(),
     };
     let encoded = data.try_to_vec().unwrap();
     let returns = vm
-        .function("returnedString", &[BorshToken::Bytes(encoded)])
+        .function("returnedString")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call()
         .unwrap();
     let string = returns.into_string().unwrap();
     assert_eq!(string, "cortado");
@@ -257,7 +295,10 @@ fn test_string_array() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let data = Input {
         a: vec![
             "coffee".to_string(),
@@ -267,7 +308,9 @@ fn test_string_array() {
     };
     let encoded = data.try_to_vec().unwrap();
     let returns = vm
-        .function("testStringVector", &[BorshToken::Bytes(encoded)])
+        .function("testStringVector")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call()
         .unwrap();
     let vec = returns.into_array().unwrap();
 
@@ -337,7 +380,10 @@ fn struct_within_struct() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let no_pad = NoPadStruct { a: 89123, b: 12354 };
     let mut tea_is_good = b"tea_is_good".to_vec();
     tea_is_good.append(&mut vec![0; 21]);
@@ -353,7 +399,10 @@ fn struct_within_struct() {
         pad,
     };
     let encoded = data.try_to_vec().unwrap();
-    let _ = vm.function("testStruct", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("testStruct")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 }
 
 #[test]
@@ -449,7 +498,10 @@ fn struct_in_array() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let mut bytes_string = b"there_is_padding_here".to_vec();
     bytes_string.append(&mut vec![0; 11]);
     let input = Input1 {
@@ -461,7 +513,10 @@ fn struct_in_array() {
         },
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("twoStructs", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("twoStructs")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 
     let input = Input2 {
         item_1: [1, -298, 3, -434],
@@ -473,13 +528,19 @@ fn struct_in_array() {
         ],
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("fixedArrays", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("fixedArrays")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 
     let input = Input3 {
         vec: vec![NoPadStruct { a: 5, b: 6 }, NoPadStruct { a: 7, b: 8 }],
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("primitiveDynamic", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("primitiveDynamic")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 }
 
 #[test]
@@ -552,7 +613,10 @@ fn arrays() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let input = Input1 {
         complex_array: vec![
             NonConstantStruct {
@@ -566,19 +630,31 @@ fn arrays() {
         ],
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("decodeComplex", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("decodeComplex")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let input = Input2 {
         vec: vec![-90, 5523, -89],
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("dynamicArray", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("dynamicArray")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let input = Input3 {
         multi_dim: [[1, 2], [4, 5], [6, 7]],
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("decodeMultiDim", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("decodeMultiDim")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }
 
 #[test]
@@ -687,7 +763,10 @@ fn multi_dimensional_arrays() {
     }
         "#,
     );
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let mut response: Vec<u8> = vec![0; 32];
 
     let input = Input1 {
@@ -732,7 +811,10 @@ fn multi_dimensional_arrays() {
         item_2: -90,
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("multiDimStruct", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("multiDimStruct")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 
     let input = Input2 {
         vec: vec![
@@ -741,13 +823,19 @@ fn multi_dimensional_arrays() {
         ],
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("multiDimInt", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("multiDimInt")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 
     let input = Input3 {
         vec: vec![9, 3, 4, 90, 834],
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("uniqueDim", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("uniqueDim")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 }
 
 #[test]
@@ -781,14 +869,20 @@ fn empty_arrays() {
     }
         "#,
     );
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let input = Input {
         vec_1: vec![],
         vec_2: vec![],
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("testEmpty", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("testEmpty")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 }
 
 #[test]
@@ -810,7 +904,10 @@ fn external_function() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let input = Input {
         selector: [1, 2, 3, 4, 5, 6, 7, 8],
         address: [
@@ -821,7 +918,10 @@ fn external_function() {
     let encoded = input.try_to_vec().unwrap();
 
     let returns = vm
-        .function("testExternalFunction", &[BorshToken::Bytes(encoded)])
+        .function("testExternalFunction")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
 
@@ -857,13 +957,20 @@ fn bytes_arrays() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let input = Input {
         item_1: [b"abcd".to_owned(), b"efgh".to_owned()],
         item_2: vec![b"12345".to_owned(), b"67890".to_owned()],
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("testByteArrays", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("testByteArrays")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }
 
 #[test]
@@ -892,10 +999,17 @@ fn different_types() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let input = Input1 { a: -789, b: 14234 };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("testByteArrays", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("testByteArrays")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }
 
 #[test]
@@ -918,11 +1032,18 @@ fn more_elements() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let input = Input { vec: [1, 4, 5, 6] };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("wrongNumber", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("wrongNumber")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }
 
 #[test]
@@ -946,13 +1067,19 @@ fn extra_element() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let input = Input {
         vec: vec![-90, 89, -2341],
     };
 
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("extraElement", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("extraElement")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 }
 
 #[test]
@@ -975,11 +1102,17 @@ fn invalid_type() {
     "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let input = Input { item: 5 };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("invalidType", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("invalidType")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 }
 
 #[test]
@@ -1003,14 +1136,21 @@ fn longer_buffer() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let input = Input {
         item_1: 4,
         item_2: 5,
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("testLongerBuffer", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("testLongerBuffer")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }
 
 #[test]
@@ -1035,14 +1175,21 @@ fn longer_buffer_array() {
             }
         }        "#,
     );
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let input = Input {
         item_1: 23434,
         item_2: [1, 2, 3, 4],
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("testLongerBuffer", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("testLongerBuffer")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }
 
 #[test]
@@ -1069,12 +1216,18 @@ fn dynamic_array_of_array() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let input = Input {
         vec: vec![[0, 1], [2, -3]],
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("testArrayAssign", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("testArrayAssign")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 }
 
 #[test]
@@ -1114,7 +1267,10 @@ fn test_struct_validation() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let mut bytes_string = b"struct".to_vec();
     bytes_string.append(&mut vec![0; 26]);
 
@@ -1127,7 +1283,10 @@ fn test_struct_validation() {
         },
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("test", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("test")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 }
 
 #[test]
@@ -1167,7 +1326,10 @@ fn test_struct_validation_invalid() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let mut bytes_string = b"struct".to_vec();
     bytes_string.append(&mut vec![0; 26]);
 
@@ -1179,7 +1341,10 @@ fn test_struct_validation_invalid() {
         },
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("test", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("test")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 }
 
 #[test]
@@ -1197,7 +1362,10 @@ fn string_fixed_array() {
 }
         "#,
     );
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     #[derive(Debug, BorshSerialize)]
     struct Input {
@@ -1213,7 +1381,10 @@ fn string_fixed_array() {
         ],
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("testing", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("testing")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 }
 
 #[test]
@@ -1233,7 +1404,10 @@ fn double_dynamic_array() {
     }
         "#,
     );
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     #[derive(Debug, BorshSerialize)]
     struct Input {
@@ -1248,5 +1422,8 @@ fn double_dynamic_array() {
         item_3: -755,
     };
     let encoded = input.try_to_vec().unwrap();
-    let _ = vm.function("testThis", &[BorshToken::Bytes(encoded)]);
+    let _ = vm
+        .function("testThis")
+        .arguments(&[BorshToken::Bytes(encoded)])
+        .call();
 }

+ 162 - 48
tests/solana_tests/abi_encode.rs

@@ -67,8 +67,11 @@ contract Testing {
         "#,
     );
 
-    vm.constructor(&[]);
-    let returns = vm.function("getThis", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm.function("getThis").call().unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res1::try_from_slice(&encoded).unwrap();
 
@@ -80,7 +83,7 @@ contract Testing {
     assert_eq!(decoded.day, WeekDay::Wednesday);
     assert!(!decoded.h);
 
-    let returns = vm.function("encodeEnum", &[]).unwrap();
+    let returns = vm.function("encodeEnum").call().unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res2::try_from_slice(&encoded).unwrap();
 
@@ -108,12 +111,19 @@ contract Testing {
 }
         "#,
     );
-    vm.constructor(&[]);
-    let returns = vm.function("getThis", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("getThis")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Response::try_from_slice(&encoded).unwrap();
-    assert_eq!(decoded.address, vm.programs[0].data);
-    assert_eq!(decoded.this, vm.programs[0].data);
+    assert_eq!(decoded.address, data_account);
+    assert_eq!(decoded.this, data_account);
 }
 
 #[test]
@@ -138,8 +148,11 @@ contract Testing {
       "#,
     );
 
-    vm.constructor(&[]);
-    let returns = vm.function("getThis", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm.function("getThis").call().unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = MyStruct::try_from_slice(&encoded).unwrap();
     assert_eq!(decoded.a, "coffe");
@@ -190,15 +203,19 @@ fn primitive_structs() {
 }
         "#,
     );
-    vm.constructor(&[]);
-    let returns = vm.function("getThis", &[]).unwrap();
+
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm.function("getThis").call().unwrap();
     let encoded = returns.into_bytes().unwrap();
 
     let decoded = NoPadStruct::try_from_slice(&encoded).unwrap();
     assert_eq!(decoded.a, 1238);
     assert_eq!(decoded.b, 87123);
 
-    let returns = vm.function("getThat", &[]).unwrap();
+    let returns = vm.function("getThat").call().unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = PaddedStruct::try_from_slice(&encoded).unwrap();
     assert_eq!(decoded.a, 12998);
@@ -226,10 +243,15 @@ contract Testing {
       "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function("testStruct", &[BorshToken::String("nihao".to_string())])
+        .function("testStruct")
+        .arguments(&[BorshToken::String("nihao".to_string())])
+        .call()
         .unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Response::try_from_slice(&encoded).unwrap();
@@ -261,14 +283,29 @@ fn test_string_array() {
         "#,
     );
 
-    vm.constructor(&[]);
-    let returns = vm.function("encode", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
+    let returns = vm
+        .function("encode")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Response::try_from_slice(&encoded).unwrap();
     assert_eq!(decoded.a.len(), 0);
 
-    let _ = vm.function("insertStrings", &[]);
-    let returns = vm.function("encode", &[]).unwrap();
+    let _ = vm
+        .function("insertStrings")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("encode")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Response::try_from_slice(&encoded).unwrap();
     assert_eq!(decoded.a.len(), 2);
@@ -338,8 +375,16 @@ contract Testing {
         "#,
     );
 
-    vm.constructor(&[]);
-    let returns = vm.function("testStruct", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
+    let returns = vm
+        .function("testStruct")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = NonConstantStruct::try_from_slice(&encoded).unwrap();
 
@@ -441,9 +486,20 @@ fn struct_in_array() {
         "#,
     );
 
-    vm.constructor(&[]);
-    let _ = vm.function("addData", &[]);
-    let returns = vm.function("encodeStruct", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
+    let _ = vm
+        .function("addData")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("encodeStruct")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res1::try_from_slice(&encoded).unwrap();
 
@@ -454,7 +510,11 @@ fn struct_in_array() {
     let b: [u8; 21] = b"there_is_padding_here".to_owned();
     assert_eq!(&decoded.item_2.c[0..21], b);
 
-    let returns = vm.function("primitiveStruct", &[]).unwrap();
+    let returns = vm
+        .function("primitiveStruct")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res2::try_from_slice(&encoded).unwrap();
 
@@ -466,7 +526,11 @@ fn struct_in_array() {
     assert_eq!(decoded.item_3[0], NoPadStruct { a: 1, b: 2 });
     assert_eq!(decoded.item_3[1], NoPadStruct { a: 3, b: 4 });
 
-    let returns = vm.function("primitiveDynamicArray", &[]).unwrap();
+    let returns = vm
+        .function("primitiveDynamicArray")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res3::try_from_slice(&encoded).unwrap();
 
@@ -541,9 +605,19 @@ fn arrays() {
       "#,
     );
 
-    vm.constructor(&[]);
-    let _ = vm.function("addData", &[]);
-    let returns = vm.function("encodeArray", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let _ = vm
+        .function("addData")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("encodeArray")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res1::try_from_slice(&encoded).unwrap();
 
@@ -552,7 +626,11 @@ fn arrays() {
     assert_eq!(decoded.vec_1[1], 5523);
     assert_eq!(decoded.vec_1[2], -89);
 
-    let returns = vm.function("encodeComplex", &[]).unwrap();
+    let returns = vm
+        .function("encodeComplex")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res2::try_from_slice(&encoded).unwrap();
 
@@ -568,7 +646,7 @@ fn arrays() {
         vec!["cortado".to_string(), "cappuccino".to_string()]
     );
 
-    let returns = vm.function("multiDimArrays", &[]).unwrap();
+    let returns = vm.function("multiDimArrays").call().unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res3::try_from_slice(&encoded).unwrap();
 
@@ -654,8 +732,11 @@ contract Testing {
         "#,
     );
 
-    vm.constructor(&[]);
-    let returns = vm.function("getThis", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm.function("getThis").call().unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res1::try_from_slice(&encoded).unwrap();
 
@@ -713,7 +794,7 @@ contract Testing {
     );
     assert_eq!(decoded.item_2, 5);
 
-    let returns = vm.function("multiDim", &[]).unwrap();
+    let returns = vm.function("multiDim").call().unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res2::try_from_slice(&encoded).unwrap();
 
@@ -721,7 +802,7 @@ contract Testing {
     assert_eq!(decoded.item[0][0], [1, 2, 3, 4]);
     assert_eq!(decoded.item[0][1], [5, 6, 7, 8]);
 
-    let returns = vm.function("uniqueDim", &[]).unwrap();
+    let returns = vm.function("uniqueDim").call().unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res3::try_from_slice(&encoded).unwrap();
 
@@ -775,8 +856,11 @@ fn null_pointer() {
         "#,
     );
 
-    vm.constructor(&[]);
-    let returns = vm.function("test1", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm.function("test1").call().unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res1::try_from_slice(&encoded).unwrap();
 
@@ -786,7 +870,7 @@ fn null_pointer() {
         assert!(decoded.item[i].f2.is_empty())
     }
 
-    let returns = vm.function("test2", &[]).unwrap();
+    let returns = vm.function("test2").call().unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res2::try_from_slice(&encoded).unwrap();
 
@@ -822,9 +906,17 @@ fn external_function() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("doThat", &[]).unwrap().unwrap_tuple();
+    let returns = vm
+        .function("doThat")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap()
+        .unwrap_tuple();
     let encoded = returns[2].clone().into_bytes().unwrap();
     let decoded = Res::try_from_slice(&encoded).unwrap();
 
@@ -857,8 +949,13 @@ fn bytes_arrays() {
     }
         "#,
     );
-    vm.constructor(&[]);
-    let returns = vm.function("testBytesArray", &[]).unwrap();
+
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
+    let returns = vm.function("testBytesArray").call().unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res::try_from_slice(&encoded).unwrap();
 
@@ -896,8 +993,11 @@ fn uint8_arrays() {
     }"#,
     );
 
-    vm.constructor(&[]);
-    let returns = vm.function("testBytesArray", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm.function("testBytesArray").call().unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res::try_from_slice(&encoded).unwrap();
 
@@ -921,15 +1021,26 @@ contract caller {
         return b + 3;
     }
 
-    function do_call() pure public returns (int64, int32) {
+    function do_call() view public returns (int64, int32) {
         return (this.doThis(5), this.doThat(3));
     }
 }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("do_call", &[]).unwrap().unwrap_tuple();
+    let returns = vm
+        .function("do_call")
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .call()
+        .unwrap()
+        .unwrap_tuple();
     assert_eq!(returns.len(), 2);
     assert_eq!(
         returns[0],
@@ -977,9 +1088,12 @@ contract Testing {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("testThis", &[]).unwrap();
+    let returns = vm.function("testThis").call().unwrap();
     let encoded = returns.into_bytes().unwrap();
     let decoded = Res::try_from_slice(&encoded).unwrap();
     assert_eq!(decoded.item_1, 99);

+ 94 - 42
tests/solana_tests/accessor.rs

@@ -13,9 +13,16 @@ fn types() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("f1", &[]).unwrap();
+    let returns = vm
+        .function("f1")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -32,16 +39,19 @@ fn types() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "f1",
-            &[BorshToken::Uint {
-                width: 256,
-                value: BigInt::from(2u8),
-            }],
-        )
+        .function("f1")
+        .arguments(&[BorshToken::Uint {
+            width: 256,
+            value: BigInt::from(2u8),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -66,22 +76,25 @@ fn types() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "f1",
-            &[
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::one(),
-                },
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from(2u8),
-                },
-            ],
-        )
+        .function("f1")
+        .arguments(&[
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::one(),
+            },
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from(2u8),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -104,16 +117,19 @@ fn types() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "f1",
-            &[BorshToken::Int {
-                width: 64,
-                value: BigInt::from(4000u16),
-            }],
-        )
+        .function("f1")
+        .arguments(&[BorshToken::Int {
+            width: 64,
+            value: BigInt::from(4000u16),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -139,9 +155,16 @@ fn interfaces() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("f1", &[]).unwrap();
+    let returns = vm
+        .function("f1")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::uint8_fixed_array(b"ab".to_vec()));
 }
@@ -155,9 +178,16 @@ fn constant() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("z", &[]).unwrap();
+    let returns = vm
+        .function("z")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -174,9 +204,16 @@ fn constant() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("z", &[]).unwrap();
+    let returns = vm
+        .function("z")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -193,9 +230,16 @@ fn constant() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("z", &[]).unwrap();
+    let returns = vm
+        .function("z")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -242,7 +286,15 @@ fn struct_accessor() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function("f", &[]);
+    vm.function("f")
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .call();
 }

+ 18 - 14
tests/solana_tests/account_access.rs

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: Apache-2.0
 
 use crate::borsh_encoding::BorshToken;
-use crate::{account_new, build_solidity, AccountMeta, AccountState, Pubkey};
+use crate::{account_new, build_solidity, create_program_address, AccountState};
 
 #[test]
 fn access_payer() {
@@ -20,6 +20,8 @@ fn access_payer() {
         "#,
     );
     let payer = account_new();
+    let pda = create_program_address(&vm.stack[0].id, &[b"sunflower"]);
+
     vm.account_data.insert(
         payer,
         AccountState {
@@ -28,19 +30,21 @@ fn access_payer() {
             lamports: 10,
         },
     );
-
-    let metas = vec![
-        AccountMeta {
-            pubkey: Pubkey(vm.stack[0].data),
-            is_writable: true,
-            is_signer: false,
-        },
-        AccountMeta {
-            pubkey: Pubkey(payer),
-            is_writable: true,
-            is_signer: true,
+    vm.account_data.insert(
+        pda.0,
+        AccountState {
+            data: [0; 4096].to_vec(),
+            owner: Some(vm.stack[0].id),
+            lamports: 0,
         },
-    ];
+    );
 
-    vm.constructor_expected(0, &metas, &[BorshToken::Address(payer)]);
+    vm.function("new")
+        .arguments(&[BorshToken::Address(payer)])
+        .accounts(vec![
+            ("dataAccount", pda.0),
+            ("payer", payer),
+            ("systemProgram", [0; 32]),
+        ])
+        .call();
 }

+ 65 - 33
tests/solana_tests/account_info.rs

@@ -27,12 +27,31 @@ fn lamports() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.account_data.get_mut(&vm.origin).unwrap().lamports = 17672630920854456917u64;
+    let acc = account_new();
+    vm.account_data.insert(
+        acc,
+        AccountState {
+            data: vec![],
+            owner: None,
+            lamports: 17672630920854456917u64,
+        },
+    );
 
     let returns = vm
-        .function("test", &[BorshToken::Address(vm.origin)])
+        .function("test")
+        .arguments(&[BorshToken::Address(acc)])
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(acc),
+            is_writable: true,
+            is_signer: false,
+        }])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -64,11 +83,18 @@ fn owner() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("test", &[]).unwrap();
+    let returns = vm
+        .function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
-    let owner = vm.stack[0].program;
+    let owner = vm.stack[0].id;
 
     assert_eq!(returns, BorshToken::Address(owner));
 }
@@ -105,22 +131,23 @@ fn data() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     for i in 0..10 {
         let returns = vm
-            .function(
-                "test",
-                &[BorshToken::Uint {
-                    width: 32,
-                    value: BigInt::from(i),
-                }],
-            )
+            .function("test")
+            .arguments(&[BorshToken::Uint {
+                width: 32,
+                value: BigInt::from(i),
+            }])
+            .accounts(vec![("dataAccount", data_account)])
+            .call()
             .unwrap();
 
-        let this = &vm.stack[0].data;
-
-        let val = vm.account_data[this].data[i];
+        let val = vm.account_data[&data_account].data[i];
 
         assert_eq!(
             returns,
@@ -131,11 +158,17 @@ fn data() {
         );
     }
 
-    let returns = vm.function("test2", &[]).unwrap();
-
-    let this = &vm.stack[0].data;
+    let returns = vm
+        .function("test2")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
-    let val = u32::from_le_bytes(vm.account_data[this].data[1..5].try_into().unwrap());
+    let val = u32::from_le_bytes(
+        vm.account_data[&data_account].data[1..5]
+            .try_into()
+            .unwrap(),
+    );
 
     assert_eq!(
         returns,
@@ -172,7 +205,10 @@ contract starter {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let acc1 = account_new();
     let acc2 = account_new();
@@ -203,11 +239,6 @@ contract starter {
     );
 
     let metas = vec![
-        AccountMeta {
-            pubkey: Pubkey(vm.stack[0].data),
-            is_writable: false,
-            is_signer: false,
-        },
         AccountMeta {
             pubkey: Pubkey(acc1),
             is_writable: true,
@@ -225,10 +256,9 @@ contract starter {
         },
     ];
 
-    let _ = vm.function_metas(
-        "createNewAccount",
-        &metas,
-        &[
+    let _ = vm
+        .function("createNewAccount")
+        .arguments(&[
             BorshToken::Uint {
                 width: 64,
                 value: BigInt::from(20u8),
@@ -241,8 +271,10 @@ contract starter {
                 width: 64,
                 value: BigInt::from(9u8),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&metas)
+        .call();
 
     assert_eq!(vm.account_data.get(&acc1).unwrap().lamports, 5);
     assert_eq!(vm.account_data.get(&acc2).unwrap().lamports, 7);

+ 31 - 34
tests/solana_tests/account_serialization.rs

@@ -19,7 +19,10 @@ fn deserialize_duplicate_account() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let random_key = account_new();
     vm.account_data.insert(
@@ -40,29 +43,24 @@ fn deserialize_duplicate_account() {
             lamports: 0,
         },
     );
-    let metas = vec![
-        AccountMeta {
-            pubkey: Pubkey(vm.stack[0].data),
-            is_writable: true,
-            is_signer: false,
-        },
-        AccountMeta {
-            pubkey: Pubkey(random_key),
-            is_signer: true,
-            is_writable: false,
-        },
-        AccountMeta {
-            pubkey: Pubkey(random_key),
-            is_signer: true,
-            is_writable: false,
-        },
-    ];
 
-    vm.function_metas(
-        "check_deserialization",
-        &metas,
-        &[BorshToken::Address(vm.stack[0].program)],
-    );
+    let program_id = vm.stack[0].id;
+    vm.function("check_deserialization")
+        .arguments(&[BorshToken::Address(program_id)])
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&[
+            AccountMeta {
+                pubkey: Pubkey(random_key),
+                is_signer: true,
+                is_writable: false,
+            },
+            AccountMeta {
+                pubkey: Pubkey(random_key),
+                is_signer: true,
+                is_writable: false,
+            },
+        ])
+        .call();
 }
 
 #[test]
@@ -79,14 +77,12 @@ fn more_than_10_accounts() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let mut metas: Vec<AccountMeta> = Vec::new();
-    metas.push(AccountMeta {
-        pubkey: Pubkey(vm.stack[0].data),
-        is_writable: true,
-        is_signer: false,
-    });
     for i in 0..11 {
         let account = account_new();
         metas.push(AccountMeta {
@@ -120,9 +116,10 @@ fn more_than_10_accounts() {
         },
     );
 
-    vm.function_metas(
-        "check_deserialization",
-        &metas,
-        &[BorshToken::Address(vm.stack[0].program)],
-    );
+    let program_id = vm.stack[0].id;
+    vm.function("check_deserialization")
+        .arguments(&[BorshToken::Address(program_id)])
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&metas)
+        .call();
 }

Різницю між файлами не показано, бо вона завелика
+ 396 - 249
tests/solana_tests/arrays.rs


+ 179 - 100
tests/solana_tests/balance.rs

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: Apache-2.0
 
-use crate::{account_new, build_solidity, AccountState, BorshToken};
+use crate::{account_new, build_solidity, AccountMeta, AccountState, BorshToken, Pubkey};
 use anchor_syn::idl::IdlInstruction;
 use num_bigint::BigInt;
 
@@ -15,7 +15,10 @@ fn get_balance() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let new = account_new();
 
@@ -28,7 +31,17 @@ fn get_balance() {
         },
     );
 
-    let returns = vm.function("test", &[BorshToken::Address(new)]).unwrap();
+    let returns = vm
+        .function("test")
+        .arguments(&[BorshToken::Address(new)])
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(new),
+            is_signer: false,
+            is_writable: false,
+        }])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -50,7 +63,10 @@ fn send_fails() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let new = account_new();
 
@@ -64,16 +80,21 @@ fn send_fails() {
     );
 
     let returns = vm
-        .function(
-            "send",
-            &[
-                BorshToken::FixedBytes(new.to_vec()),
-                BorshToken::Uint {
-                    width: 64,
-                    value: BigInt::from(102u8),
-                },
-            ],
-        )
+        .function("send")
+        .arguments(&[
+            BorshToken::Address(new),
+            BorshToken::Uint {
+                width: 64,
+                value: BigInt::from(102u8),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(new),
+            is_signer: false,
+            is_writable: true,
+        }])
+        .call()
         .unwrap();
 
     assert_eq!(returns, BorshToken::Bool(false));
@@ -92,12 +113,15 @@ fn send_succeeds() {
         }"#,
     );
 
-    vm.account_data.get_mut(&vm.stack[0].data).unwrap().lamports = 103;
+    let data_account = vm.initialize_data_account();
 
-    vm.constructor(&[]);
+    vm.account_data.get_mut(&data_account).unwrap().lamports = 103;
 
-    let new = account_new();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
+    let new = account_new();
     vm.account_data.insert(
         new,
         AccountState {
@@ -108,26 +132,28 @@ fn send_succeeds() {
     );
 
     let returns = vm
-        .function(
-            "send",
-            &[
-                BorshToken::FixedBytes(new.to_vec()),
-                BorshToken::Uint {
-                    width: 64,
-                    value: BigInt::from(102u8),
-                },
-            ],
-        )
+        .function("send")
+        .arguments(&[
+            BorshToken::FixedBytes(new.to_vec()),
+            BorshToken::Uint {
+                width: 64,
+                value: BigInt::from(102u8),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(new),
+            is_signer: false,
+            is_writable: true,
+        }])
+        .call()
         .unwrap();
 
     assert_eq!(returns, BorshToken::Bool(true));
 
     assert_eq!(vm.account_data.get_mut(&new).unwrap().lamports, 107);
 
-    assert_eq!(
-        vm.account_data.get_mut(&vm.stack[0].data).unwrap().lamports,
-        1
-    );
+    assert_eq!(vm.account_data.get_mut(&data_account).unwrap().lamports, 1);
 }
 
 #[test]
@@ -141,9 +167,13 @@ fn send_overflows() {
         }"#,
     );
 
-    vm.account_data.get_mut(&vm.stack[0].data).unwrap().lamports = 103;
+    let data_account = vm.initialize_data_account();
+
+    vm.account_data.get_mut(&data_account).unwrap().lamports = 103;
 
-    vm.constructor(&[]);
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let new = account_new();
 
@@ -157,16 +187,21 @@ fn send_overflows() {
     );
 
     let returns = vm
-        .function(
-            "send",
-            &[
-                BorshToken::FixedBytes(new.to_vec()),
-                BorshToken::Uint {
-                    width: 64,
-                    value: BigInt::from(102u8),
-                },
-            ],
-        )
+        .function("send")
+        .arguments(&[
+            BorshToken::Address(new),
+            BorshToken::Uint {
+                width: 64,
+                value: BigInt::from(102u8),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(new),
+            is_signer: false,
+            is_writable: true,
+        }])
+        .call()
         .unwrap();
 
     assert_eq!(returns, BorshToken::Bool(false));
@@ -177,7 +212,7 @@ fn send_overflows() {
     );
 
     assert_eq!(
-        vm.account_data.get_mut(&vm.stack[0].data).unwrap().lamports,
+        vm.account_data.get_mut(&data_account).unwrap().lamports,
         103
     );
 }
@@ -193,9 +228,12 @@ fn transfer_succeeds() {
         }"#,
     );
 
-    vm.account_data.get_mut(&vm.stack[0].data).unwrap().lamports = 103;
+    let data_account = vm.initialize_data_account();
+    vm.account_data.get_mut(&data_account).unwrap().lamports = 103;
 
-    vm.constructor(&[]);
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let new = account_new();
 
@@ -208,23 +246,25 @@ fn transfer_succeeds() {
         },
     );
 
-    vm.function(
-        "transfer",
-        &[
-            BorshToken::FixedBytes(new.to_vec()),
+    vm.function("transfer")
+        .arguments(&[
+            BorshToken::Address(new),
             BorshToken::Uint {
                 width: 64,
                 value: BigInt::from(102u8),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(new),
+            is_signer: false,
+            is_writable: true,
+        }])
+        .call();
 
     assert_eq!(vm.account_data.get_mut(&new).unwrap().lamports, 107);
 
-    assert_eq!(
-        vm.account_data.get_mut(&vm.stack[0].data).unwrap().lamports,
-        1
-    );
+    assert_eq!(vm.account_data.get_mut(&data_account).unwrap().lamports, 1);
 }
 
 #[test]
@@ -238,9 +278,12 @@ fn transfer_fails_not_enough() {
         }"#,
     );
 
-    vm.account_data.get_mut(&vm.stack[0].data).unwrap().lamports = 103;
+    let data_account = vm.initialize_data_account();
+    vm.account_data.get_mut(&data_account).unwrap().lamports = 103;
 
-    vm.constructor(&[]);
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let new = account_new();
 
@@ -253,16 +296,22 @@ fn transfer_fails_not_enough() {
         },
     );
 
-    let res = vm.function_must_fail(
-        "transfer",
-        &[
-            BorshToken::FixedBytes(new.to_vec()),
+    let res = vm
+        .function("transfer")
+        .arguments(&[
+            BorshToken::Address(new),
             BorshToken::Uint {
                 width: 64,
                 value: BigInt::from(104u8),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(new),
+            is_signer: false,
+            is_writable: true,
+        }])
+        .must_fail();
     assert!(res.is_err());
 }
 
@@ -279,9 +328,12 @@ fn transfer_fails_overflow() {
         }"#,
     );
 
-    vm.account_data.get_mut(&vm.stack[0].data).unwrap().lamports = 103;
+    let data_account = vm.initialize_data_account();
+    vm.account_data.get_mut(&data_account).unwrap().lamports = 103;
 
-    vm.constructor(&[]);
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let new = account_new();
 
@@ -294,16 +346,22 @@ fn transfer_fails_overflow() {
         },
     );
 
-    let res = vm.function_must_fail(
-        "transfer",
-        &[
+    let res = vm
+        .function("transfer")
+        .arguments(&[
             BorshToken::FixedBytes(new.to_vec()),
             BorshToken::Uint {
                 width: 64,
                 value: BigInt::from(104u8),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(new),
+            is_writable: false,
+            is_signer: true,
+        }])
+        .must_fail();
     assert!(res.is_err());
 }
 
@@ -318,9 +376,10 @@ fn fallback() {
         }"#,
     );
 
-    vm.account_data.get_mut(&vm.origin).unwrap().lamports = 312;
-
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     if let Some(idl) = &vm.stack[0].idl {
         let mut idl = idl.clone();
@@ -336,7 +395,7 @@ fn fallback() {
         vm.stack[0].idl = Some(idl);
     }
 
-    vm.function("extinct", &[]);
+    vm.function("extinct").call();
 
     assert_eq!(vm.logs, "fallback");
 }
@@ -354,9 +413,12 @@ fn value_overflows() {
         }"#,
     );
 
-    vm.account_data.get_mut(&vm.stack[0].data).unwrap().lamports = 103;
+    let data_account = vm.initialize_data_account();
+    vm.account_data.get_mut(&data_account).unwrap().lamports = 103;
 
-    vm.constructor(&[]);
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let new = account_new();
 
@@ -369,42 +431,59 @@ fn value_overflows() {
         },
     );
 
-    let res = vm.function_must_fail(
-        "send",
-        &[
-            BorshToken::FixedBytes(new.to_vec()),
+    let res = vm
+        .function("send")
+        .arguments(&[
+            BorshToken::Address(new),
             BorshToken::Uint {
                 width: 128,
                 value: BigInt::from(u64::MAX as u128 + 1),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(new),
+            is_signer: false,
+            is_writable: true,
+        }])
+        .must_fail();
     assert_eq!(res.unwrap(), 4294967296);
 
-    let res = vm.function_must_fail(
-        "send",
-        &[
-            BorshToken::FixedBytes(new.to_vec()),
+    let res = vm
+        .function("send")
+        .arguments(&[
+            BorshToken::Address(new),
             BorshToken::Uint {
                 width: 128,
                 value: BigInt::from(u128::MAX),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(new),
+            is_signer: false,
+            is_writable: true,
+        }])
+        .must_fail();
 
     assert_eq!(res.unwrap(), 4294967296);
 
     let returns = vm
-        .function(
-            "send",
-            &[
-                BorshToken::FixedBytes(new.to_vec()),
-                BorshToken::Uint {
-                    width: 128,
-                    value: BigInt::from(102u8),
-                },
-            ],
-        )
+        .function("send")
+        .arguments(&[
+            BorshToken::Address(new),
+            BorshToken::Uint {
+                width: 128,
+                value: BigInt::from(102u8),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(new),
+            is_signer: false,
+            is_writable: true,
+        }])
+        .call()
         .unwrap();
 
     assert_eq!(returns, BorshToken::Bool(false));
@@ -415,7 +494,7 @@ fn value_overflows() {
     );
 
     assert_eq!(
-        vm.account_data.get_mut(&vm.stack[0].data).unwrap().lamports,
+        vm.account_data.get_mut(&data_account).unwrap().lamports,
         103
     );
 }

+ 12 - 3
tests/solana_tests/base58_encoding.rs

@@ -20,11 +20,17 @@ contract Base58 {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     for _ in 0..10 {
         let account = account_new();
-        let _ = vm.function("print_this", &[BorshToken::Address(account)]);
+        let _ = vm
+            .function("print_this")
+            .arguments(&[BorshToken::Address(account)])
+            .call();
         let mut base_58 = account.to_base58();
         while base_58.len() < 44 {
             // Rust's to_base58() ignores leading zeros in the byte array,
@@ -35,7 +41,10 @@ contract Base58 {
         }
         assert_eq!(vm.logs, base_58);
         vm.logs.clear();
-        let _ = vm.function("print_as_hex", &[BorshToken::Address(account)]);
+        let _ = vm
+            .function("print_as_hex")
+            .arguments(&[BorshToken::Address(account)])
+            .call();
         let decoded = hex::decode(vm.logs.as_str()).unwrap();
         assert_eq!(account, decoded.as_ref());
         vm.logs.clear();

+ 105 - 34
tests/solana_tests/builtin.rs

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: Apache-2.0
 
 use crate::{build_solidity, BorshToken};
-use base58::ToBase58;
+use base58::{FromBase58, ToBase58};
 use num_bigint::BigInt;
 
 #[test]
@@ -30,9 +30,25 @@ fn builtins() {
         }"#,
     );
 
-    vm.constructor(&[]);
-
-    let returns = vm.function("mr_now", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
+    let clock_account = <[u8; 32]>::try_from(
+        "SysvarC1ock11111111111111111111111111111111"
+            .from_base58()
+            .unwrap(),
+    )
+    .unwrap();
+    let returns = vm
+        .function("mr_now")
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("clock", clock_account),
+        ])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -42,7 +58,14 @@ fn builtins() {
         }
     );
 
-    let returns = vm.function("mr_slot", &[]).unwrap();
+    let returns = vm
+        .function("mr_slot")
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("clock", clock_account),
+        ])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -52,7 +75,14 @@ fn builtins() {
         }
     );
 
-    let returns = vm.function("mr_blocknumber", &[]).unwrap();
+    let returns = vm
+        .function("mr_blocknumber")
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("clock", clock_account),
+        ])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -63,13 +93,13 @@ fn builtins() {
     );
 
     let returns = vm
-        .function(
-            "msg_data",
-            &[BorshToken::Uint {
-                width: 32,
-                value: BigInt::from(0xdeadcafeu32),
-            }],
-        )
+        .function("msg_data")
+        .arguments(&[BorshToken::Uint {
+            width: 32,
+            value: BigInt::from(0xdeadcafeu32),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     if let BorshToken::Bytes(v) = &returns {
@@ -81,7 +111,11 @@ fn builtins() {
         BorshToken::Bytes(hex::decode("a73fcaa3b216e85afecaadde").unwrap())
     );
 
-    let returns = vm.function("sig", &[]).unwrap();
+    let returns = vm
+        .function("sig")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     if let Some(v) = returns.clone().into_fixed_bytes() {
         println!("{}", hex::encode(v));
@@ -92,9 +126,13 @@ fn builtins() {
         BorshToken::uint8_fixed_array(hex::decode("4b22101a3c98d6cb").unwrap())
     );
 
-    let returns = vm.function("prog", &[]).unwrap();
+    let returns = vm
+        .function("prog")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
-    assert_eq!(returns, BorshToken::Address(vm.stack[0].program));
+    assert_eq!(returns, BorshToken::Address(vm.stack[0].id));
 }
 
 #[test]
@@ -133,10 +171,19 @@ fn pda() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function("create_pda", &[BorshToken::Bool(true)])
+        .function("create_pda")
+        .arguments(&[BorshToken::Bool(true)])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .call()
         .unwrap();
 
     if let Some(bs) = returns.clone().into_fixed_bytes() {
@@ -149,7 +196,13 @@ fn pda() {
     }
 
     let returns = vm
-        .function("create_pda", &[BorshToken::Bool(false)])
+        .function("create_pda")
+        .arguments(&[BorshToken::Bool(false)])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .call()
         .unwrap();
 
     if let Some(bs) = returns.clone().into_fixed_bytes() {
@@ -162,13 +215,16 @@ fn pda() {
     }
 
     let returns = vm
-        .function(
-            "create_pda2",
-            &[
-                BorshToken::Bytes(b"Talking".to_vec()),
-                BorshToken::Bytes(b"Squirrels".to_vec()),
-            ],
-        )
+        .function("create_pda2")
+        .arguments(&[
+            BorshToken::Bytes(b"Talking".to_vec()),
+            BorshToken::Bytes(b"Squirrels".to_vec()),
+        ])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .call()
         .unwrap();
 
     if let Some(bs) = returns.clone().into_fixed_bytes() {
@@ -181,7 +237,10 @@ fn pda() {
     }
 
     let returns = vm
-        .function("create_pda2_bump", &[BorshToken::Bool(true)])
+        .function("create_pda2_bump")
+        .arguments(&[BorshToken::Bool(true)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
 
@@ -197,7 +256,10 @@ fn pda() {
     }
 
     let returns = vm
-        .function("create_pda2_bump", &[BorshToken::Bool(false)])
+        .function("create_pda2_bump")
+        .arguments(&[BorshToken::Bool(false)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
 
@@ -229,8 +291,11 @@ fn test_string_bytes_buffer_write() {
     }
         "#,
     );
-    vm.constructor(&[]);
-    let returns = vm.function("testStringAndBytes", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm.function("testStringAndBytes").call().unwrap();
     let bytes = returns.into_bytes().unwrap();
 
     assert_eq!(bytes.len(), 9);
@@ -254,8 +319,11 @@ fn out_of_bounds_bytes_write() {
         "#,
     );
 
-    vm.constructor(&[]);
-    let _ = vm.function("testBytesOut", &[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let _ = vm.function("testBytesOut").call();
 }
 
 #[test]
@@ -274,6 +342,9 @@ fn out_of_bounds_string_write() {
         "#,
     );
 
-    vm.constructor(&[]);
-    let _ = vm.function("testStringOut", &[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let _ = vm.function("testStringOut").call();
 }

+ 280 - 103
tests/solana_tests/call.rs

@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: Apache-2.0
 
 use crate::{
-    build_solidity, create_program_address, BorshToken, Instruction, Pubkey, VirtualMachine,
+    build_solidity, create_program_address, AccountMeta, AccountState, BorshToken, Instruction,
+    Pubkey, VirtualMachine,
 };
 use base58::FromBase58;
 use num_bigint::BigInt;
@@ -28,30 +29,56 @@ fn simple_external_call() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let bar1_account = vm.initialize_data_account();
+    let bar1_program_id = vm.stack[0].id;
+    vm.function("new")
+        .accounts(vec![("dataAccount", bar1_account)])
+        .call();
 
-    vm.function("test_bar", &[BorshToken::String(String::from("yo"))]);
+    vm.function("test_bar")
+        .accounts(vec![("dataAccount", bar1_account)])
+        .arguments(&[BorshToken::String(String::from("yo"))])
+        .call();
 
     assert_eq!(vm.logs, "bar1 says: yo");
 
     vm.logs.truncate(0);
 
-    let bar1_account = vm.stack[0].data;
-
     vm.set_program(0);
 
-    vm.constructor(&[]);
+    let bar0_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", bar0_account)])
+        .call();
 
-    vm.function(
-        "test_bar",
-        &[BorshToken::String(String::from("uncle beau"))],
-    );
+    vm.function("test_bar")
+        .accounts(vec![("dataAccount", bar0_account)])
+        .arguments(&[BorshToken::String(String::from("uncle beau"))])
+        .call();
 
     assert_eq!(vm.logs, "bar0 says: uncle beau");
 
     vm.logs.truncate(0);
 
-    vm.function("test_other", &[BorshToken::Address(bar1_account)]);
+    vm.function("test_other")
+        .accounts(vec![
+            ("dataAccount", bar0_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .remaining_accounts(&[
+            AccountMeta {
+                pubkey: Pubkey(bar1_account),
+                is_writable: false,
+                is_signer: false,
+            },
+            AccountMeta {
+                pubkey: Pubkey(bar1_program_id),
+                is_signer: false,
+                is_writable: false,
+            },
+        ])
+        .arguments(&[BorshToken::Address(bar1_account)])
+        .call();
 
     assert_eq!(vm.logs, "bar1 says: cross contract call");
 }
@@ -73,16 +100,20 @@ fn external_call_with_returns() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let bar1_account = vm.initialize_data_account();
+    let bar1_program_id = vm.stack[0].id;
+    vm.function("new")
+        .accounts(vec![("dataAccount", bar1_account)])
+        .call();
 
     let res = vm
-        .function(
-            "test_bar",
-            &[BorshToken::Int {
-                width: 64,
-                value: BigInt::from(21),
-            }],
-        )
+        .function("test_bar")
+        .accounts(vec![("dataAccount", bar1_account)])
+        .arguments(&[BorshToken::Int {
+            width: 64,
+            value: BigInt::from(21),
+        }])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -93,14 +124,33 @@ fn external_call_with_returns() {
         }
     );
 
-    let bar1_account = vm.stack[0].data;
-
     vm.set_program(0);
 
-    vm.constructor(&[]);
+    let bar0_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", bar0_account)])
+        .call();
 
     let res = vm
-        .function("test_other", &[BorshToken::Address(bar1_account)])
+        .function("test_other")
+        .arguments(&[BorshToken::Address(bar1_account)])
+        .accounts(vec![
+            ("dataAccount", bar0_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .remaining_accounts(&[
+            AccountMeta {
+                pubkey: Pubkey(bar1_account),
+                is_writable: false,
+                is_signer: false,
+            },
+            AccountMeta {
+                pubkey: Pubkey(bar1_program_id),
+                is_signer: false,
+                is_writable: false,
+            },
+        ])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -136,16 +186,20 @@ fn external_raw_call_with_returns() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let bar1_account = vm.initialize_data_account();
+    let bar1_program_id = vm.stack[0].id;
+    vm.function("new")
+        .accounts(vec![("dataAccount", bar1_account)])
+        .call();
 
     let res = vm
-        .function(
-            "test_bar",
-            &[BorshToken::Int {
-                width: 64,
-                value: BigInt::from(21u8),
-            }],
-        )
+        .function("test_bar")
+        .arguments(&[BorshToken::Int {
+            width: 64,
+            value: BigInt::from(21u8),
+        }])
+        .accounts(vec![("dataAccount", bar1_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -156,14 +210,33 @@ fn external_raw_call_with_returns() {
         }
     );
 
-    let bar1_account = vm.stack[0].data;
-
     vm.set_program(0);
 
-    vm.constructor(&[]);
+    let bar0_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", bar0_account)])
+        .call();
 
     let res = vm
-        .function("test_other", &[BorshToken::Address(bar1_account)])
+        .function("test_other")
+        .arguments(&[BorshToken::Address(bar1_account)])
+        .accounts(vec![
+            ("dataAccount", bar0_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .remaining_accounts(&[
+            AccountMeta {
+                pubkey: Pubkey(bar1_account),
+                is_writable: false,
+                is_signer: false,
+            },
+            AccountMeta {
+                pubkey: Pubkey(bar1_program_id),
+                is_signer: false,
+                is_writable: false,
+            },
+        ])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -195,9 +268,20 @@ fn call_external_func_type() {
     "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let res = vm.function("doTest", &[]).unwrap().unwrap_tuple();
+    let res = vm
+        .function("doTest")
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .call()
+        .unwrap()
+        .unwrap_tuple();
 
     assert_eq!(
         res,
@@ -242,33 +326,74 @@ fn external_call_with_string_returns() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let bar1_account = vm.initialize_data_account();
+    let bar1_program_id = vm.stack[0].id;
+    vm.function("new")
+        .accounts(vec![("dataAccount", bar1_account)])
+        .call();
 
     let res = vm
-        .function(
-            "test_bar",
-            &[BorshToken::Int {
-                width: 64,
-                value: BigInt::from(22u8),
-            }],
-        )
+        .function("test_bar")
+        .arguments(&[BorshToken::Int {
+            width: 64,
+            value: BigInt::from(22u8),
+        }])
+        .accounts(vec![("dataAccount", bar1_account)])
+        .call()
         .unwrap();
 
     assert_eq!(res, BorshToken::String(String::from("foo:22")));
 
-    let bar1_account = vm.stack[0].data;
-
     vm.set_program(0);
 
-    vm.constructor(&[]);
+    let bar0_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", bar0_account)])
+        .call();
 
     let res = vm
-        .function("test_other", &[BorshToken::Address(bar1_account)])
+        .function("test_other")
+        .arguments(&[BorshToken::Address(bar1_account)])
+        .accounts(vec![
+            ("dataAccount", bar0_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .remaining_accounts(&[
+            AccountMeta {
+                pubkey: Pubkey(bar1_account),
+                is_writable: false,
+                is_signer: false,
+            },
+            AccountMeta {
+                pubkey: Pubkey(bar1_program_id),
+                is_signer: false,
+                is_writable: false,
+            },
+        ])
+        .call()
         .unwrap();
 
     assert_eq!(res, BorshToken::String(String::from("foo:7")));
 
-    vm.function("test_this", &[BorshToken::Address(bar1_account)]);
+    vm.function("test_this")
+        .arguments(&[BorshToken::Address(bar1_account)])
+        .accounts(vec![
+            ("dataAccount", bar0_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .remaining_accounts(&[
+            AccountMeta {
+                pubkey: Pubkey(bar1_account),
+                is_writable: false,
+                is_signer: false,
+            },
+            AccountMeta {
+                pubkey: Pubkey(bar1_program_id),
+                is_signer: false,
+                is_writable: false,
+            },
+        ])
+        .call();
 }
 
 #[test]
@@ -295,16 +420,20 @@ fn encode_call() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let bar1_account = vm.initialize_data_account();
+    let bar1_program_id = vm.stack[0].id;
+    vm.function("new")
+        .accounts(vec![("dataAccount", bar1_account)])
+        .call();
 
     let res = vm
-        .function(
-            "test_bar",
-            &[BorshToken::Int {
-                width: 64,
-                value: BigInt::from(21u8),
-            }],
-        )
+        .function("test_bar")
+        .arguments(&[BorshToken::Int {
+            width: 64,
+            value: BigInt::from(21u8),
+        }])
+        .accounts(vec![("dataAccount", bar1_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -315,14 +444,33 @@ fn encode_call() {
         }
     );
 
-    let bar1_account = vm.stack[0].data;
-
     vm.set_program(0);
 
-    vm.constructor(&[]);
+    let bar0_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", bar0_account)])
+        .call();
 
     let res = vm
-        .function("test_other", &[BorshToken::Address(bar1_account)])
+        .function("test_other")
+        .arguments(&[BorshToken::Address(bar1_account)])
+        .accounts(vec![
+            ("dataAccount", bar0_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .remaining_accounts(&[
+            AccountMeta {
+                pubkey: Pubkey(bar1_account),
+                is_writable: false,
+                is_signer: false,
+            },
+            AccountMeta {
+                pubkey: Pubkey(bar1_program_id),
+                is_signer: false,
+                is_writable: false,
+            },
+        ])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -363,26 +511,33 @@ fn internal_function_storage() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let res = vm.function("set_op", &[BorshToken::Bool(true)]);
+    let res = vm
+        .function("set_op")
+        .arguments(&[BorshToken::Bool(true)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert!(res.is_none());
 
     let res = vm
-        .function(
-            "test",
-            &[
-                BorshToken::Int {
-                    width: 32,
-                    value: BigInt::from(3u8),
-                },
-                BorshToken::Int {
-                    width: 32,
-                    value: BigInt::from(5u8),
-                },
-            ],
-        )
+        .function("test")
+        .arguments(&[
+            BorshToken::Int {
+                width: 32,
+                value: BigInt::from(3u8),
+            },
+            BorshToken::Int {
+                width: 32,
+                value: BigInt::from(5u8),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -393,24 +548,28 @@ fn internal_function_storage() {
         }
     );
 
-    let res = vm.function("set_op", &[BorshToken::Bool(false)]);
+    let res = vm
+        .function("set_op")
+        .arguments(&[BorshToken::Bool(false)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert!(res.is_none());
 
     let res = vm
-        .function(
-            "test",
-            &[
-                BorshToken::Int {
-                    width: 32,
-                    value: BigInt::from(3u8),
-                },
-                BorshToken::Int {
-                    width: 32,
-                    value: BigInt::from(5u8),
-                },
-            ],
-        )
+        .function("test")
+        .arguments(&[
+            BorshToken::Int {
+                width: 32,
+                value: BigInt::from(3u8),
+            },
+            BorshToken::Int {
+                width: 32,
+                value: BigInt::from(5u8),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -459,7 +618,10 @@ fn raw_call_accounts() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let token = Pubkey(
         "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
@@ -468,6 +630,7 @@ fn raw_call_accounts() {
             .try_into()
             .unwrap(),
     );
+    vm.account_data.insert(token.0, AccountState::default());
 
     let test_args = |_vm: &VirtualMachine, instr: &Instruction, _signers: &[Pubkey]| {
         let sysvar_rent = Pubkey(
@@ -503,19 +666,23 @@ fn raw_call_accounts() {
         assert_eq!(instr.accounts[1].pubkey, sysvar_rent);
     };
 
-    vm.call_params_check.insert(token, test_args);
+    vm.call_params_check.insert(token.clone(), test_args);
 
-    vm.function(
-        "create_mint_with_freezeauthority",
-        &[
+    vm.function("create_mint_with_freezeauthority")
+        .arguments(&[
             BorshToken::Uint {
                 width: 8,
                 value: BigInt::from(11u8),
             },
             BorshToken::Address(b"quinquagintaquadringentilliardth".to_owned()),
             BorshToken::Address(b"quinquagintaquadringentillionths".to_owned()),
-        ],
-    );
+        ])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("tokenProgram", token.0),
+            ("systemProgram", [0; 32]),
+        ])
+        .call();
 }
 
 #[test]
@@ -540,16 +707,19 @@ fn pda() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let test_args = |vm: &VirtualMachine, _instr: &Instruction, signers: &[Pubkey]| {
         assert_eq!(
             signers[0],
-            create_program_address(&vm.stack[0].program, &[b"foo"])
+            create_program_address(&vm.stack[0].id, &[b"foo"])
         );
         assert_eq!(
             signers[1],
-            create_program_address(&vm.stack[0].program, &[b"bar"])
+            create_program_address(&vm.stack[0].id, &[b"bar"])
         );
     };
 
@@ -561,7 +731,14 @@ fn pda() {
             .unwrap(),
     );
 
-    vm.call_params_check.insert(token, test_args);
+    vm.account_data.insert(token.0, AccountState::default());
+    vm.call_params_check.insert(token.clone(), test_args);
 
-    vm.function("test", &[]);
+    vm.function("test")
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("tokenProgram", token.0),
+            ("systemProgram", [0; 32]),
+        ])
+        .call();
 }

+ 18 - 4
tests/solana_tests/constant.rs

@@ -20,9 +20,16 @@ fn constant() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("f", &[]).unwrap();
+    let returns = vm
+        .function("f")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Uint {
@@ -46,9 +53,16 @@ fn constant() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("f", &[]).unwrap();
+    let returns = vm
+        .function("f")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Uint {

+ 312 - 125
tests/solana_tests/create_contract.rs

@@ -11,8 +11,8 @@ fn simple_create_contract_no_seed() {
     let mut vm = build_solidity(
         r#"
         contract bar0 {
-            function test_other(address foo, address payer) external returns (bar1) {
-                bar1 x = new bar1{address: foo}("yo from bar0", payer);
+            function test_other(address foo) external returns (bar1) {
+                bar1 x = new bar1{address: foo}("yo from bar0");
 
                 return x;
             }
@@ -25,7 +25,7 @@ fn simple_create_contract_no_seed() {
         @program_id("CPDgqnhHDCsjFkJKMturRQ1QeM9EXZg3EYCeDoRP8pdT")
         contract bar1 {
             @payer(payer)
-            constructor(string v, address payer) {
+            constructor(string v) {
                 print("bar1 says: " + v);
             }
 
@@ -37,7 +37,10 @@ fn simple_create_contract_no_seed() {
 
     vm.set_program(0);
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let program_id: Account = "CPDgqnhHDCsjFkJKMturRQ1QeM9EXZg3EYCeDoRP8pdT"
         .from_base58()
@@ -50,6 +53,7 @@ fn simple_create_contract_no_seed() {
 
     println!("new account: {}", acc.to_base58());
 
+    vm.account_data.insert(payer, AccountState::default());
     vm.account_data.insert(
         acc,
         AccountState {
@@ -59,13 +63,20 @@ fn simple_create_contract_no_seed() {
         },
     );
 
-    vm.account_data.insert([0; 32], AccountState::default());
-
     let bar1 = vm
-        .function(
-            "test_other",
-            &[BorshToken::Address(acc), BorshToken::Address(payer)],
-        )
+        .function("test_other")
+        .arguments(&[BorshToken::Address(acc)])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("payer", payer),
+            ("systemProgram", [0; 32]),
+        ])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(acc),
+            is_writable: true,
+            is_signer: true,
+        }])
+        .call()
         .unwrap();
 
     assert_eq!(vm.logs, "bar1 says: yo from bar0");
@@ -74,10 +85,25 @@ fn simple_create_contract_no_seed() {
 
     vm.logs.truncate(0);
 
-    vm.function(
-        "call_bar1_at_address",
-        &[bar1, BorshToken::String(String::from("xywoleh"))],
-    );
+    vm.function("call_bar1_at_address")
+        .arguments(&[bar1, BorshToken::String(String::from("xywoleh"))])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .remaining_accounts(&[
+            AccountMeta {
+                pubkey: Pubkey(acc),
+                is_signer: false,
+                is_writable: false,
+            },
+            AccountMeta {
+                pubkey: Pubkey(program_id),
+                is_writable: false,
+                is_signer: false,
+            },
+        ])
+        .call();
 
     assert_eq!(vm.logs, "Hello xywoleh");
 }
@@ -87,8 +113,8 @@ fn simple_create_contract() {
     let mut vm = build_solidity(
         r#"
         contract bar0 {
-            function test_other(address foo, address payer) external returns (bar1) {
-                bar1 x = new bar1{address: foo}("yo from bar0", payer);
+            function test_other(address foo) external returns (bar1) {
+                bar1 x = new bar1{address: foo}("yo from bar0");
 
                 return x;
             }
@@ -101,7 +127,7 @@ fn simple_create_contract() {
         @program_id("CPDgqnhHDCsjFkJKMturRQ1QeM9EXZg3EYCeDoRP8pdT")
         contract bar1 {
             @payer(pay)
-            constructor(string v, address pay) {
+            constructor(string v) {
                 print("bar1 says: " + v);
             }
 
@@ -113,8 +139,10 @@ fn simple_create_contract() {
 
     vm.set_program(0);
 
-    vm.constructor(&[]);
-
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let program_id: Account = "CPDgqnhHDCsjFkJKMturRQ1QeM9EXZg3EYCeDoRP8pdT"
         .from_base58()
         .unwrap()
@@ -124,13 +152,22 @@ fn simple_create_contract() {
     let seed = vm.create_pda(&program_id);
     let payer = account_new();
 
-    vm.account_data.insert([0; 32], AccountState::default());
+    vm.account_data.insert(payer, AccountState::default());
 
     let bar1 = vm
-        .function(
-            "test_other",
-            &[BorshToken::Address(seed.0), BorshToken::Address(payer)],
-        )
+        .function("test_other")
+        .arguments(&[BorshToken::Address(seed.0)])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("pay", payer),
+            ("systemProgram", [0; 32]),
+        ])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(seed.0),
+            is_signer: false,
+            is_writable: true,
+        }])
+        .call()
         .unwrap();
 
     assert_eq!(vm.logs, "bar1 says: yo from bar0");
@@ -139,10 +176,25 @@ fn simple_create_contract() {
 
     println!("next test, {bar1:?}");
 
-    vm.function(
-        "call_bar1_at_address",
-        &[bar1, BorshToken::String(String::from("xywoleh"))],
-    );
+    vm.function("call_bar1_at_address")
+        .arguments(&[bar1, BorshToken::String(String::from("xywoleh"))])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .remaining_accounts(&[
+            AccountMeta {
+                pubkey: Pubkey(seed.0),
+                is_signer: false,
+                is_writable: false,
+            },
+            AccountMeta {
+                pubkey: Pubkey(program_id),
+                is_writable: false,
+                is_signer: false,
+            },
+        ])
+        .call();
 
     assert_eq!(vm.logs, "Hello xywoleh");
 }
@@ -156,9 +208,12 @@ fn create_contract_wrong_program_id() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let program = &vm.programs[0].program;
+    let program = &vm.programs[0].id;
     let code = vm.account_data[program].data.clone();
 
     let mut vm = build_solidity(
@@ -168,10 +223,14 @@ fn create_contract_wrong_program_id() {
         "#,
     );
 
-    let program = &vm.programs[0].program;
+    let program = &vm.programs[0].id;
     vm.account_data.get_mut(program).unwrap().data = code;
 
-    vm.constructor_expected(7 << 32, &vm.default_metas(), &[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .expected(7 << 32)
+        .call();
 
     assert_eq!(
         vm.logs,
@@ -188,9 +247,15 @@ fn call_constructor_twice() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.constructor_expected(2, &vm.default_metas(), &[]);
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .expected(2)
+        .call();
 }
 
 #[test]
@@ -201,7 +266,7 @@ fn create_contract_with_payer() {
             uint64 v;
 
             @payer(p)
-            constructor(address p) {
+            constructor() {
                 v = 102;
             }
 
@@ -211,14 +276,22 @@ fn create_contract_with_payer() {
         }"#,
     );
 
-    // 'remove' the data account
-    let data = vm.programs[0].data;
-    vm.account_data.get_mut(&data).unwrap().data.truncate(0);
     let payer = account_new();
-
-    vm.constructor(&[BorshToken::Address(payer)]);
-
-    let ret = vm.function("f", &[]).unwrap();
+    vm.account_data.insert(payer, AccountState::default());
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("p", payer),
+            ("systemProgram", [0; 32]),
+        ])
+        .call();
+
+    let ret = vm
+        .function("f")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         ret,
@@ -260,15 +333,41 @@ fn missing_contract() {
     );
 
     vm.set_program(0);
-
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let missing = account_new();
-
     vm.logs.clear();
     vm.account_data.insert(missing, AccountState::default());
+    let program_id: Account = "7vJKRaKLGCNUPuHWdeHCTknkYf3dHXXEZ6ri7dc6ngeV"
+        .from_base58()
+        .unwrap()
+        .try_into()
+        .unwrap();
+
     // There is no payer account, so the external call fails.
-    let _ = vm.function_must_fail("test_other", &[BorshToken::Address(missing)]);
+    let _ = vm
+        .function("test_other")
+        .arguments(&[BorshToken::Address(missing)])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .remaining_accounts(&[
+            AccountMeta {
+                pubkey: Pubkey(missing),
+                is_signer: true,
+                is_writable: false,
+            },
+            AccountMeta {
+                pubkey: Pubkey(program_id),
+                is_writable: false,
+                is_signer: false,
+            },
+        ])
+        .must_fail();
 }
 
 #[test]
@@ -294,8 +393,10 @@ fn two_contracts() {
     );
 
     vm.set_program(0);
-
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let program_id: Account = "CPDgqnhHDCsjFkJKMturRQ1QeM9EXZg3EYCeDoRP8pdT"
         .from_base58()
@@ -305,12 +406,37 @@ fn two_contracts() {
 
     let seed1 = vm.create_pda(&program_id);
     let seed2 = vm.create_pda(&program_id);
+    let payer = account_new();
+    vm.account_data.insert(seed1.0, AccountState::default());
+    vm.account_data.insert(seed2.0, AccountState::default());
+    vm.account_data.insert(payer, AccountState::default());
 
-    vm.account_data.insert([0; 32], AccountState::default());
-    let _bar1 = vm.function(
-        "test_other",
-        &[BorshToken::Address(seed1.0), BorshToken::Address(seed2.0)],
-    );
+    let _bar1 = vm
+        .function("test_other")
+        .arguments(&[BorshToken::Address(seed1.0), BorshToken::Address(seed2.0)])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+            ("payer_account", payer),
+        ])
+        .remaining_accounts(&[
+            AccountMeta {
+                pubkey: Pubkey(seed1.0),
+                is_signer: true,
+                is_writable: true,
+            },
+            AccountMeta {
+                pubkey: Pubkey(seed2.0),
+                is_signer: true,
+                is_writable: true,
+            },
+            AccountMeta {
+                pubkey: Pubkey(program_id),
+                is_writable: false,
+                is_signer: false,
+            },
+        ])
+        .call();
 
     assert_eq!(vm.logs, "bar1 says: yo from bar0bar1 says: hi from bar0");
 
@@ -326,11 +452,17 @@ fn account_too_small() {
         }"#,
     );
 
-    let data = vm.stack[0].data;
-
-    vm.account_data.get_mut(&data).unwrap().data.truncate(100);
+    let data_account = vm.initialize_data_account();
+    vm.account_data
+        .get_mut(&data_account)
+        .unwrap()
+        .data
+        .truncate(100);
 
-    vm.constructor_expected(5 << 32, &vm.default_metas(), &[]);
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .expected(5 << 32)
+        .call();
 }
 
 #[test]
@@ -340,7 +472,7 @@ fn account_with_space() {
         contract bar {
 
             @payer(payer)
-            constructor(@space uint64 x, address payer) {}
+            constructor(@space uint64 x) {}
 
             function hello() public returns (bool) {
                 return true;
@@ -349,23 +481,37 @@ fn account_with_space() {
         "#,
     );
 
-    let data = vm.stack[0].data;
-
-    vm.account_data.get_mut(&data).unwrap().data.truncate(0);
+    let data_account = vm.initialize_data_account();
+    vm.account_data
+        .get_mut(&data_account)
+        .unwrap()
+        .data
+        .truncate(0);
 
     let payer = account_new();
+    vm.account_data.insert(payer, AccountState::default());
 
-    vm.constructor(&[
-        BorshToken::Uint {
+    vm.function("new")
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("payer", payer),
+            ("systemProgram", [0; 32]),
+        ])
+        .arguments(&[BorshToken::Uint {
             width: 64,
             value: 306.into(),
-        },
-        BorshToken::Address(payer),
-    ]);
-
-    assert_eq!(vm.account_data.get_mut(&data).unwrap().data.len(), 306);
+        }])
+        .call();
+    assert_eq!(
+        vm.account_data.get_mut(&data_account).unwrap().data.len(),
+        306
+    );
 
-    let ret = vm.function("hello", &[]).unwrap();
+    let ret = vm
+        .function("hello")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(ret, BorshToken::Bool(true));
 }
@@ -387,20 +533,30 @@ fn account_with_seed() {
         "#,
     );
 
-    let program_id = vm.stack[0].program;
-
+    let program_id = vm.stack[0].id;
     let seed = vm.create_pda(&program_id);
+    let payer = account_new();
+    vm.account_data.insert(payer, AccountState::default());
 
-    vm.stack[0].data = seed.0;
-
-    vm.constructor(&[BorshToken::Bytes(seed.1)]);
+    vm.function("new")
+        .accounts(vec![
+            ("dataAccount", seed.0),
+            ("payer", payer),
+            ("systemProgram", [0; 32]),
+        ])
+        .arguments(&[BorshToken::Bytes(seed.1)])
+        .call();
 
     assert_eq!(
         vm.account_data.get_mut(&seed.0).unwrap().data.len(),
         511 + 102
     );
 
-    let ret = vm.function("hello", &[]).unwrap();
+    let ret = vm
+        .function("hello")
+        .accounts(vec![("dataAccount", seed.0)])
+        .call()
+        .unwrap();
 
     assert_eq!(ret, BorshToken::Bool(true));
 }
@@ -422,28 +578,38 @@ fn account_with_seed_bump() {
         "#,
     );
 
-    let program_id = vm.stack[0].program;
+    let program_id = vm.stack[0].id;
 
     let mut seed = vm.create_pda(&program_id);
-
     let bump = seed.1.pop().unwrap();
+    let payer = account_new();
+    vm.account_data.insert(payer, AccountState::default());
 
-    vm.stack[0].data = seed.0;
-
-    vm.constructor(&[
-        BorshToken::Bytes(seed.1),
-        BorshToken::Uint {
-            width: 8,
-            value: bump.into(),
-        },
-    ]);
+    vm.function("new")
+        .arguments(&[
+            BorshToken::Bytes(seed.1),
+            BorshToken::Uint {
+                width: 8,
+                value: bump.into(),
+            },
+        ])
+        .accounts(vec![
+            ("dataAccount", seed.0),
+            ("payer", payer),
+            ("systemProgram", [0; 32]),
+        ])
+        .call();
 
     assert_eq!(
         vm.account_data.get_mut(&seed.0).unwrap().data.len(),
         511 + 102
     );
 
-    let ret = vm.function("hello", &[]).unwrap();
+    let ret = vm
+        .function("hello")
+        .accounts(vec![("dataAccount", seed.0)])
+        .call()
+        .unwrap();
 
     assert_eq!(ret, BorshToken::Bool(true));
 }
@@ -467,22 +633,31 @@ fn account_with_seed_bump_literals() {
         "#,
     );
 
-    let program_id = vm.stack[0].program;
+    let program_id = vm.stack[0].id;
 
     let account = create_program_address(&program_id, &[b"meh!"]);
-
+    let payer = account_new();
     vm.create_empty_account(&account.0, &program_id);
+    vm.account_data.insert(payer, AccountState::default());
 
-    vm.stack[0].data = account.0;
-
-    vm.constructor(&[]);
+    vm.function("new")
+        .accounts(vec![
+            ("dataAccount", account.0),
+            ("my_account", payer),
+            ("systemProgram", [0; 32]),
+        ])
+        .call();
 
     assert_eq!(
         vm.account_data.get_mut(&account.0).unwrap().data.len(),
         8192
     );
 
-    let ret = vm.function("hello", &[]).unwrap();
+    let ret = vm
+        .function("hello")
+        .accounts(vec![("dataAccount", account.0)])
+        .call()
+        .unwrap();
 
     assert_eq!(ret, BorshToken::Bool(true));
 }
@@ -517,19 +692,31 @@ fn create_child() {
     );
 
     vm.set_program(0);
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let payer = account_new();
-
-    let program_id = vm.stack[0].program;
+    let program_id = vm.stack[0].id;
 
     let seed = vm.create_pda(&program_id);
     vm.account_data.insert(payer, AccountState::default());
     vm.account_data.insert(seed.0, AccountState::default());
 
-    vm.account_data.insert([0; 32], AccountState::default());
-
-    vm.function("create_child", &[BorshToken::Address(seed.0)]);
+    vm.function("create_child")
+        .arguments(&[BorshToken::Address(seed.0)])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("payer", payer),
+            ("systemProgram", [0; 32]),
+        ])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(seed.0),
+            is_signer: true,
+            is_writable: true,
+        }])
+        .call();
 
     assert_eq!(
         vm.logs,
@@ -553,7 +740,7 @@ contract creator {
             // Passing the system account here crashes the VM, even if I add it to vm.account_data
             // AccountMeta({pubkey: address"11111111111111111111111111111111", is_writable: false, is_signer: false})
         ];
-        c = new Child{accounts: metas}(payer);
+        c = new Child{accounts: metas}();
         c.say_hello();
     }
 }
@@ -562,7 +749,7 @@ contract creator {
 contract Child {
     @payer(payer)
     @space(511 + 7)
-    constructor(address payer) {
+    constructor() {
         print("In child constructor");
     }
 
@@ -574,36 +761,36 @@ contract Child {
     );
 
     vm.set_program(0);
-
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let payer = account_new();
-
-    let program_id = vm.stack[0].program;
-
+    let program_id = vm.stack[0].id;
     let seed = vm.create_pda(&program_id);
-
     vm.account_data.insert(seed.0, AccountState::default());
-
     vm.account_data.insert(payer, AccountState::default());
 
-    let mut metas = vm.default_metas();
-    metas.push(AccountMeta {
-        pubkey: Pubkey(seed.0),
-        is_signer: false,
-        is_writable: false,
-    });
-    metas.push(AccountMeta {
-        pubkey: Pubkey(payer),
-        is_signer: true,
-        is_writable: false,
-    });
-
-    vm.function_metas(
-        "create_child_with_meta",
-        &metas,
-        &[BorshToken::Address(seed.0), BorshToken::Address(payer)],
-    );
+    vm.function("create_child_with_meta")
+        .arguments(&[BorshToken::Address(seed.0), BorshToken::Address(payer)])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .remaining_accounts(&[
+            AccountMeta {
+                pubkey: Pubkey(seed.0),
+                is_signer: false,
+                is_writable: false,
+            },
+            AccountMeta {
+                pubkey: Pubkey(payer),
+                is_signer: true,
+                is_writable: false,
+            },
+        ])
+        .call();
 
     assert_eq!(
         vm.logs,

+ 46 - 11
tests/solana_tests/destructure.rs

@@ -18,10 +18,16 @@ fn conditional_destructure() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function("f", &[BorshToken::Bool(true), BorshToken::Bool(true)])
+        .function("f")
+        .arguments(&[BorshToken::Bool(true), BorshToken::Bool(true)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
 
@@ -40,7 +46,10 @@ fn conditional_destructure() {
     );
 
     let returns = vm
-        .function("f", &[BorshToken::Bool(true), BorshToken::Bool(false)])
+        .function("f")
+        .arguments(&[BorshToken::Bool(true), BorshToken::Bool(false)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
 
@@ -59,7 +68,10 @@ fn conditional_destructure() {
     );
 
     let returns = vm
-        .function("f", &[BorshToken::Bool(false), BorshToken::Bool(false)])
+        .function("f")
+        .arguments(&[BorshToken::Bool(false), BorshToken::Bool(false)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
 
@@ -78,7 +90,10 @@ fn conditional_destructure() {
     );
 
     let returns = vm
-        .function("f", &[BorshToken::Bool(false), BorshToken::Bool(true)])
+        .function("f")
+        .arguments(&[BorshToken::Bool(false), BorshToken::Bool(true)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
 
@@ -113,9 +128,17 @@ fn casting_destructure() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("f", &[]).unwrap().unwrap_tuple();
+    let returns = vm
+        .function("f")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap()
+        .unwrap_tuple();
 
     assert_eq!(
         returns,
@@ -141,9 +164,16 @@ fn casting_destructure() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("f", &[]).unwrap();
+    let returns = vm
+        .function("f")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::String(String::from("Hello")));
 }
@@ -177,7 +207,12 @@ fn casting_storage_destructure() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function("bar", &[]);
+    vm.function("bar")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }

+ 14 - 4
tests/solana_tests/events.rs

@@ -23,9 +23,14 @@ fn simple_event() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function("go", &[]);
+    vm.function("go")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(vm.events.len(), 1);
     assert_eq!(vm.events[0].len(), 1);
@@ -77,9 +82,14 @@ fn less_simple_event() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function("go", &[]);
+    vm.function("go")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(vm.events.len(), 1);
     assert_eq!(vm.events[0].len(), 1);

+ 91 - 50
tests/solana_tests/expressions.rs

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: Apache-2.0
 
-use crate::{build_solidity, BorshToken};
+use crate::{account_new, build_solidity, BorshToken};
 use num_bigint::BigInt;
 use rand::Rng;
 
@@ -20,9 +20,16 @@ fn interfaceid() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get", &[]).unwrap();
+    let returns = vm
+        .function("get")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -57,23 +64,37 @@ fn write_buffer() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("test1", &[]).unwrap();
+    let returns = vm
+        .function("test1")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
         BorshToken::Bytes([0xbc, 0xbc, 0xbd, 0xbe, 8, 7, 6, 5, 4, 3, 2, 1].to_vec())
     );
 
-    let returns = vm.function("test2", &[]).unwrap();
+    let returns = vm
+        .function("test2")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     let mut buf = vec![0x42u8, 0x41u8];
-    buf.extend_from_slice(&vm.stack[0].program);
+    buf.extend_from_slice(&vm.stack[0].id);
 
     assert_eq!(returns, BorshToken::Bytes(buf));
 
-    let res = vm.function_must_fail("test3", &[]);
+    let res = vm
+        .function("test3")
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
     assert_eq!(res.unwrap(), 4294967296);
 }
 
@@ -92,15 +113,18 @@ fn read_buffer() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "test1",
-            &[BorshToken::Bytes(
-                [0xbc, 0xbc, 0xbd, 0xbe, 8, 7, 6, 5, 4, 3, 2, 1].to_vec(),
-            )],
-        )
+        .function("test1")
+        .arguments(&[BorshToken::Bytes(
+            [0xbc, 0xbc, 0xbd, 0xbe, 8, 7, 6, 5, 4, 3, 2, 1].to_vec(),
+        )])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
 
@@ -118,19 +142,24 @@ fn read_buffer() {
         ]
     );
 
-    let res = vm.function_must_fail(
-        "test1",
-        &[BorshToken::Bytes(
+    let res = vm
+        .function("test1")
+        .arguments(&[BorshToken::Bytes(
             [0xbc, 0xbc, 0xbd, 0xbe, 8, 7, 6, 5, 4, 3, 2].to_vec(),
-        )],
-    );
+        )])
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
     assert_eq!(res.unwrap(), 4294967296);
 
     let mut buf = vec![0x42u8, 0x41u8];
-    buf.extend_from_slice(&vm.origin);
+    let acc = account_new();
+    buf.extend_from_slice(&acc);
 
     let returns = vm
-        .function("test2", &[BorshToken::Bytes(buf.clone())])
+        .function("test2")
+        .arguments(&[BorshToken::Bytes(buf.clone())])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
 
@@ -141,13 +170,17 @@ fn read_buffer() {
                 width: 16,
                 value: BigInt::from(0x4142u16)
             },
-            BorshToken::Address(vm.origin)
+            BorshToken::Address(acc)
         ]
     );
 
     buf.pop();
 
-    let res = vm.function_must_fail("test2", &[BorshToken::Bytes(buf)]);
+    let res = vm
+        .function("test2")
+        .arguments(&[BorshToken::Bytes(buf)])
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
     assert_eq!(res.unwrap(), 4294967296);
 }
 
@@ -166,22 +199,25 @@ fn bytes_compare() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "test1",
-            &[BorshToken::FixedBytes([0xbc, 0xbc, 0xbd, 0xbe].to_vec())],
-        )
+        .function("test1")
+        .arguments(&[BorshToken::FixedBytes([0xbc, 0xbc, 0xbd, 0xbe].to_vec())])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(returns, BorshToken::Bool(true));
 
     let returns = vm
-        .function(
-            "test2",
-            &[BorshToken::FixedBytes([0xbc, 0xbc, 0xbd, 0xbe].to_vec())],
-        )
+        .function("test2")
+        .arguments(&[BorshToken::FixedBytes([0xbc, 0xbc, 0xbd, 0xbe].to_vec())])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(returns, BorshToken::Bool(false));
@@ -200,26 +236,28 @@ fn assignment_in_ternary() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     for _ in 0..10 {
         let left = rng.gen::<u64>();
         let right = rng.gen::<u64>();
 
         let returns = vm
-            .function(
-                "minimum",
-                &[
-                    BorshToken::Uint {
-                        width: 64,
-                        value: BigInt::from(left),
-                    },
-                    BorshToken::Uint {
-                        width: 64,
-                        value: BigInt::from(right),
-                    },
-                ],
-            )
+            .function("minimum")
+            .arguments(&[
+                BorshToken::Uint {
+                    width: 64,
+                    value: BigInt::from(left),
+                },
+                BorshToken::Uint {
+                    width: 64,
+                    value: BigInt::from(right),
+                },
+            ])
+            .call()
             .unwrap();
 
         assert_eq!(
@@ -237,15 +275,18 @@ fn power() {
     let mut vm = build_solidity(
         r#"
         contract foo {
-            function power() public returns (uint) {
+            function power() public pure returns (uint) {
                 return 2 ** 3 ** 4;
             }
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("power", &[]).unwrap();
+    let returns = vm.function("power").call().unwrap();
 
     assert_eq!(
         returns,

+ 64 - 12
tests/solana_tests/hash.rs

@@ -15,8 +15,16 @@ fn constants_hash_tests() {
         }"#,
     );
 
-    runtime.constructor(&[]);
-    runtime.function("test", &[]);
+    let data_account = runtime.initialize_data_account();
+    runtime
+        .function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
+    runtime
+        .function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let mut runtime = build_solidity(
         r#"
@@ -29,8 +37,15 @@ fn constants_hash_tests() {
         }"#,
     );
 
-    runtime.constructor(&[]);
-    runtime.function("test", &[]);
+    let data_account = runtime.initialize_data_account();
+    runtime
+        .function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    runtime
+        .function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let mut runtime = build_solidity(
         r#"
@@ -43,8 +58,15 @@ fn constants_hash_tests() {
         }"#,
     );
 
-    runtime.constructor(&[]);
-    runtime.function("test", &[]);
+    let data_account = runtime.initialize_data_account();
+    runtime
+        .function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    runtime
+        .function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }
 
 #[test]
@@ -60,9 +82,19 @@ fn hash_tests() {
         }"##,
     );
 
-    runtime.constructor(&[]);
+    let data_account = runtime.initialize_data_account();
+    runtime
+        .function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let hash = runtime
-        .function("test", &[BorshToken::Bytes(b"Hello, World!".to_vec())])
+        .function("test")
+        .arguments(&[BorshToken::Bytes(b"Hello, World!".to_vec())])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -83,9 +115,19 @@ fn hash_tests() {
         }"##,
     );
 
-    runtime.constructor(&[]);
+    let data_account = runtime.initialize_data_account();
+    runtime
+        .function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let hash = runtime
-        .function("test", &[BorshToken::Bytes(b"Hello, World!".to_vec())])
+        .function("test")
+        .arguments(&[BorshToken::Bytes(b"Hello, World!".to_vec())])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -107,9 +149,19 @@ fn hash_tests() {
         }"##,
     );
 
-    runtime.constructor(&[]);
+    let data_account = runtime.initialize_data_account();
+    runtime
+        .function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let hash = runtime
-        .function("test", &[BorshToken::Bytes(b"Hello, World!".to_vec())])
+        .function("test")
+        .arguments(&[BorshToken::Bytes(b"Hello, World!".to_vec())])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .call()
         .unwrap();
 
     assert_eq!(

+ 381 - 259
tests/solana_tests/mappings.rs

@@ -25,12 +25,14 @@ fn simple_mapping() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     for i in 0..10 {
-        vm.function(
-            "set",
-            &[
+        vm.function("set")
+            .arguments(&[
                 BorshToken::Uint {
                     width: 64,
                     value: BigInt::from(102 + i),
@@ -39,19 +41,20 @@ fn simple_mapping() {
                     width: 64,
                     value: BigInt::from(300331 + i),
                 },
-            ],
-        );
+            ])
+            .accounts(vec![("dataAccount", data_account)])
+            .call();
     }
 
     for i in 0..10 {
         let returns = vm
-            .function(
-                "get",
-                &[BorshToken::Uint {
-                    width: 64,
-                    value: BigInt::from(102 + i),
-                }],
-            )
+            .function("get")
+            .arguments(&[BorshToken::Uint {
+                width: 64,
+                value: BigInt::from(102 + i),
+            }])
+            .accounts(vec![("dataAccount", data_account)])
+            .call()
             .unwrap();
 
         assert_eq!(
@@ -64,13 +67,13 @@ fn simple_mapping() {
     }
 
     let returns = vm
-        .function(
-            "get",
-            &[BorshToken::Uint {
-                width: 64,
-                value: BigInt::from(101u8),
-            }],
-        )
+        .function("get")
+        .arguments(&[BorshToken::Uint {
+            width: 64,
+            value: BigInt::from(101u8),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -81,23 +84,23 @@ fn simple_mapping() {
         }
     );
 
-    vm.function(
-        "rm",
-        &[BorshToken::Uint {
+    vm.function("rm")
+        .arguments(&[BorshToken::Uint {
             width: 64,
             value: BigInt::from(104u8),
-        }],
-    );
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     for i in 0..10 {
         let returns = vm
-            .function(
-                "get",
-                &[BorshToken::Uint {
-                    width: 64,
-                    value: BigInt::from(102 + i),
-                }],
-            )
+            .function("get")
+            .arguments(&[BorshToken::Uint {
+                width: 64,
+                value: BigInt::from(102 + i),
+            }])
+            .accounts(vec![("dataAccount", data_account)])
+            .call()
             .unwrap();
 
         if 102 + i != 104 {
@@ -150,10 +153,14 @@ fn less_simple_mapping() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     vm.function(
-        "set_string",
+        "set_string")
+        .arguments(
         &[
             BorshToken::Uint {
                 width: 256,
@@ -161,11 +168,12 @@ fn less_simple_mapping() {
             },
             BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder")),
         ],
-    );
+    )
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function(
-        "add_int",
-        &[
+    vm.function("add_int")
+        .arguments(&[
             BorshToken::Uint {
                 width: 256,
                 value: BigInt::from(12313132131321312311213131u128),
@@ -174,17 +182,18 @@ fn less_simple_mapping() {
                 width: 64,
                 value: BigInt::from(102u8),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "get",
-            &[BorshToken::Uint {
-                width: 256,
-                value: BigInt::from(12313132131321312311213131u128),
-            }],
-        )
+        .function("get")
+        .arguments(&[BorshToken::Uint {
+            width: 256,
+            value: BigInt::from(12313132131321312311213131u128),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -231,29 +240,38 @@ fn string_mapping() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     vm.function(
-        "set_string",
+        "set_string")
+        .arguments(
         &[
             BorshToken::String(String::from("a")),
             BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder")),
         ],
-    );
+    )
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function(
-        "add_int",
-        &[
+    vm.function("add_int")
+        .arguments(&[
             BorshToken::String(String::from("a")),
             BorshToken::Int {
                 width: 64,
                 value: BigInt::from(102u8),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function("get", &[BorshToken::String(String::from("a"))])
+        .function("get")
+        .arguments(&[BorshToken::String(String::from("a"))])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -293,27 +311,46 @@ fn contract_mapping() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let index = BorshToken::Address(account_new());
 
     vm.function(
-        "set",
+        "set")
+        .arguments(
         &[
             index.clone(),
             BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder")),
-        ], );
+        ], )
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get", &[index.clone()]).unwrap();
+    let returns = vm
+        .function("get")
+        .arguments(&[index.clone()])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
         BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder"))
     );
 
-    vm.function("rm", &[index.clone()]);
+    vm.function("rm")
+        .arguments(&[index.clone()])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get", &[index]).unwrap();
+    let returns = vm
+        .function("get")
+        .arguments(&[index])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::String(String::from("")));
 }
@@ -331,61 +368,64 @@ fn mapping_in_mapping() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function(
-        "set",
-        &[
+    vm.function("set")
+        .arguments(&[
             BorshToken::String(String::from("a")),
             BorshToken::Int {
                 width: 64,
                 value: BigInt::from(102u8),
             },
             BorshToken::FixedBytes(vec![0x98]),
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "map",
-            &[
-                BorshToken::String(String::from("a")),
-                BorshToken::Int {
-                    width: 64,
-                    value: BigInt::from(102u8),
-                },
-            ],
-        )
+        .function("map")
+        .arguments(&[
+            BorshToken::String(String::from("a")),
+            BorshToken::Int {
+                width: 64,
+                value: BigInt::from(102u8),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(returns, BorshToken::uint8_fixed_array(vec![0x98]));
 
     let returns = vm
-        .function(
-            "map",
-            &[
-                BorshToken::String(String::from("a")),
-                BorshToken::Int {
-                    width: 64,
-                    value: BigInt::from(103u8),
-                },
-            ],
-        )
+        .function("map")
+        .arguments(&[
+            BorshToken::String(String::from("a")),
+            BorshToken::Int {
+                width: 64,
+                value: BigInt::from(103u8),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(returns, BorshToken::uint8_fixed_array(vec![0]));
 
     let returns = vm
-        .function(
-            "map",
-            &[
-                BorshToken::String(String::from("b")),
-                BorshToken::Int {
-                    width: 64,
-                    value: BigInt::from(102u8),
-                },
-            ],
-        )
+        .function("map")
+        .arguments(&[
+            BorshToken::String(String::from("b")),
+            BorshToken::Int {
+                width: 64,
+                value: BigInt::from(102u8),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(returns, BorshToken::uint8_fixed_array(vec![0]));
@@ -421,21 +461,26 @@ fn sparse_array() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     vm.function(
-        "set_string",
+        "set_string")
+        .arguments(
         &[
             BorshToken::Uint{
                 width: 256,
                 value: BigInt::from(909090909u64)
             },
             BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder")),
-        ], );
+        ], )
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function(
-        "add_int",
-        &[
+    vm.function("add_int")
+        .arguments(&[
             BorshToken::Uint {
                 width: 256,
                 value: BigInt::from(909090909u64),
@@ -444,17 +489,18 @@ fn sparse_array() {
                 width: 64,
                 value: BigInt::from(102u8),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "get",
-            &[BorshToken::Uint {
-                width: 256,
-                value: BigInt::from(909090909u64),
-            }],
-        )
+        .function("get")
+        .arguments(&[BorshToken::Uint {
+            width: 256,
+            value: BigInt::from(909090909u64),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -501,21 +547,26 @@ fn massive_sparse_array() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     vm.function(
-        "set_string",
+        "set_string")
+        .arguments(
         &[
             BorshToken::Uint {
                 width: 256,
                 value: BigInt::from(786868768768678687686877u128)
             },
             BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder")),
-        ], );
+        ], )
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function(
-        "add_int",
-        &[
+    vm.function("add_int")
+        .arguments(&[
             BorshToken::Uint {
                 width: 256,
                 value: BigInt::from(786868768768678687686877u128),
@@ -524,17 +575,18 @@ fn massive_sparse_array() {
                 width: 64,
                 value: BigInt::from(102u8),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "get",
-            &[BorshToken::Uint {
-                width: 256,
-                value: BigInt::from(786868768768678687686877u128),
-            }],
-        )
+        .function("get")
+        .arguments(&[BorshToken::Uint {
+            width: 256,
+            value: BigInt::from(786868768768678687686877u128),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -585,24 +637,30 @@ fn mapping_in_dynamic_array() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function(
-        "setNumber",
-        &[BorshToken::Int {
+    vm.function("setNumber")
+        .arguments(&[BorshToken::Int {
             width: 64,
             value: BigInt::from(2147483647),
-        }],
-    );
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function("push", &[]);
-    vm.function("push", &[]);
+    vm.function("push")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    vm.function("push")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     for array_no in 0..2 {
         for i in 0..10 {
-            vm.function(
-                "set",
-                &[
+            vm.function("set")
+                .arguments(&[
                     BorshToken::Uint {
                         width: 64,
                         value: BigInt::from(array_no),
@@ -615,27 +673,28 @@ fn mapping_in_dynamic_array() {
                         width: 64,
                         value: BigInt::from(300331 + i),
                     },
-                ],
-            );
+                ])
+                .accounts(vec![("dataAccount", data_account)])
+                .call();
         }
     }
 
     for array_no in 0..2 {
         for i in 0..10 {
             let returns = vm
-                .function(
-                    "map",
-                    &[
-                        BorshToken::Uint {
-                            width: 256,
-                            value: BigInt::from(array_no),
-                        },
-                        BorshToken::Uint {
-                            width: 64,
-                            value: BigInt::from(102 + i + array_no * 500),
-                        },
-                    ],
-                )
+                .function("map")
+                .arguments(&[
+                    BorshToken::Uint {
+                        width: 256,
+                        value: BigInt::from(array_no),
+                    },
+                    BorshToken::Uint {
+                        width: 64,
+                        value: BigInt::from(102 + i + array_no * 500),
+                    },
+                ])
+                .accounts(vec![("dataAccount", data_account)])
+                .call()
                 .unwrap();
 
             assert_eq!(
@@ -649,19 +708,19 @@ fn mapping_in_dynamic_array() {
     }
 
     let returns = vm
-        .function(
-            "map",
-            &[
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::zero(),
-                },
-                BorshToken::Uint {
-                    width: 64,
-                    value: BigInt::from(101u8),
-                },
-            ],
-        )
+        .function("map")
+        .arguments(&[
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::zero(),
+            },
+            BorshToken::Uint {
+                width: 64,
+                value: BigInt::from(101u8),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -672,9 +731,8 @@ fn mapping_in_dynamic_array() {
         }
     );
 
-    vm.function(
-        "rm",
-        &[
+    vm.function("rm")
+        .arguments(&[
             BorshToken::Uint {
                 width: 64,
                 value: BigInt::zero(),
@@ -683,24 +741,25 @@ fn mapping_in_dynamic_array() {
                 width: 64,
                 value: BigInt::from(104u8),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     for i in 0..10 {
         let returns = vm
-            .function(
-                "map",
-                &[
-                    BorshToken::Uint {
-                        width: 256,
-                        value: BigInt::zero(),
-                    },
-                    BorshToken::Uint {
-                        width: 64,
-                        value: BigInt::from(102 + i),
-                    },
-                ],
-            )
+            .function("map")
+            .arguments(&[
+                BorshToken::Uint {
+                    width: 256,
+                    value: BigInt::zero(),
+                },
+                BorshToken::Uint {
+                    width: 64,
+                    value: BigInt::from(102 + i),
+                },
+            ])
+            .accounts(vec![("dataAccount", data_account)])
+            .call()
             .unwrap();
 
         if 102 + i != 104 {
@@ -722,7 +781,11 @@ fn mapping_in_dynamic_array() {
         }
     }
 
-    let returns = vm.function("length", &[]).unwrap();
+    let returns = vm
+        .function("length")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Uint {
@@ -731,9 +794,15 @@ fn mapping_in_dynamic_array() {
         }
     );
 
-    vm.function("pop", &[]);
+    vm.function("pop")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("length", &[]).unwrap();
+    let returns = vm
+        .function("length")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Uint {
@@ -742,9 +811,15 @@ fn mapping_in_dynamic_array() {
         }
     );
 
-    vm.function("pop", &[]);
+    vm.function("pop")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("length", &[]).unwrap();
+    let returns = vm
+        .function("length")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Uint {
@@ -753,7 +828,11 @@ fn mapping_in_dynamic_array() {
         }
     );
 
-    let returns = vm.function("number", &[]).unwrap();
+    let returns = vm
+        .function("number")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -802,24 +881,30 @@ fn mapping_in_struct_in_dynamic_array() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function(
-        "setNumber",
-        &[BorshToken::Int {
+    vm.function("setNumber")
+        .arguments(&[BorshToken::Int {
             width: 64,
             value: BigInt::from(2147483647),
-        }],
-    );
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function("push", &[]);
-    vm.function("push", &[]);
+    vm.function("push")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    vm.function("push")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     for array_no in 0..2 {
         for i in 0..10 {
-            vm.function(
-                "set",
-                &[
+            vm.function("set")
+                .arguments(&[
                     BorshToken::Uint {
                         width: 64,
                         value: BigInt::from(array_no),
@@ -832,27 +917,28 @@ fn mapping_in_struct_in_dynamic_array() {
                         width: 64,
                         value: BigInt::from(300331 + i),
                     },
-                ],
-            );
+                ])
+                .accounts(vec![("dataAccount", data_account)])
+                .call();
         }
     }
 
     for array_no in 0..2 {
         for i in 0..10 {
             let returns = vm
-                .function(
-                    "get",
-                    &[
-                        BorshToken::Uint {
-                            width: 64,
-                            value: BigInt::from(array_no),
-                        },
-                        BorshToken::Uint {
-                            width: 64,
-                            value: BigInt::from(102 + i + array_no * 500),
-                        },
-                    ],
-                )
+                .function("get")
+                .arguments(&[
+                    BorshToken::Uint {
+                        width: 64,
+                        value: BigInt::from(array_no),
+                    },
+                    BorshToken::Uint {
+                        width: 64,
+                        value: BigInt::from(102 + i + array_no * 500),
+                    },
+                ])
+                .accounts(vec![("dataAccount", data_account)])
+                .call()
                 .unwrap();
 
             assert_eq!(
@@ -866,19 +952,19 @@ fn mapping_in_struct_in_dynamic_array() {
     }
 
     let returns = vm
-        .function(
-            "get",
-            &[
-                BorshToken::Uint {
-                    width: 64,
-                    value: BigInt::zero(),
-                },
-                BorshToken::Uint {
-                    width: 64,
-                    value: BigInt::from(101u8),
-                },
-            ],
-        )
+        .function("get")
+        .arguments(&[
+            BorshToken::Uint {
+                width: 64,
+                value: BigInt::zero(),
+            },
+            BorshToken::Uint {
+                width: 64,
+                value: BigInt::from(101u8),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -889,9 +975,8 @@ fn mapping_in_struct_in_dynamic_array() {
         },
     );
 
-    vm.function(
-        "rm",
-        &[
+    vm.function("rm")
+        .arguments(&[
             BorshToken::Uint {
                 width: 64,
                 value: BigInt::zero(),
@@ -900,24 +985,25 @@ fn mapping_in_struct_in_dynamic_array() {
                 width: 64,
                 value: BigInt::from(104u8),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     for i in 0..10 {
         let returns = vm
-            .function(
-                "get",
-                &[
-                    BorshToken::Uint {
-                        width: 64,
-                        value: BigInt::zero(),
-                    },
-                    BorshToken::Uint {
-                        width: 64,
-                        value: BigInt::from(102 + i),
-                    },
-                ],
-            )
+            .function("get")
+            .arguments(&[
+                BorshToken::Uint {
+                    width: 64,
+                    value: BigInt::zero(),
+                },
+                BorshToken::Uint {
+                    width: 64,
+                    value: BigInt::from(102 + i),
+                },
+            ])
+            .accounts(vec![("dataAccount", data_account)])
+            .call()
             .unwrap();
 
         if 102 + i != 104 {
@@ -939,10 +1025,18 @@ fn mapping_in_struct_in_dynamic_array() {
         }
     }
 
-    vm.function("pop", &[]);
-    vm.function("pop", &[]);
+    vm.function("pop")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    vm.function("pop")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("number", &[]).unwrap();
+    let returns = vm
+        .function("number")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -987,10 +1081,24 @@ contract DeleteTest {
 
     let sender = account_new();
 
-    vm.constructor(&[]);
-    let _ = vm.function("addData", &[BorshToken::Address(sender)]);
-    let _ = vm.function("deltest", &[]);
-    let returns = vm.function("get", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let _ = vm
+        .function("addData")
+        .arguments(&[BorshToken::Address(sender)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let _ = vm
+        .function("deltest")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("get")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Tuple(vec![
@@ -1048,10 +1156,16 @@ function getArrAmt() public view returns (uint) {
 
     let sender = account_new();
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let ret = vm
-        .function("newCampaign", &[BorshToken::Address(sender)])
+        .function("newCampaign")
+        .arguments(&[BorshToken::Address(sender)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -1062,7 +1176,11 @@ function getArrAmt() public view returns (uint) {
         }
     );
 
-    let ret = vm.function("getAmt", &[]).unwrap();
+    let ret = vm
+        .function("getAmt")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         ret,
         BorshToken::Uint {
@@ -1071,7 +1189,11 @@ function getArrAmt() public view returns (uint) {
         }
     );
 
-    let ret = vm.function("getArrAmt", &[]).unwrap();
+    let ret = vm
+        .function("getArrAmt")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         ret,
         BorshToken::Uint {

+ 61 - 53
tests/solana_tests/math.rs

@@ -39,22 +39,25 @@ fn safe_math() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "mul_test",
-            &[
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from_str("1000000000000000000").unwrap(),
-                },
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from_str("4000000000000000000").unwrap(),
-                },
-            ],
-        )
+        .function("mul_test")
+        .arguments(&[
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from_str("1000000000000000000").unwrap(),
+            },
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from_str("4000000000000000000").unwrap(),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -66,19 +69,19 @@ fn safe_math() {
     );
 
     let returns = vm
-        .function(
-            "add_test",
-            &[
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from_str("1000000000000000000").unwrap(),
-                },
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from_str("4000000000000000000").unwrap(),
-                },
-            ],
-        )
+        .function("add_test")
+        .arguments(&[
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from_str("1000000000000000000").unwrap(),
+            },
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from_str("4000000000000000000").unwrap(),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -90,19 +93,19 @@ fn safe_math() {
     );
 
     let returns = vm
-        .function(
-            "sub_test",
-            &[
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from_str("4000000000000000000").unwrap(),
-                },
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from_str("1000000000000000000").unwrap(),
-                },
-            ],
-        )
+        .function("sub_test")
+        .arguments(&[
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from_str("4000000000000000000").unwrap(),
+            },
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from_str("1000000000000000000").unwrap(),
+            },
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -113,9 +116,9 @@ fn safe_math() {
         },
     );
 
-    let res = vm.function_must_fail(
-        "mul_test",
-        &[
+    let res = vm
+        .function("mul_test")
+        .arguments(&[
             BorshToken::Uint {
                 width: 256,
                 value: BigInt::from_str("400000000000000000000000000000000000000").unwrap(),
@@ -124,13 +127,15 @@ fn safe_math() {
                 width: 256,
                 value: BigInt::from_str("400000000000000000000000000000000000000").unwrap(),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_ne!(res.unwrap(), 0);
 
-    let res = vm.function_must_fail(
-        "add_test",
+    let res = vm.function(
+        "add_test")
+        .arguments(
         &[
             BorshToken::Uint {
                 width: 256,
@@ -141,13 +146,15 @@ fn safe_math() {
                 value: BigInt::from_str("100000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap(),
             },
         ],
-    );
+    )
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_ne!(res.unwrap(), 0);
 
-    let res = vm.function_must_fail(
-        "sub_test",
-        &[
+    let res = vm
+        .function("sub_test")
+        .arguments(&[
             BorshToken::Uint {
                 width: 256,
                 value: BigInt::from_str("1000000000000000000").unwrap(),
@@ -156,8 +163,9 @@ fn safe_math() {
                 width: 256,
                 value: BigInt::from_str("4000000000000000000").unwrap(),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_ne!(res.unwrap(), 0);
 }

+ 29 - 13
tests/solana_tests/metas.rs

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: Apache-2.0
 
-use crate::{account_new, build_solidity, AccountState, BorshToken};
+use crate::{account_new, build_solidity, AccountMeta, AccountState, BorshToken, Pubkey};
 
 #[test]
 fn use_authority() {
@@ -17,12 +17,24 @@ fn use_authority() {
         },
     );
 
-    vm.constructor(&[BorshToken::Address(authority)]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .arguments(&[BorshToken::Address(authority)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let res = vm.function_must_fail("inc", &[]).unwrap();
+    let res = vm
+        .function("inc")
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail()
+        .unwrap();
     assert_ne!(res, 0);
 
-    let res = vm.function("get", &[]).unwrap();
+    let res = vm
+        .function("get")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         res,
         BorshToken::Uint {
@@ -31,16 +43,20 @@ fn use_authority() {
         }
     );
 
-    let mut metas = vm.default_metas();
+    vm.function("inc")
+        .accounts(vec![("dataAccount", data_account)])
+        .remaining_accounts(&[AccountMeta {
+            pubkey: Pubkey(authority),
+            is_signer: true,
+            is_writable: false,
+        }])
+        .call();
 
-    // "sign" the transaction with the authority
-    if let Some(meta) = metas.iter_mut().find(|e| e.pubkey.0 == authority) {
-        meta.is_signer = true;
-    }
-
-    vm.function_metas("inc", &metas, &[]);
-
-    let res = vm.function("get", &[]).unwrap();
+    let res = vm
+        .function("get")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         res,
         BorshToken::Uint {

+ 12 - 3
tests/solana_tests/modifiers.rs

@@ -28,10 +28,16 @@ fn returns_and_phis_needed() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function("func", &[BorshToken::Bool(false)])
+        .function("func")
+        .arguments(&[BorshToken::Bool(false)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
 
@@ -47,7 +53,10 @@ fn returns_and_phis_needed() {
     );
 
     let returns = vm
-        .function("func", &[BorshToken::Bool(true)])
+        .function("func")
+        .arguments(&[BorshToken::Bool(true)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
 

Різницю між файлами не показано, бо вона завелика
+ 384 - 306
tests/solana_tests/primitives.rs


+ 79 - 23
tests/solana_tests/rational.rs

@@ -21,9 +21,16 @@ fn rational() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("test", &[]).unwrap();
+    let returns = vm
+        .function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -33,7 +40,11 @@ fn rational() {
         }
     );
 
-    let returns = vm.function("test2", &[]).unwrap();
+    let returns = vm
+        .function("test2")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -53,9 +64,16 @@ fn rational() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("test", &[]).unwrap();
+    let returns = vm
+        .function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -75,9 +93,16 @@ fn rational() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("test", &[]).unwrap();
+    let returns = vm
+        .function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -97,9 +122,16 @@ fn rational() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("test", &[]).unwrap();
+    let returns = vm
+        .function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -119,9 +151,16 @@ fn rational() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("test", &[]).unwrap();
+    let returns = vm
+        .function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -140,9 +179,16 @@ fn rational() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("test", &[]).unwrap();
+    let returns = vm
+        .function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -161,9 +207,16 @@ fn rational() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("test", &[]).unwrap();
+    let returns = vm
+        .function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -182,16 +235,19 @@ fn rational() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "test",
-            &[BorshToken::Uint {
-                width: 64,
-                value: BigInt::from(982451653u32),
-            }],
-        )
+        .function("test")
+        .arguments(&[BorshToken::Uint {
+            width: 64,
+            value: BigInt::from(982451653u32),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
 

+ 100 - 22
tests/solana_tests/returns.rs

@@ -31,9 +31,16 @@ fn return_single() {
             }
         }"#,
     );
-    vm.constructor(&[]);
-
-    let returns = vm.function("f", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
+    let returns = vm
+        .function("f")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Uint {
@@ -42,7 +49,11 @@ fn return_single() {
         },
     );
 
-    let returns = vm.function("g", &[]).unwrap();
+    let returns = vm
+        .function("g")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Uint {
@@ -51,7 +62,11 @@ fn return_single() {
         },
     );
 
-    let returns = vm.function("h", &[]).unwrap();
+    let returns = vm
+        .function("h")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Uint {
@@ -60,7 +75,11 @@ fn return_single() {
         },
     );
 
-    let returns = vm.function("i", &[]).unwrap();
+    let returns = vm
+        .function("i")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Uint {
@@ -69,7 +88,11 @@ fn return_single() {
         },
     );
 
-    let returns = vm.function("j", &[]).unwrap();
+    let returns = vm
+        .function("j")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Uint {
@@ -90,8 +113,16 @@ fn return_ternary() {
         }"#,
     );
 
-    vm.constructor(&[]);
-    let returns = vm.function("f", &[]).unwrap().unwrap_tuple();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("f")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap()
+        .unwrap_tuple();
 
     assert_eq!(
         returns,
@@ -116,8 +147,16 @@ fn return_ternary() {
         }"#,
     );
 
-    vm.constructor(&[]);
-    let returns = vm.function("f", &[]).unwrap().unwrap_tuple();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("f")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap()
+        .unwrap_tuple();
 
     assert_eq!(
         returns,
@@ -156,10 +195,23 @@ fn return_nothing() {
         }"#,
     );
 
-    vm.constructor(&[]);
-    let _returns = vm.function("strange", &[]);
-    let _returns = vm.function("inc", &[]);
-    let returns = vm.function("get", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let _returns = vm
+        .function("strange")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let _returns = vm
+        .function("inc")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("get")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -192,9 +244,19 @@ fn return_nothing() {
         }"#,
     );
 
-    vm.constructor(&[]);
-    let _returns = vm.function("f", &[]);
-    let returns = vm.function("get", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let _returns = vm
+        .function("f")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("get")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -220,8 +282,16 @@ fn return_function() {
         }"#,
     );
 
-    vm.constructor(&[]);
-    let returns = vm.function("f", &[]).unwrap().unwrap_tuple();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("f")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap()
+        .unwrap_tuple();
 
     assert_eq!(
         returns,
@@ -250,8 +320,16 @@ fn return_function() {
         }"#,
     );
 
-    vm.constructor(&[]);
-    let returns = vm.function("f", &[]).unwrap().unwrap_tuple();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("f")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap()
+        .unwrap_tuple();
 
     assert_eq!(
         returns,

+ 80 - 53
tests/solana_tests/runtime_errors.rs

@@ -135,28 +135,33 @@ contract calle_contract {
     );
 
     vm.set_program(0);
-    vm.constructor(&[]);
-
-    let mut _res = vm.function_must_fail(
-        "math_overflow",
-        &[BorshToken::Int {
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
+    let mut _res = vm
+        .function("math_overflow")
+        .arguments(&[BorshToken::Int {
             width: 8,
             value: BigInt::from(10u8),
-        }],
-    );
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
     assert_eq!(
         vm.logs,
         "runtime_error: math overflow in test.sol:22:20-29,\n"
     );
     vm.logs.clear();
 
-    _res = vm.function_must_fail(
-        "require_test",
-        &[BorshToken::Int {
+    _res = vm
+        .function("require_test")
+        .arguments(&[BorshToken::Int {
             width: 256,
             value: BigInt::from(9u8),
-        }],
-    );
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_eq!(
         vm.logs,
@@ -165,7 +170,10 @@ contract calle_contract {
 
     vm.logs.clear();
 
-    _res = vm.function_must_fail("get_storage_bytes", &[]);
+    _res = vm
+        .function("get_storage_bytes")
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_eq!(
         vm.logs,
@@ -174,7 +182,10 @@ contract calle_contract {
 
     vm.logs.clear();
 
-    _res = vm.function_must_fail("set_storage_bytes", &[]);
+    _res = vm
+        .function("set_storage_bytes")
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_eq!(
         vm.logs,
@@ -182,13 +193,14 @@ contract calle_contract {
     );
     vm.logs.clear();
 
-    _res = vm.function_must_fail(
-        "read_integer_failure",
-        &[BorshToken::Uint {
+    _res = vm
+        .function("read_integer_failure")
+        .arguments(&[BorshToken::Uint {
             width: 32,
             value: BigInt::from(2u8),
-        }],
-    );
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_eq!(
         vm.logs,
@@ -196,13 +208,14 @@ contract calle_contract {
     );
     vm.logs.clear();
 
-    _res = vm.function_must_fail(
-        "trunc_failure",
-        &[BorshToken::Uint {
+    _res = vm
+        .function("trunc_failure")
+        .arguments(&[BorshToken::Uint {
             width: 256,
             value: BigInt::from(u128::MAX),
-        }],
-    );
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_eq!(
         vm.logs,
@@ -210,7 +223,10 @@ contract calle_contract {
     );
     vm.logs.clear();
 
-    _res = vm.function_must_fail("invalid_instruction", &[]);
+    _res = vm
+        .function("invalid_instruction")
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_eq!(
         vm.logs,
@@ -219,7 +235,10 @@ contract calle_contract {
 
     vm.logs.clear();
 
-    _res = vm.function_must_fail("pop_empty_storage", &[]);
+    _res = vm
+        .function("pop_empty_storage")
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_eq!(
         vm.logs,
@@ -228,13 +247,14 @@ contract calle_contract {
 
     vm.logs.clear();
 
-    _res = vm.function_must_fail(
-        "write_bytes_failure",
-        &[BorshToken::Uint {
+    _res = vm
+        .function("write_bytes_failure")
+        .arguments(&[BorshToken::Uint {
             width: 256,
             value: BigInt::from(9u8),
-        }],
-    );
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_eq!(
         vm.logs,
@@ -243,13 +263,14 @@ contract calle_contract {
 
     vm.logs.clear();
 
-    _res = vm.function_must_fail(
-        "assert_test",
-        &[BorshToken::Uint {
+    _res = vm
+        .function("assert_test")
+        .arguments(&[BorshToken::Uint {
             width: 256,
             value: BigInt::from(9u8),
-        }],
-    );
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
     println!("{}", vm.logs);
     assert_eq!(
         vm.logs,
@@ -257,13 +278,14 @@ contract calle_contract {
     );
     vm.logs.clear();
 
-    _res = vm.function_must_fail(
-        "out_of_bounds",
-        &[BorshToken::Uint {
+    _res = vm
+        .function("out_of_bounds")
+        .arguments(&[BorshToken::Uint {
             width: 256,
             value: BigInt::from(19u8),
-        }],
-    );
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_eq!(
         vm.logs,
@@ -272,13 +294,14 @@ contract calle_contract {
 
     vm.logs.clear();
 
-    _res = vm.function_must_fail(
-        "write_integer_failure",
-        &[BorshToken::Uint {
+    _res = vm
+        .function("write_integer_failure")
+        .arguments(&[BorshToken::Uint {
             width: 256,
             value: BigInt::from(1u8),
-        }],
-    );
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_eq!(
         vm.logs,
@@ -287,13 +310,14 @@ contract calle_contract {
 
     vm.logs.clear();
 
-    _res = vm.function_must_fail(
-        "byte_cast_failure",
-        &[BorshToken::Uint {
+    _res = vm
+        .function("byte_cast_failure")
+        .arguments(&[BorshToken::Uint {
             width: 256,
             value: BigInt::from(33u8),
-        }],
-    );
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_eq!(
         vm.logs,
@@ -302,7 +326,10 @@ contract calle_contract {
 
     vm.logs.clear();
 
-    _res = vm.function_must_fail("i_will_revert", &[]);
+    _res = vm
+        .function("i_will_revert")
+        .accounts(vec![("dataAccount", data_account)])
+        .must_fail();
 
     assert_eq!(
         vm.logs,
@@ -311,7 +338,7 @@ contract calle_contract {
 
     vm.logs.clear();
 
-    _res = vm.function_must_fail("revert_with_message", &[]);
+    _res = vm.function("revert_with_message").must_fail();
     assert_eq!(
         vm.logs,
         "runtime_error: I reverted! revert encountered in test.sol:103:9-30,\n"

+ 45 - 25
tests/solana_tests/signature_verify.rs

@@ -43,7 +43,18 @@ fn verify() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
+    let instructions_account: Account = "Sysvar1nstructions1111111111111111111111111"
+        .from_base58()
+        .unwrap()
+        .try_into()
+        .unwrap();
+    vm.account_data
+        .insert(instructions_account, AccountState::default());
 
     let mut csprng = rand_07::thread_rng();
     let keypair: Keypair = Keypair::generate(&mut csprng);
@@ -60,14 +71,17 @@ fn verify() {
     println!("T: MES: {}", hex::encode(message));
 
     let returns = vm
-        .function(
-            "verify",
-            &[
-                BorshToken::Address(keypair.public.to_bytes()),
-                BorshToken::Bytes(message.to_vec()),
-                BorshToken::Bytes(signature_bs.clone()),
-            ],
-        )
+        .function("verify")
+        .arguments(&[
+            BorshToken::Address(keypair.public.to_bytes()),
+            BorshToken::Bytes(message.to_vec()),
+            BorshToken::Bytes(signature_bs.clone()),
+        ])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("SysvarInstruction", instructions_account),
+        ])
+        .call()
         .unwrap();
 
     assert_eq!(returns, BorshToken::Bool(false));
@@ -91,14 +105,17 @@ fn verify() {
     println!("Now try for real");
 
     let returns = vm
-        .function(
-            "verify",
-            &[
-                BorshToken::Address(keypair.public.to_bytes()),
-                BorshToken::Bytes(message.to_vec()),
-                BorshToken::Bytes(signature_bs.clone()),
-            ],
-        )
+        .function("verify")
+        .arguments(&[
+            BorshToken::Address(keypair.public.to_bytes()),
+            BorshToken::Bytes(message.to_vec()),
+            BorshToken::Bytes(signature_bs.clone()),
+        ])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("SysvarInstruction", instructions_account),
+        ])
+        .call()
         .unwrap();
 
     assert_eq!(returns, BorshToken::Bool(true));
@@ -121,14 +138,17 @@ fn verify() {
     );
 
     let returns = vm
-        .function(
-            "verify",
-            &[
-                BorshToken::Address(keypair.public.to_bytes()),
-                BorshToken::Bytes(message.to_vec()),
-                BorshToken::Bytes(signature_bs),
-            ],
-        )
+        .function("verify")
+        .arguments(&[
+            BorshToken::Address(keypair.public.to_bytes()),
+            BorshToken::Bytes(message.to_vec()),
+            BorshToken::Bytes(signature_bs),
+        ])
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("SysvarInstruction", instructions_account),
+        ])
+        .call()
         .unwrap();
 
     assert_eq!(returns, BorshToken::Bool(false));

+ 143 - 85
tests/solana_tests/simple.rs

@@ -20,13 +20,18 @@ fn simple() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(vm.logs, "Hello from constructor");
 
     vm.logs.truncate(0);
 
-    vm.function("test", &[]);
+    vm.function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(vm.logs, "Hello from function");
 }
@@ -44,7 +49,10 @@ fn format() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(
         vm.logs,
@@ -69,11 +77,13 @@ fn parameters() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function(
-        "test",
-        &[
+    vm.function("test")
+        .arguments(&[
             BorshToken::Uint {
                 width: 32,
                 value: BigInt::from(10u8),
@@ -82,16 +92,16 @@ fn parameters() {
                 width: 64,
                 value: BigInt::from(10u8),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(vm.logs, "x is 10");
 
     vm.logs.truncate(0);
 
-    vm.function(
-        "test",
-        &[
+    vm.function("test")
+        .arguments(&[
             BorshToken::Uint {
                 width: 32,
                 value: BigInt::from(99u8),
@@ -100,8 +110,9 @@ fn parameters() {
                 width: 64,
                 value: BigInt::from(102u8),
             },
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(vm.logs, "y is 102");
 }
@@ -117,16 +128,19 @@ fn returns() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "test",
-            &[BorshToken::Uint {
-                width: 32,
-                value: BigInt::from(10u8),
-            }],
-        )
+        .function("test")
+        .arguments(&[BorshToken::Uint {
+            width: 32,
+            value: BigInt::from(10u8),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
 
     assert_eq!(
@@ -146,16 +160,19 @@ fn returns() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "test",
-            &[BorshToken::Uint {
-                width: 64,
-                value: BigInt::from(982451653u64),
-            }],
-        )
+        .function("test")
+        .arguments(&[BorshToken::Uint {
+            width: 64,
+            value: BigInt::from(982451653u64),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
 
@@ -197,25 +214,39 @@ fn flipper() {
         }"#,
     );
 
-    vm.constructor(&[BorshToken::Bool(true)]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .arguments(&[BorshToken::Bool(true)])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(
-        vm.data()[0..17].to_vec(),
+        vm.account_data[&data_account].data[0..17].to_vec(),
         hex::decode("6fc90ec500000000000000001800000001").unwrap()
     );
 
-    let returns = vm.function("get", &[]).unwrap();
+    let returns = vm
+        .function("get")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::Bool(true));
 
-    vm.function("flip", &[]);
+    vm.function("flip")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(
-        vm.data()[0..17].to_vec(),
+        vm.account_data[&data_account].data[0..17].to_vec(),
         hex::decode("6fc90ec500000000000000001800000000").unwrap()
     );
 
-    let returns = vm.function("get", &[]).unwrap();
+    let returns = vm
+        .function("get")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::Bool(false));
 }
@@ -251,12 +282,21 @@ fn incrementer() {
         }"#,
     );
 
-    vm.constructor(&[BorshToken::Uint {
-        width: 32,
-        value: BigInt::from(5u8),
-    }]);
+    let data_account = vm.initialize_data_account();
+
+    vm.function("new")
+        .arguments(&[BorshToken::Uint {
+            width: 32,
+            value: BigInt::from(5u8),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get", &[]).unwrap();
+    let returns = vm
+        .function("get")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -266,15 +306,19 @@ fn incrementer() {
         }
     );
 
-    vm.function(
-        "inc",
-        &[BorshToken::Uint {
+    vm.function("inc")
+        .arguments(&[BorshToken::Uint {
             width: 32,
             value: BigInt::from(5u8),
-        }],
-    );
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get", &[]).unwrap();
+    let returns = vm
+        .function("get")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -329,7 +373,10 @@ fn two_arrays() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }
 
 #[test]
@@ -354,9 +401,16 @@ fn dead_storage_bug() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("v", &[]).unwrap();
+    let returns = vm
+        .function("v")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -415,19 +469,23 @@ contract test3 {
     );
 
     // call constructor
-    runtime.constructor(&[]);
+    let data_account = runtime.initialize_data_account();
+    runtime
+        .function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     for i in 0..=50 {
         let res = ((50 - i) * 100 + 5) + i * 1000;
 
         let returns = runtime
-            .function(
-                "foo",
-                &[BorshToken::Uint {
-                    width: 32,
-                    value: BigInt::from(i),
-                }],
-            )
+            .function("foo")
+            .arguments(&[BorshToken::Uint {
+                width: 32,
+                value: BigInt::from(i),
+            }])
+            .accounts(vec![("dataAccount", data_account)])
+            .call()
             .unwrap();
 
         assert_eq!(
@@ -443,16 +501,16 @@ contract test3 {
         let res = (i + 1) * 10 + 1;
 
         let returns = runtime
-            .function(
-                "bar",
-                &[
-                    BorshToken::Uint {
-                        width: 32,
-                        value: BigInt::from(i),
-                    },
-                    BorshToken::Bool(true),
-                ],
-            )
+            .function("bar")
+            .arguments(&[
+                BorshToken::Uint {
+                    width: 32,
+                    value: BigInt::from(i),
+                },
+                BorshToken::Bool(true),
+            ])
+            .accounts(vec![("dataAccount", data_account)])
+            .call()
             .unwrap();
 
         assert_eq!(
@@ -472,16 +530,16 @@ contract test3 {
         }
 
         let returns = runtime
-            .function(
-                "bar",
-                &[
-                    BorshToken::Uint {
-                        width: 32,
-                        value: BigInt::from(i),
-                    },
-                    BorshToken::Bool(false),
-                ],
-            )
+            .function("bar")
+            .arguments(&[
+                BorshToken::Uint {
+                    width: 32,
+                    value: BigInt::from(i),
+                },
+                BorshToken::Bool(false),
+            ])
+            .accounts(vec![("dataAccount", data_account)])
+            .call()
             .unwrap();
 
         assert_eq!(
@@ -505,13 +563,13 @@ contract test3 {
         }
 
         let returns = runtime
-            .function(
-                "baz",
-                &[BorshToken::Uint {
-                    width: 32,
-                    value: BigInt::from(i),
-                }],
-            )
+            .function("baz")
+            .arguments(&[BorshToken::Uint {
+                width: 32,
+                value: BigInt::from(i),
+            }])
+            .accounts(vec![("dataAccount", data_account)])
+            .call()
             .unwrap();
 
         assert_eq!(

+ 277 - 121
tests/solana_tests/storage.rs

@@ -18,8 +18,15 @@ fn simple() {
         }"#,
     );
 
-    vm.constructor(&[]);
-    let returns = vm.function("boom", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("boom")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Int {
@@ -48,8 +55,15 @@ fn simple() {
         }"#,
     );
 
-    vm.constructor(&[]);
-    let returns = vm.function("func", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("func")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Int {
@@ -76,53 +90,84 @@ fn string() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(
-        vm.data()[0..20].to_vec(),
+        vm.account_data[&data_account].data[0..20].to_vec(),
         vec![65, 177, 160, 100, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0]
     );
 
-    let returns = vm.function("get", &[]).unwrap();
+    let returns = vm
+        .function("get")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::String(String::from("")));
 
-    vm.function("set", &[BorshToken::String(String::from("Hello, World!"))]);
+    vm.function("set")
+        .arguments(&[BorshToken::String(String::from("Hello, World!"))])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(
-        vm.data()[0..20].to_vec(),
+        vm.account_data[&data_account].data[0..20].to_vec(),
         vec![65, 177, 160, 100, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0]
     );
 
-    assert_eq!(vm.data()[40..53].to_vec(), b"Hello, World!");
+    assert_eq!(
+        vm.account_data[&data_account].data[40..53].to_vec(),
+        b"Hello, World!"
+    );
 
-    let returns = vm.function("get", &[]).unwrap();
+    let returns = vm
+        .function("get")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::String(String::from("Hello, World!")));
 
     // try replacing it with a string of the same length. This is a special
     // fast-path handling
-    vm.function("set", &[BorshToken::String(String::from("Hallo, Werld!"))]);
+    vm.function("set")
+        .arguments(&[BorshToken::String(String::from("Hallo, Werld!"))])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get", &[]).unwrap();
+    let returns = vm
+        .function("get")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::String(String::from("Hallo, Werld!")));
 
     assert_eq!(
-        vm.data()[0..20].to_vec(),
+        vm.account_data[&data_account].data[0..20].to_vec(),
         vec![65, 177, 160, 100, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0]
     );
 
     // Try setting this to an empty string. This is also a special case where
     // the result should be offset 0
-    vm.function("set", &[BorshToken::String(String::from(""))]);
+    vm.function("set")
+        .arguments(&[BorshToken::String(String::from(""))])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get", &[]).unwrap();
+    let returns = vm
+        .function("get")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::String(String::from("")));
 
     assert_eq!(
-        vm.data()[0..20].to_vec(),
+        vm.account_data[&data_account].data[0..20].to_vec(),
         vec![65, 177, 160, 100, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0]
     );
 }
@@ -152,14 +197,21 @@ fn bytes() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(
-        vm.data()[0..20].to_vec(),
+        vm.account_data[&data_account].data[0..20].to_vec(),
         vec![11, 66, 182, 57, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0]
     );
 
-    let returns = vm.function("foo_length", &[]).unwrap();
+    let returns = vm
+        .function("foo_length")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -169,15 +221,15 @@ fn bytes() {
         }
     );
 
-    vm.function(
-        "set_foo",
-        &[BorshToken::Bytes(
+    vm.function("set_foo")
+        .arguments(&[BorshToken::Bytes(
             b"The shoemaker always wears the worst shoes".to_vec(),
-        )],
-    );
+        )])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(
-        vm.data()[0..20].to_vec(),
+        vm.account_data[&data_account].data[0..20].to_vec(),
         vec![11, 66, 182, 57, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0]
     );
 
@@ -186,52 +238,52 @@ fn bytes() {
         .enumerate()
     {
         let returns = vm
-            .function(
-                "get_foo_offset",
-                &[BorshToken::Uint {
-                    width: 32,
-                    value: BigInt::from(i),
-                }],
-            )
+            .function("get_foo_offset")
+            .arguments(&[BorshToken::Uint {
+                width: 32,
+                value: BigInt::from(i),
+            }])
+            .accounts(vec![("dataAccount", data_account)])
+            .call()
             .unwrap();
 
         assert_eq!(returns, BorshToken::uint8_fixed_array(vec![*b]));
     }
 
-    vm.function(
-        "set_foo_offset",
-        &[
+    vm.function("set_foo_offset")
+        .arguments(&[
             BorshToken::Uint {
                 width: 32,
                 value: BigInt::from(2u8),
             },
             BorshToken::FixedBytes(b"E".to_vec()),
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function(
-        "set_foo_offset",
-        &[
+    vm.function("set_foo_offset")
+        .arguments(&[
             BorshToken::Uint {
                 width: 32,
                 value: BigInt::from(7u8),
             },
             BorshToken::FixedBytes(b"E".to_vec()),
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     for (i, b) in b"ThE shoEmaker always wears the worst shoes"
         .iter()
         .enumerate()
     {
         let returns = vm
-            .function(
-                "get_foo_offset",
-                &[BorshToken::Uint {
-                    width: 32,
-                    value: BigInt::from(i),
-                }],
-            )
+            .function("get_foo_offset")
+            .arguments(&[BorshToken::Uint {
+                width: 32,
+                value: BigInt::from(i),
+            }])
+            .accounts(vec![("dataAccount", data_account)])
+            .call()
             .unwrap();
 
         assert_eq!(returns, BorshToken::uint8_fixed_array(vec![*b]));
@@ -264,18 +316,21 @@ fn bytes_set_subscript_range() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function(
-        "set_foo_offset",
-        &[
+    vm.function("set_foo_offset")
+        .arguments(&[
             BorshToken::Uint {
                 width: 32,
                 value: BigInt::zero(),
             },
             BorshToken::FixedBytes(b"E".to_vec()),
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }
 
 #[test]
@@ -304,22 +359,25 @@ fn bytes_get_subscript_range() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function(
-        "set_foo",
-        &[BorshToken::Bytes(
+    vm.function("set_foo")
+        .arguments(&[BorshToken::Bytes(
             b"The shoemaker always wears the worst shoes".to_vec(),
-        )],
-    );
+        )])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function(
-        "get_foo_offset",
-        &[BorshToken::Uint {
+    vm.function("get_foo_offset")
+        .arguments(&[BorshToken::Uint {
             width: 32,
             value: BigInt::from(0x80000000u64),
-        }],
-    );
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }
 
 #[test]
@@ -335,10 +393,13 @@ fn storage_alignment() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(
-        vm.data()[0..40].to_vec(),
+        vm.account_data[&data_account].data[0..40].to_vec(),
         vec![
             11, 66, 182, 57, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 1, 0, 3, 2, 4, 0, 0, 0, 8, 7, 6,
             5, 0, 0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9
@@ -367,31 +428,60 @@ fn bytes_push_pop() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get_bs", &[]).unwrap();
+    let returns = vm
+        .function("get_bs")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::Bytes(vec!(0x0e, 0xda)));
 
-    let returns = vm.function("pop", &[]).unwrap();
+    let returns = vm
+        .function("pop")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::uint8_fixed_array(vec!(0xda)));
 
-    let returns = vm.function("get_bs", &[]).unwrap();
+    let returns = vm
+        .function("get_bs")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::Bytes(vec!(0x0e)));
 
-    vm.function("push", &[BorshToken::FixedBytes(vec![0x41])]);
+    vm.function("push")
+        .arguments(&[BorshToken::FixedBytes(vec![0x41])])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    println!("data:{}", hex::encode(vm.data()));
+    //println!("data:{}", hex::encode(vm.data()));
 
-    let returns = vm.function("get_bs", &[]).unwrap();
+    let returns = vm
+        .function("get_bs")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::Bytes(vec!(0x0e, 0x41)));
 
-    vm.function("push", &[BorshToken::FixedBytes(vec![0x01])]);
+    vm.function("push")
+        .arguments(&[BorshToken::FixedBytes(vec![0x01])])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get_bs", &[]).unwrap();
+    let returns = vm
+        .function("get_bs")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::Bytes(vec!(0x0e, 0x41, 0x01)));
 }
@@ -410,9 +500,14 @@ fn bytes_empty_pop() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function("pop", &[]);
+    vm.function("pop")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }
 
 #[test]
@@ -442,19 +537,28 @@ fn simple_struct() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function("set_s2", &[]);
+    vm.function("set_s2")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(
-        vm.data()[0..32].to_vec(),
+        vm.account_data[&data_account].data[0..32].to_vec(),
         vec![
             11, 66, 182, 57, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 173, 222, 0, 0, 254, 0, 0, 0,
             173, 222, 0, 0, 0, 0, 0, 0
         ]
     );
 
-    let returns = vm.function("get_s1", &[]).unwrap();
+    let returns = vm
+        .function("get_s1")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -470,9 +574,8 @@ fn simple_struct() {
         ])
     );
 
-    vm.function(
-        "set_s1",
-        &[BorshToken::Tuple(vec![
+    vm.function("set_s1")
+        .arguments(&[BorshToken::Tuple(vec![
             BorshToken::Uint {
                 width: 8,
                 value: BigInt::from(102u8),
@@ -481,10 +584,15 @@ fn simple_struct() {
                 width: 32,
                 value: BigInt::from(3240121u32),
             },
-        ])],
-    );
+        ])])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get_s1", &[]).unwrap();
+    let returns = vm
+        .function("get_s1")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -534,12 +642,17 @@ fn struct_in_struct() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function("set_s2", &[]);
+    vm.function("set_s2")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(
-        vm.data()[0..52].to_vec(),
+        vm.account_data[&data_account].data[0..52].to_vec(),
         vec![
             11, 66, 182, 57, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 173, 222, 0, 0, 0, 0, 0, 0, 254,
             0, 0, 0, 0, 0, 102, 0, 0, 0, 0, 0, 114, 97, 98, 111, 111, 102, 0, 0, 0, 0, 0, 0, 210,
@@ -547,7 +660,11 @@ fn struct_in_struct() {
         ]
     );
 
-    let returns = vm.function("get_s1", &[]).unwrap();
+    let returns = vm
+        .function("get_s1")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -570,9 +687,8 @@ fn struct_in_struct() {
         ])
     );
 
-    vm.function(
-        "set_s1",
-        &[BorshToken::Tuple(vec![
+    vm.function("set_s1")
+        .arguments(&[BorshToken::Tuple(vec![
             BorshToken::Uint {
                 width: 8,
                 value: BigInt::from(127u8),
@@ -588,10 +704,15 @@ fn struct_in_struct() {
                 width: 64,
                 value: BigInt::from(12345678901234567890u64),
             },
-        ])],
-    );
+        ])])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get_s1", &[]).unwrap();
+    let returns = vm
+        .function("get_s1")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -643,12 +764,17 @@ fn string_in_struct() {
             }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function("set_s2", &[]);
+    vm.function("set_s2")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(
-        vm.data()[0..64].to_vec(),
+        vm.account_data[&data_account].data[0..64].to_vec(),
         vec![
             11, 66, 182, 57, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 173, 222, 0, 0, 0, 0, 0, 0, 254,
             0, 0, 0, 56, 0, 0, 0, 210, 2, 150, 73, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,
@@ -656,7 +782,11 @@ fn string_in_struct() {
         ]
     );
 
-    let returns = vm.function("get_s1", &[]).unwrap();
+    let returns = vm
+        .function("get_s1")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -673,9 +803,8 @@ fn string_in_struct() {
         ])
     );
 
-    vm.function(
-        "set_s1",
-        &[BorshToken::Tuple(vec![
+    vm.function("set_s1")
+        .arguments(&[BorshToken::Tuple(vec![
             BorshToken::Uint {
                 width: 8,
                 value: BigInt::from(127u8),
@@ -685,10 +814,15 @@ fn string_in_struct() {
                 width: 64,
                 value: BigInt::from(12345678901234567890u64),
             },
-        ])],
-    );
+        ])])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get_s1", &[]).unwrap();
+    let returns = vm
+        .function("get_s1")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -758,11 +892,21 @@ fn complex_struct() {
         }"#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    vm.function("set_s2", &[]);
+    vm.function("set_s2")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get_s1", &[]).unwrap().unwrap_tuple();
+    let returns = vm
+        .function("get_s1")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap()
+        .unwrap_tuple();
 
     assert_eq!(
         returns,
@@ -796,9 +940,8 @@ fn complex_struct() {
         ]
     );
 
-    vm.function(
-        "set_s1",
-        &[
+    vm.function("set_s1")
+        .arguments(&[
             BorshToken::Tuple(vec![
                 BorshToken::Uint {
                     width: 8,
@@ -823,10 +966,16 @@ fn complex_struct() {
                 BorshToken::String(String::from("be as honest as the day is long")),
             ]),
             BorshToken::String(String::from("yadayada")),
-        ],
-    );
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get_s1", &[]).unwrap().unwrap_tuple();
+    let returns = vm
+        .function("get_s1")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap()
+        .unwrap_tuple();
 
     assert_eq!(
         returns,
@@ -858,9 +1007,16 @@ fn complex_struct() {
         ]
     );
 
-    vm.function("rm", &[]);
+    vm.function("rm")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let returns = vm.function("get_s1", &[]).unwrap().unwrap_tuple();
+    let returns = vm
+        .function("get_s1")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap()
+        .unwrap_tuple();
 
     assert_eq!(
         returns,

+ 46 - 29
tests/solana_tests/strings.rs

@@ -20,13 +20,21 @@ fn storage_string_length() {
     }
     "#,
     );
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
-    let _ = vm.function(
-        "setString",
-        &[BorshToken::String("coffee_tastes_good".to_string())],
-    );
-    let returns = vm.function("getLength", &[]).unwrap();
+    let _ = vm
+        .function("setString")
+        .arguments(&[BorshToken::String("coffee_tastes_good".to_string())])
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("getLength")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -59,8 +67,17 @@ fn load_string_vector() {
       "#,
     );
 
-    vm.constructor(&[]);
-    let returns = vm.function("testLength", &[]).unwrap().unwrap_tuple();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("testLength")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap()
+        .unwrap_tuple();
+
     assert_eq!(
         returns[0],
         BorshToken::Uint {
@@ -84,35 +101,35 @@ fn load_string_vector() {
     );
 
     let returns = vm
-        .function(
-            "getString",
-            &[BorshToken::Uint {
-                width: 32,
-                value: BigInt::zero(),
-            }],
-        )
+        .function("getString")
+        .arguments(&[BorshToken::Uint {
+            width: 32,
+            value: BigInt::zero(),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
     assert_eq!(returns, BorshToken::String("tea".to_string()));
 
     let returns = vm
-        .function(
-            "getString",
-            &[BorshToken::Uint {
-                width: 32,
-                value: BigInt::one(),
-            }],
-        )
+        .function("getString")
+        .arguments(&[BorshToken::Uint {
+            width: 32,
+            value: BigInt::one(),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
     assert_eq!(returns, BorshToken::String("coffe".to_string()));
 
     let returns = vm
-        .function(
-            "getString",
-            &[BorshToken::Uint {
-                width: 32,
-                value: BigInt::from(2u8),
-            }],
-        )
+        .function("getString")
+        .arguments(&[BorshToken::Uint {
+            width: 32,
+            value: BigInt::from(2u8),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap();
     assert_eq!(returns, BorshToken::String("sixsix".to_string()));
 }

+ 5 - 2
tests/solana_tests/structs.rs

@@ -24,7 +24,10 @@ fn struct_as_reference() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
     let input = BorshToken::Array(vec![
         BorshToken::Tuple(vec![
             BorshToken::Uint {
@@ -48,7 +51,7 @@ fn struct_as_reference() {
         ]),
     ]);
 
-    let res = vm.function("try_ref", &[input]).unwrap();
+    let res = vm.function("try_ref").arguments(&[input]).call().unwrap();
     assert_eq!(
         res,
         BorshToken::Array(vec![

+ 23 - 5
tests/solana_tests/unused_variable_elimination.rs

@@ -37,9 +37,19 @@ fn test_returns() {
     "#;
 
     let mut vm = build_solidity(file);
-    vm.constructor(&[]);
-    let _ = vm.function("assign", &[]);
-    let returns = vm.function("pb1", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let _ = vm
+        .function("assign")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("pb1")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(
         returns,
@@ -49,7 +59,11 @@ fn test_returns() {
         }
     );
 
-    let returns = vm.function("test1", &[]).unwrap();
+    let returns = vm
+        .function("test1")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Int {
@@ -57,7 +71,11 @@ fn test_returns() {
             value: BigInt::from(52u8)
         }
     );
-    let returns = vm.function("test2", &[]).unwrap();
+    let returns = vm
+        .function("test2")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Int {

+ 39 - 9
tests/solana_tests/using.rs

@@ -29,8 +29,15 @@ fn using_for_contracts() {
         }"#,
     );
 
-    runtime.constructor(&[]);
-    runtime.function("test", &[]);
+    let data_account = runtime.initialize_data_account();
+    runtime
+        .function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    runtime
+        .function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     assert_eq!(runtime.logs, "Hello");
 
@@ -72,8 +79,18 @@ fn using_for_contracts() {
         }"#,
     );
 
-    runtime.constructor(&[]);
-    runtime.function("test", &[]);
+    let data_account = runtime.initialize_data_account();
+    runtime
+        .function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    runtime
+        .function("test")
+        .accounts(vec![
+            ("dataAccount", data_account),
+            ("systemProgram", [0; 32]),
+        ])
+        .call();
 
     assert_eq!(runtime.logs, "X libX contractx:2");
 }
@@ -202,9 +219,22 @@ fn user_defined_oper() {
         }"#,
     );
 
-    runtime.constructor(&[]);
-
-    runtime.function("test_cmp", &[]);
-    runtime.function("test_arith", &[]);
-    runtime.function("test_bit", &[]);
+    let data_account = runtime.initialize_data_account();
+    runtime
+        .function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
+    runtime
+        .function("test_cmp")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    runtime
+        .function("test_arith")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    runtime
+        .function("test_bit")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 }

+ 9 - 2
tests/solana_tests/vector_to_slice.rs

@@ -20,8 +20,15 @@ fn test_slice_in_phi() {
     "#;
 
     let mut vm = build_solidity(file);
-    vm.constructor(&[]);
-    let returns = vm.function("test", &[]).unwrap();
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+    let returns = vm
+        .function("test")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
     assert_eq!(returns, BorshToken::String(String::from("Hello!")));
 }

+ 230 - 184
tests/solana_tests/yul.rs

@@ -60,9 +60,17 @@ contract testing  {
       "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
+    let returns = vm
+        .function("test_slot")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
 
-    let returns = vm.function("test_slot", &[]).unwrap();
     assert_eq!(
         returns,
         BorshToken::Uint {
@@ -72,27 +80,26 @@ contract testing  {
     );
 
     let returns = vm
-        .function(
-            "call_data_array",
-            &[BorshToken::Array(vec![
-                BorshToken::Uint {
-                    width: 32,
-                    value: BigInt::from(3u8),
-                },
-                BorshToken::Uint {
-                    width: 32,
-                    value: BigInt::from(5u8),
-                },
-                BorshToken::Uint {
-                    width: 32,
-                    value: BigInt::from(7u8),
-                },
-                BorshToken::Uint {
-                    width: 32,
-                    value: BigInt::from(11u8),
-                },
-            ])],
-        )
+        .function("call_data_array")
+        .arguments(&[BorshToken::Array(vec![
+            BorshToken::Uint {
+                width: 32,
+                value: BigInt::from(3u8),
+            },
+            BorshToken::Uint {
+                width: 32,
+                value: BigInt::from(5u8),
+            },
+            BorshToken::Uint {
+                width: 32,
+                value: BigInt::from(7u8),
+            },
+            BorshToken::Uint {
+                width: 32,
+                value: BigInt::from(11u8),
+            },
+        ])])
+        .call()
         .unwrap()
         .unwrap_tuple();
 
@@ -111,13 +118,19 @@ contract testing  {
         ]
     );
 
-    let returns = vm.function("selector_address", &[]).unwrap().unwrap_tuple();
+    let returns = vm
+        .function("selector_address")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap()
+        .unwrap_tuple();
+
     assert_eq!(
         returns,
         vec![
             BorshToken::Uint {
                 width: 256,
-                value: BigInt::from_bytes_be(Sign::Plus, vm.stack[0].data.as_ref())
+                value: BigInt::from_bytes_be(Sign::Plus, data_account.as_ref())
             },
             BorshToken::Uint {
                 width: 256,
@@ -167,18 +180,22 @@ contract testing  {
       "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "general_test",
-            &[BorshToken::Uint {
-                width: 64,
-                value: BigInt::from(5u8),
-            }],
-        )
+        .function("general_test")
+        .arguments(&[BorshToken::Uint {
+            width: 64,
+            value: BigInt::from(5u8),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
+
     assert_eq!(
         returns,
         vec![
@@ -194,15 +211,16 @@ contract testing  {
     );
 
     let returns = vm
-        .function(
-            "general_test",
-            &[BorshToken::Uint {
-                width: 64,
-                value: BigInt::from(78u8),
-            }],
-        )
+        .function("general_test")
+        .arguments(&[BorshToken::Uint {
+            width: 64,
+            value: BigInt::from(78u8),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
+
     assert_eq!(
         returns,
         vec![
@@ -218,15 +236,16 @@ contract testing  {
     );
 
     let returns = vm
-        .function(
-            "general_test",
-            &[BorshToken::Uint {
-                width: 64,
-                value: BigInt::from(259u16),
-            }],
-        )
+        .function("general_test")
+        .arguments(&[BorshToken::Uint {
+            width: 64,
+            value: BigInt::from(259u16),
+        }])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
+
     assert_eq!(
         returns,
         vec![
@@ -272,21 +291,26 @@ contract c {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
     let num: Vec<u8> = vec![
         0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
         0x11, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
         0x2f, 0x31,
     ];
+
     let returns = vm
-        .function(
-            "getByte",
-            &[BorshToken::Uint {
-                width: 256,
-                value: BigInt::from_bytes_be(Sign::Plus, &num),
-            }],
-        )
+        .function("getByte")
+        .arguments(&[BorshToken::Uint {
+            width: 256,
+            value: BigInt::from_bytes_be(Sign::Plus, &num),
+        }])
+        .call()
         .unwrap();
+
     assert_eq!(
         returns,
         BorshToken::Uint {
@@ -296,21 +320,21 @@ contract c {
     );
 
     let returns = vm
-        .function(
-            "divide",
-            &[
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from(4u8),
-                },
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from(3u8),
-                },
-            ],
-        )
+        .function("divide")
+        .arguments(&[
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from(4u8),
+            },
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from(3u8),
+            },
+        ])
+        .call()
         .unwrap()
         .unwrap_tuple();
+
     assert_eq!(
         returns,
         vec![
@@ -326,21 +350,21 @@ contract c {
     );
 
     let returns = vm
-        .function(
-            "divide",
-            &[
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from(4u8),
-                },
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::zero(),
-                },
-            ],
-        )
+        .function("divide")
+        .arguments(&[
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from(4u8),
+            },
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::zero(),
+            },
+        ])
+        .call()
         .unwrap()
         .unwrap_tuple();
+
     assert_eq!(
         returns,
         vec![
@@ -356,25 +380,25 @@ contract c {
     );
 
     let returns = vm
-        .function(
-            "mods",
-            &[
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from(4u8),
-                },
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from(2u8),
-                },
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from(3u8),
-                },
-            ],
-        )
+        .function("mods")
+        .arguments(&[
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from(4u8),
+            },
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from(2u8),
+            },
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from(3u8),
+            },
+        ])
+        .call()
         .unwrap()
         .unwrap_tuple();
+
     assert_eq!(
         returns,
         vec![
@@ -390,25 +414,25 @@ contract c {
     );
 
     let returns = vm
-        .function(
-            "mods",
-            &[
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from(4u8),
-                },
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from(2u8),
-                },
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::zero(),
-                },
-            ],
-        )
+        .function("mods")
+        .arguments(&[
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from(4u8),
+            },
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from(2u8),
+            },
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::zero(),
+            },
+        ])
+        .call()
         .unwrap()
         .unwrap_tuple();
+
     assert_eq!(
         returns,
         vec![
@@ -448,20 +472,24 @@ fn external_function() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
     let mut addr: Vec<u8> = vec![0; 32];
     addr[5] = 90;
     let returns = vm
-        .function(
-            "test",
-            &[
-                BorshToken::Uint {
-                    width: 256,
-                    value: BigInt::from_bytes_le(Sign::Plus, addr.as_slice()),
-                },
-                BorshToken::FixedBytes(vec![1, 2, 3, 4, 5, 6, 7, 8]),
-            ],
-        )
+        .function("test")
+        .arguments(&[
+            BorshToken::Uint {
+                width: 256,
+                value: BigInt::from_bytes_le(Sign::Plus, addr.as_slice()),
+            },
+            BorshToken::FixedBytes(vec![1, 2, 3, 4, 5, 6, 7, 8]),
+        ])
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
         .unwrap()
         .unwrap_tuple();
 
@@ -499,8 +527,17 @@ contract testing  {
 }"#,
     );
 
-    runtime.constructor(&[]);
-    let returns = runtime.function("test_address", &[]).unwrap();
+    let data_account = runtime.initialize_data_account();
+    runtime
+        .function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
+    let returns = runtime
+        .function("test_address")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     let addr = returns.into_bigint().unwrap();
     let mut b_vec = addr.to_bytes_be().1;
     // test_address() returns address as uint256. If the highest bits are 0, then addr.to_bytes_be().1
@@ -508,14 +545,18 @@ contract testing  {
     while b_vec.len() < 32 {
         b_vec.insert(0, 0);
     }
-    assert_eq!(&b_vec, runtime.stack[0].data.as_ref());
+    assert_eq!(&b_vec, data_account.as_ref());
 
     runtime
         .account_data
-        .get_mut(&runtime.stack[0].data)
+        .get_mut(&data_account)
         .unwrap()
         .lamports = 102;
-    let returns = runtime.function("test_balance", &[]).unwrap();
+    let returns = runtime
+        .function("test_balance")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
     assert_eq!(
         returns,
         BorshToken::Uint {
@@ -524,7 +565,12 @@ contract testing  {
         }
     );
 
-    let returns = runtime.function("test_selfbalance", &[]).unwrap();
+    let returns = runtime
+        .function("test_selfbalance")
+        .accounts(vec![("dataAccount", data_account)])
+        .call()
+        .unwrap();
+
     assert_eq!(
         returns,
         BorshToken::Uint {
@@ -554,9 +600,13 @@ fn addmod_mulmod() {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
+
+    let returns = vm.function("testMod").call().unwrap().unwrap_tuple();
 
-    let returns = vm.function("testMod", &[]).unwrap().unwrap_tuple();
     assert_eq!(
         returns,
         vec![
@@ -632,16 +682,18 @@ contract Testing {
         "#,
     );
 
-    vm.constructor(&[]);
+    let data_account = vm.initialize_data_account();
+    vm.function("new")
+        .accounts(vec![("dataAccount", data_account)])
+        .call();
 
     let returns = vm
-        .function(
-            "switch_default",
-            &[BorshToken::Uint {
-                width: 256,
-                value: BigInt::one(),
-            }],
-        )
+        .function("switch_default")
+        .arguments(&[BorshToken::Uint {
+            width: 256,
+            value: BigInt::one(),
+        }])
+        .call()
         .unwrap();
     assert_eq!(
         returns,
@@ -652,13 +704,12 @@ contract Testing {
     );
 
     let returns = vm
-        .function(
-            "switch_default",
-            &[BorshToken::Uint {
-                width: 256,
-                value: BigInt::from(2u8),
-            }],
-        )
+        .function("switch_default")
+        .arguments(&[BorshToken::Uint {
+            width: 256,
+            value: BigInt::from(2u8),
+        }])
+        .call()
         .unwrap();
     assert_eq!(
         returns,
@@ -669,13 +720,12 @@ contract Testing {
     );
 
     let returns = vm
-        .function(
-            "switch_default",
-            &[BorshToken::Uint {
-                width: 256,
-                value: BigInt::from(6u8),
-            }],
-        )
+        .function("switch_default")
+        .arguments(&[BorshToken::Uint {
+            width: 256,
+            value: BigInt::from(6u8),
+        }])
+        .call()
         .unwrap();
     assert_eq!(
         returns,
@@ -686,13 +736,12 @@ contract Testing {
     );
 
     let returns = vm
-        .function(
-            "switch_no_default",
-            &[BorshToken::Uint {
-                width: 256,
-                value: BigInt::one(),
-            }],
-        )
+        .function("switch_no_default")
+        .arguments(&[BorshToken::Uint {
+            width: 256,
+            value: BigInt::one(),
+        }])
+        .call()
         .unwrap();
     assert_eq!(
         returns,
@@ -703,13 +752,12 @@ contract Testing {
     );
 
     let returns = vm
-        .function(
-            "switch_no_default",
-            &[BorshToken::Uint {
-                width: 256,
-                value: BigInt::from(2u8),
-            }],
-        )
+        .function("switch_no_default")
+        .arguments(&[BorshToken::Uint {
+            width: 256,
+            value: BigInt::from(2u8),
+        }])
+        .call()
         .unwrap();
     assert_eq!(
         returns,
@@ -720,13 +768,12 @@ contract Testing {
     );
 
     let returns = vm
-        .function(
-            "switch_no_default",
-            &[BorshToken::Uint {
-                width: 256,
-                value: BigInt::from(6u8),
-            }],
-        )
+        .function("switch_no_default")
+        .arguments(&[BorshToken::Uint {
+            width: 256,
+            value: BigInt::from(6u8),
+        }])
+        .call()
         .unwrap();
     assert_eq!(
         returns,
@@ -737,13 +784,12 @@ contract Testing {
     );
 
     let returns = vm
-        .function(
-            "switch_no_case",
-            &[BorshToken::Uint {
-                width: 256,
-                value: BigInt::from(3u8),
-            }],
-        )
+        .function("switch_no_case")
+        .arguments(&[BorshToken::Uint {
+            width: 256,
+            value: BigInt::from(3u8),
+        }])
+        .call()
         .unwrap();
     assert_eq!(
         returns,

Деякі файли не було показано, через те що забагато файлів було змінено