diff --git a/test/functional/wallet_importmulti.py b/test/functional/wallet_importmulti.py
index 5c789b1c0..a163f7018 100755
--- a/test/functional/wallet_importmulti.py
+++ b/test/functional/wallet_importmulti.py
@@ -2,9 +2,43 @@
 # Copyright (c) 2014-2018 The Bitcoin Core developers
 # Distributed under the MIT software license, see the accompanying
 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
-"""Test the importmulti RPC."""
+"""Test the importmulti RPC.
 
-from test_framework import script
+Test importmulti by generating keys on node0, importing the scriptPubKeys and
+addresses on node1 and then testing the address info for the different address
+variants.
+
+- `get_key()` and `get_multisig()` are called to generate keys on node0 and
+  return the privkeys, pubkeys and all variants of scriptPubKey and address.
+- `test_importmulti()` is called to send an importmulti call to node1, test
+  success, and (if unsuccessful) test the error code and error message returned.
+- `test_address()` is called to call getaddressinfo for an address on node1
+  and test the values returned."""
+from collections import namedtuple
+
+from test_framework.address import (
+    key_to_p2pkh,
+    key_to_p2sh_p2wpkh,
+    key_to_p2wpkh,
+    script_to_p2sh,
+    script_to_p2sh_p2wsh,
+    script_to_p2wsh,
+)
+from test_framework.script import (
+    CScript,
+    OP_0,
+    OP_2,
+    OP_3,
+    OP_CHECKMULTISIG,
+    OP_CHECKSIG,
+    OP_DUP,
+    OP_EQUAL,
+    OP_EQUALVERIFY,
+    OP_HASH160,
+    OP_NOP,
+    hash160,
+    sha256,
+)
 from test_framework.test_framework import BitcoinTestFramework
 from test_framework.util import (
     assert_equal,
@@ -13,12 +47,26 @@ from test_framework.util import (
     bytes_to_hex_str,
     hex_str_to_bytes
 )
-from test_framework.script import (
-    CScript,
-    OP_0,
-    hash160
-)
-from test_framework.messages import sha256
+
+Key = namedtuple('Key', ['privkey',
+                         'pubkey',
+                         'p2pkh_script',
+                         'p2pkh_addr',
+                         'p2wpkh_script',
+                         'p2wpkh_addr',
+                         'p2sh_p2wpkh_script',
+                         'p2sh_p2wpkh_redeem_script',
+                         'p2sh_p2wpkh_addr'])
+
+Multisig = namedtuple('Multisig', ['privkeys',
+                                   'pubkeys',
+                                   'p2sh_script',
+                                   'p2sh_addr',
+                                   'redeem_script',
+                                   'p2wsh_script',
+                                   'p2wsh_addr',
+                                   'p2sh_p2wsh_script',
+                                   'p2sh_p2wsh_addr'])
 
 class ImportMultiTest(BitcoinTestFramework):
     def set_test_params(self):
@@ -32,7 +80,64 @@ class ImportMultiTest(BitcoinTestFramework):
     def setup_network(self):
         self.setup_nodes()
 
-    def run_test (self):
+    def get_key(self):
+        """Generate a fresh key on node0
+
+        Returns a named tuple of privkey, pubkey and all address and scripts."""
+        addr = self.nodes[0].getnewaddress()
+        pubkey = self.nodes[0].getaddressinfo(addr)['pubkey']
+        pkh = hash160(hex_str_to_bytes(pubkey))
+        return Key(self.nodes[0].dumpprivkey(addr),
+                   pubkey,
+                   CScript([OP_DUP, OP_HASH160, pkh, OP_EQUALVERIFY, OP_CHECKSIG]).hex(),  # p2pkh
+                   key_to_p2pkh(pubkey),  # p2pkh addr
+                   CScript([OP_0, pkh]).hex(),  # p2wpkh
+                   key_to_p2wpkh(pubkey),  # p2wpkh addr
+                   CScript([OP_HASH160, hash160(CScript([OP_0, pkh])), OP_EQUAL]).hex(),  # p2sh-p2wpkh
+                   CScript([OP_0, pkh]).hex(),  # p2sh-p2wpkh redeem script
+                   key_to_p2sh_p2wpkh(pubkey))  # p2sh-p2wpkh addr
+
+    def get_multisig(self):
+        """Generate a fresh multisig on node0
+
+        Returns a named tuple of privkeys, pubkeys and all address and scripts."""
+        addrs = []
+        pubkeys = []
+        for _ in range(3):
+            addr = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
+            addrs.append(addr['address'])
+            pubkeys.append(addr['pubkey'])
+        script_code = CScript([OP_2] + [hex_str_to_bytes(pubkey) for pubkey in pubkeys] + [OP_3, OP_CHECKMULTISIG])
+        witness_script = CScript([OP_0, sha256(script_code)])
+        return Multisig([self.nodes[0].dumpprivkey(addr) for addr in addrs],
+                        pubkeys,
+                        CScript([OP_HASH160, hash160(script_code), OP_EQUAL]).hex(),  # p2sh
+                        script_to_p2sh(script_code),  # p2sh addr
+                        script_code.hex(),  # redeem script
+                        witness_script.hex(),  # p2wsh
+                        script_to_p2wsh(script_code),  # p2wsh addr
+                        CScript([OP_HASH160, witness_script, OP_EQUAL]).hex(),  # p2sh-p2wsh
+                        script_to_p2sh_p2wsh(script_code))  # p2sh-p2wsh addr
+
+    def test_importmulti(self, req, success, error_code=None, error_message=None):
+        """Run importmulti and assert success"""
+        result = self.nodes[1].importmulti([req])
+        assert_equal(result[0]['success'], success)
+        if error_code is not None:
+            assert_equal(result[0]['error']['code'], error_code)
+            assert_equal(result[0]['error']['message'], error_message)
+
+    def test_address(self, address, **kwargs):
+        """Get address info for `address` and test whether the returned values are as expected."""
+        addr_info = self.nodes[1].getaddressinfo(address)
+        for key, value in kwargs.items():
+            if value is None:
+                if key in addr_info.keys():
+                    raise AssertionError("key {} unexpectedly returned in getaddressinfo.".format(key))
+            elif addr_info[key] != value:
+                raise AssertionError("key {} value {} did not match expected value {}".format(key, addr_info[key], value))
+
+    def run_test(self):
         self.log.info("Mining blocks...")
         self.nodes[0].generate(1)
         self.nodes[1].generate(1)
@@ -40,587 +145,460 @@ class ImportMultiTest(BitcoinTestFramework):
 
         node0_address1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
 
-        #Check only one address
+        # Check only one address
         assert_equal(node0_address1['ismine'], True)
 
-        #Node 1 sync test
-        assert_equal(self.nodes[1].getblockcount(),1)
+        # Node 1 sync test
+        assert_equal(self.nodes[1].getblockcount(), 1)
 
-        #Address Test - before import
+        # Address Test - before import
         address_info = self.nodes[1].getaddressinfo(node0_address1['address'])
         assert_equal(address_info['iswatchonly'], False)
         assert_equal(address_info['ismine'], False)
 
-
         # RPC importmulti -----------------------------------------------
 
         # Bitcoin Address (implicit non-internal)
         self.log.info("Should import an address")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": address['address']
-            },
-            "timestamp": "now",
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], True)
-        assert_equal(address_assert['ismine'], False)
-        assert_equal(address_assert['timestamp'], timestamp)
-        assert_equal(address_assert['ischange'], False)
-        watchonly_address = address['address']
+        key = self.get_key()
+        address = key.p2pkh_addr
+        self.test_importmulti({"scriptPubKey": {"address": address},
+                               "timestamp": "now"},
+                              True)
+        self.test_address(address,
+                          iswatchonly=True,
+                          ismine=False,
+                          timestamp=timestamp,
+                          ischange=False)
+        watchonly_address = address
         watchonly_timestamp = timestamp
 
         self.log.info("Should not import an invalid address")
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": "not valid address",
-            },
-            "timestamp": "now",
-        }])
-        assert_equal(result[0]['success'], False)
-        assert_equal(result[0]['error']['code'], -5)
-        assert_equal(result[0]['error']['message'], 'Invalid address')
+        self.test_importmulti({"scriptPubKey": {"address": "not valid address"},
+                               "timestamp": "now"},
+                              False,
+                              error_code=-5,
+                              error_message='Invalid address')
 
         # ScriptPubKey + internal
         self.log.info("Should import a scriptPubKey with internal flag")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": address['scriptPubKey'],
-            "timestamp": "now",
-            "internal": True
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], True)
-        assert_equal(address_assert['ismine'], False)
-        assert_equal(address_assert['timestamp'], timestamp)
-        assert_equal(address_assert['ischange'], True)
+        key = self.get_key()
+        self.test_importmulti({"scriptPubKey": key.p2pkh_script,
+                               "timestamp": "now",
+                               "internal": True},
+                              True)
+        self.test_address(key.p2pkh_addr,
+                          iswatchonly=True,
+                          ismine=False,
+                          timestamp=timestamp,
+                          ischange=True)
 
         # ScriptPubKey + internal + label
         self.log.info("Should not allow a label to be specified when internal is true")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": address['scriptPubKey'],
-            "timestamp": "now",
-            "internal": True,
-            "label": "Example label"
-        }])
-        assert_equal(result[0]['success'], False)
-        assert_equal(result[0]['error']['code'], -8)
-        assert_equal(result[0]['error']['message'], 'Internal addresses should not have a label')
+        key = self.get_key()
+        self.test_importmulti({"scriptPubKey": key.p2pkh_script,
+                               "timestamp": "now",
+                               "internal": True,
+                               "label": "Example label"},
+                              False,
+                              error_code=-8,
+                              error_message='Internal addresses should not have a label')
 
         # Nonstandard scriptPubKey + !internal
         self.log.info("Should not import a nonstandard scriptPubKey without internal flag")
-        nonstandardScriptPubKey = address['scriptPubKey'] + bytes_to_hex_str(script.CScript([script.OP_NOP]))
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": nonstandardScriptPubKey,
-            "timestamp": "now",
-        }])
-        assert_equal(result[0]['success'], False)
-        assert_equal(result[0]['error']['code'], -8)
-        assert_equal(result[0]['error']['message'], 'Internal must be set to true for nonstandard scriptPubKey imports.')
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], False)
-        assert_equal(address_assert['ismine'], False)
-        assert_equal('timestamp' in address_assert, False)
-
+        nonstandardScriptPubKey = key.p2pkh_script + bytes_to_hex_str(CScript([OP_NOP]))
+        key = self.get_key()
+        address = key.p2pkh_addr
+        self.test_importmulti({"scriptPubKey": nonstandardScriptPubKey,
+                               "timestamp": "now"},
+                              False,
+                              error_code=-8,
+                              error_message='Internal must be set to true for nonstandard scriptPubKey imports.')
+        self.test_address(address,
+                          iswatchonly=False,
+                          ismine=False,
+                          timestamp=None)
 
         # Address + Public key + !Internal(explicit)
         self.log.info("Should import an address with public key")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": address['address']
-            },
-            "timestamp": "now",
-            "pubkeys": [ address['pubkey'] ],
-            "internal": False
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], True)
-        assert_equal(address_assert['ismine'], False)
-        assert_equal(address_assert['timestamp'], timestamp)
-
+        key = self.get_key()
+        address = key.p2pkh_addr
+        self.test_importmulti({"scriptPubKey": {"address": address},
+                               "timestamp": "now",
+                               "pubkeys": [key.pubkey],
+                               "internal": False},
+                              True)
+        self.test_address(address,
+                          iswatchonly=True,
+                          ismine=False,
+                          timestamp=timestamp)
 
         # ScriptPubKey + Public key + internal
         self.log.info("Should import a scriptPubKey with internal and with public key")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        request = [{
-            "scriptPubKey": address['scriptPubKey'],
-            "timestamp": "now",
-            "pubkeys": [ address['pubkey'] ],
-            "internal": True
-        }]
-        result = self.nodes[1].importmulti(requests=request)
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], True)
-        assert_equal(address_assert['ismine'], False)
-        assert_equal(address_assert['timestamp'], timestamp)
+        key = self.get_key()
+        address = key.p2pkh_addr
+        self.test_importmulti({"scriptPubKey": key.p2pkh_script,
+                               "timestamp": "now",
+                               "pubkeys": [key.pubkey],
+                               "internal": True},
+                              True)
+        self.test_address(address,
+                          iswatchonly=True,
+                          ismine=False,
+                          timestamp=timestamp)
 
         # Nonstandard scriptPubKey + Public key + !internal
         self.log.info("Should not import a nonstandard scriptPubKey without internal and with public key")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        request = [{
-            "scriptPubKey": nonstandardScriptPubKey,
-            "timestamp": "now",
-            "pubkeys": [ address['pubkey'] ]
-        }]
-        result = self.nodes[1].importmulti(requests=request)
-        assert_equal(result[0]['success'], False)
-        assert_equal(result[0]['error']['code'], -8)
-        assert_equal(result[0]['error']['message'], 'Internal must be set to true for nonstandard scriptPubKey imports.')
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], False)
-        assert_equal(address_assert['ismine'], False)
-        assert_equal('timestamp' in address_assert, False)
+        key = self.get_key()
+        address = key.p2pkh_addr
+        self.test_importmulti({"scriptPubKey": nonstandardScriptPubKey,
+                               "timestamp": "now",
+                               "pubkeys": [key.pubkey]},
+                              False,
+                              error_code=-8,
+                              error_message='Internal must be set to true for nonstandard scriptPubKey imports.')
+        self.test_address(address,
+                          iswatchonly=False,
+                          ismine=False,
+                          timestamp=None)
 
         # Address + Private key + !watchonly
         self.log.info("Should import an address with private key")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": address['address']
-            },
-            "timestamp": "now",
-            "keys": [ self.nodes[0].dumpprivkey(address['address']) ]
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], False)
-        assert_equal(address_assert['ismine'], True)
-        assert_equal(address_assert['timestamp'], timestamp)
+        key = self.get_key()
+        address = key.p2pkh_addr
+        self.test_importmulti({"scriptPubKey": {"address": address},
+                               "timestamp": "now",
+                               "keys": [key.privkey]},
+                              True)
+        self.test_address(address,
+                          iswatchonly=False,
+                          ismine=True,
+                          timestamp=timestamp)
 
         self.log.info("Should not import an address with private key if is already imported")
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": address['address']
-            },
-            "timestamp": "now",
-            "keys": [ self.nodes[0].dumpprivkey(address['address']) ]
-        }])
-        assert_equal(result[0]['success'], False)
-        assert_equal(result[0]['error']['code'], -4)
-        assert_equal(result[0]['error']['message'], 'The wallet already contains the private key for this address or script')
+        self.test_importmulti({"scriptPubKey": {"address": address},
+                               "timestamp": "now",
+                               "keys": [key.privkey]},
+                              False,
+                              error_code=-4,
+                              error_message='The wallet already contains the private key for this address or script')
 
         # Address + Private key + watchonly
         self.log.info("Should not import an address with private key and with watchonly")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": address['address']
-            },
-            "timestamp": "now",
-            "keys": [ self.nodes[0].dumpprivkey(address['address']) ],
-            "watchonly": True
-        }])
-        assert_equal(result[0]['success'], False)
-        assert_equal(result[0]['error']['code'], -8)
-        assert_equal(result[0]['error']['message'], 'Watch-only addresses should not include private keys')
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], False)
-        assert_equal(address_assert['ismine'], False)
-        assert_equal('timestamp' in address_assert, False)
+        key = self.get_key()
+        address = key.p2pkh_addr
+        self.test_importmulti({"scriptPubKey": {"address": address},
+                               "timestamp": "now",
+                               "keys": [key.privkey],
+                               "watchonly": True},
+                              False,
+                              error_code=-8,
+                              error_message='Watch-only addresses should not include private keys')
+        self.test_address(address,
+                          iswatchonly=False,
+                          ismine=False,
+                          timestamp=None)
 
         # ScriptPubKey + Private key + internal
         self.log.info("Should import a scriptPubKey with internal and with private key")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": address['scriptPubKey'],
-            "timestamp": "now",
-            "keys": [ self.nodes[0].dumpprivkey(address['address']) ],
-            "internal": True
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], False)
-        assert_equal(address_assert['ismine'], True)
-        assert_equal(address_assert['timestamp'], timestamp)
+        key = self.get_key()
+        address = key.p2pkh_addr
+        self.test_importmulti({"scriptPubKey": key.p2pkh_script,
+                               "timestamp": "now",
+                               "keys": [key.privkey],
+                               "internal": True},
+                              True)
+        self.test_address(address,
+                          iswatchonly=False,
+                          ismine=True,
+                          timestamp=timestamp)
 
         # Nonstandard scriptPubKey + Private key + !internal
         self.log.info("Should not import a nonstandard scriptPubKey without internal and with private key")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": nonstandardScriptPubKey,
-            "timestamp": "now",
-            "keys": [ self.nodes[0].dumpprivkey(address['address']) ]
-        }])
-        assert_equal(result[0]['success'], False)
-        assert_equal(result[0]['error']['code'], -8)
-        assert_equal(result[0]['error']['message'], 'Internal must be set to true for nonstandard scriptPubKey imports.')
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], False)
-        assert_equal(address_assert['ismine'], False)
-        assert_equal('timestamp' in address_assert, False)
-
+        key = self.get_key()
+        address = key.p2pkh_addr
+        self.test_importmulti({"scriptPubKey": nonstandardScriptPubKey,
+                               "timestamp": "now",
+                               "keys": [key.privkey]},
+                              False,
+                              error_code=-8,
+                              error_message='Internal must be set to true for nonstandard scriptPubKey imports.')
+        self.test_address(address,
+                          iswatchonly=False,
+                          ismine=False,
+                          timestamp=None)
 
         # P2SH address
-        sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        sig_address_2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        sig_address_3 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']])
+        multisig = self.get_multisig()
         self.nodes[1].generate(100)
-        self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
+        self.nodes[1].sendtoaddress(multisig.p2sh_addr, 10.00)
         self.nodes[1].generate(1)
         timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
 
         self.log.info("Should import a p2sh")
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": multi_sig_script['address']
-            },
-            "timestamp": "now",
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(multi_sig_script['address'])
-        assert_equal(address_assert['isscript'], True)
-        assert_equal(address_assert['iswatchonly'], True)
-        assert_equal(address_assert['timestamp'], timestamp)
-        p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
+        self.test_importmulti({"scriptPubKey": {"address": multisig.p2sh_addr},
+                               "timestamp": "now"},
+                              True)
+        self.test_address(multisig.p2sh_addr,
+                          isscript=True,
+                          iswatchonly=True,
+                          timestamp=timestamp)
+        p2shunspent = self.nodes[1].listunspent(0, 999999, [multisig.p2sh_addr])[0]
         assert_equal(p2shunspent['spendable'], False)
         assert_equal(p2shunspent['solvable'], False)
 
-
         # P2SH + Redeem script
-        sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        sig_address_2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        sig_address_3 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']])
+        multisig = self.get_multisig()
         self.nodes[1].generate(100)
-        self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
+        self.nodes[1].sendtoaddress(multisig.p2sh_addr, 10.00)
         self.nodes[1].generate(1)
         timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
 
         self.log.info("Should import a p2sh with respective redeem script")
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": multi_sig_script['address']
-            },
-            "timestamp": "now",
-            "redeemscript": multi_sig_script['redeemScript']
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(multi_sig_script['address'])
-        assert_equal(address_assert['timestamp'], timestamp)
+        self.test_importmulti({"scriptPubKey": {"address": multisig.p2sh_addr},
+                               "timestamp": "now",
+                               "redeemscript": multisig.redeem_script},
+                              True)
+        self.test_address(multisig.p2sh_addr, timestamp=timestamp)
 
-        p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
+        p2shunspent = self.nodes[1].listunspent(0, 999999, [multisig.p2sh_addr])[0]
         assert_equal(p2shunspent['spendable'], False)
         assert_equal(p2shunspent['solvable'], True)
 
-
         # P2SH + Redeem script + Private Keys + !Watchonly
-        sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        sig_address_2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        sig_address_3 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']])
+        multisig = self.get_multisig()
         self.nodes[1].generate(100)
-        self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
+        self.nodes[1].sendtoaddress(multisig.p2sh_addr, 10.00)
         self.nodes[1].generate(1)
         timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
 
         self.log.info("Should import a p2sh with respective redeem script and private keys")
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": multi_sig_script['address']
-            },
-            "timestamp": "now",
-            "redeemscript": multi_sig_script['redeemScript'],
-            "keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address'])]
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(multi_sig_script['address'])
-        assert_equal(address_assert['timestamp'], timestamp)
+        self.test_importmulti({"scriptPubKey": {"address": multisig.p2sh_addr},
+                               "timestamp": "now",
+                               "redeemscript": multisig.redeem_script,
+                               "keys": multisig.privkeys[0:2]},
+                              True)
+        self.test_address(multisig.p2sh_addr,
+                          timestamp=timestamp)
 
-        p2shunspent = self.nodes[1].listunspent(0,999999, [multi_sig_script['address']])[0]
+        p2shunspent = self.nodes[1].listunspent(0, 999999, [multisig.p2sh_addr])[0]
         assert_equal(p2shunspent['spendable'], False)
         assert_equal(p2shunspent['solvable'], True)
 
         # P2SH + Redeem script + Private Keys + Watchonly
-        sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        sig_address_2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        sig_address_3 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        multi_sig_script = self.nodes[0].createmultisig(2, [sig_address_1['pubkey'], sig_address_2['pubkey'], sig_address_3['pubkey']])
+        multisig = self.get_multisig()
         self.nodes[1].generate(100)
-        self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00)
+        self.nodes[1].sendtoaddress(multisig.p2sh_addr, 10.00)
         self.nodes[1].generate(1)
         timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime']
 
         self.log.info("Should import a p2sh with respective redeem script and private keys")
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": multi_sig_script['address']
-            },
-            "timestamp": "now",
-            "redeemscript": multi_sig_script['redeemScript'],
-            "keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address'])],
-            "watchonly": True
-        }])
-        assert_equal(result[0]['success'], False)
-        assert_equal(result[0]['error']['code'], -8)
-        assert_equal(result[0]['error']['message'], 'Watch-only addresses should not include private keys')
-
+        self.test_importmulti({"scriptPubKey": {"address": multisig.p2sh_addr},
+                               "timestamp": "now",
+                               "redeemscript": multisig.redeem_script,
+                               "keys": multisig.privkeys[0:2],
+                               "watchonly": True},
+                              False,
+                              error_code=-8,
+                              error_message='Watch-only addresses should not include private keys')
 
         # Address + Public key + !Internal + Wrong pubkey
         self.log.info("Should not import an address with a wrong public key")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        address2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": address['address']
-            },
-            "timestamp": "now",
-            "pubkeys": [ address2['pubkey'] ]
-        }])
-        assert_equal(result[0]['success'], False)
-        assert_equal(result[0]['error']['code'], -5)
-        assert_equal(result[0]['error']['message'], 'Key does not match address destination')
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], False)
-        assert_equal(address_assert['ismine'], False)
-        assert_equal('timestamp' in address_assert, False)
-
+        key = self.get_key()
+        address = key.p2pkh_addr
+        wrong_key = self.get_key().pubkey
+        self.test_importmulti({"scriptPubKey": {"address": address},
+                               "timestamp": "now",
+                               "pubkeys": [wrong_key]},
+                              False,
+                              error_code=-5,
+                              error_message='Key does not match address destination')
+        self.test_address(address,
+                          iswatchonly=False,
+                          ismine=False,
+                          timestamp=None)
 
         # ScriptPubKey + Public key + internal + Wrong pubkey
         self.log.info("Should not import a scriptPubKey with internal and with a wrong public key")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        address2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        request = [{
-            "scriptPubKey": address['scriptPubKey'],
-            "timestamp": "now",
-            "pubkeys": [ address2['pubkey'] ],
-            "internal": True
-        }]
-        result = self.nodes[1].importmulti(request)
-        assert_equal(result[0]['success'], False)
-        assert_equal(result[0]['error']['code'], -5)
-        assert_equal(result[0]['error']['message'], 'Key does not match address destination')
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], False)
-        assert_equal(address_assert['ismine'], False)
-        assert_equal('timestamp' in address_assert, False)
-
+        key = self.get_key()
+        address = key.p2pkh_addr
+        wrong_key = self.get_key().pubkey
+        self.test_importmulti({"scriptPubKey": key.p2pkh_script,
+                               "timestamp": "now",
+                               "pubkeys": [wrong_key],
+                               "internal": True},
+                              False,
+                              error_code=-5,
+                              error_message='Key does not match address destination')
+        self.test_address(address,
+                          iswatchonly=False,
+                          ismine=False,
+                          timestamp=None)
 
         # Address + Private key + !watchonly + Wrong private key
         self.log.info("Should not import an address with a wrong private key")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        address2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": address['address']
-            },
-            "timestamp": "now",
-            "keys": [ self.nodes[0].dumpprivkey(address2['address']) ]
-        }])
-        assert_equal(result[0]['success'], False)
-        assert_equal(result[0]['error']['code'], -5)
-        assert_equal(result[0]['error']['message'], 'Key does not match address destination')
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], False)
-        assert_equal(address_assert['ismine'], False)
-        assert_equal('timestamp' in address_assert, False)
-
+        key = self.get_key()
+        address = key.p2pkh_addr
+        wrong_privkey = self.get_key().privkey
+        self.test_importmulti({"scriptPubKey": {"address": address},
+                               "timestamp": "now",
+                               "keys": [wrong_privkey]},
+                              False,
+                              error_code=-5,
+                              error_message='Key does not match address destination')
+        self.test_address(address,
+                          iswatchonly=False,
+                          ismine=False,
+                          timestamp=None)
 
         # ScriptPubKey + Private key + internal + Wrong private key
         self.log.info("Should not import a scriptPubKey with internal and with a wrong private key")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        address2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": address['scriptPubKey'],
-            "timestamp": "now",
-            "keys": [ self.nodes[0].dumpprivkey(address2['address']) ],
-            "internal": True
-        }])
-        assert_equal(result[0]['success'], False)
-        assert_equal(result[0]['error']['code'], -5)
-        assert_equal(result[0]['error']['message'], 'Key does not match address destination')
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], False)
-        assert_equal(address_assert['ismine'], False)
-        assert_equal('timestamp' in address_assert, False)
-
+        key = self.get_key()
+        address = key.p2pkh_addr
+        wrong_privkey = self.get_key().privkey
+        self.test_importmulti({"scriptPubKey": key.p2pkh_script,
+                               "timestamp": "now",
+                               "keys": [wrong_privkey],
+                               "internal": True},
+                              False,
+                              error_code=-5,
+                              error_message='Key does not match address destination')
+        self.test_address(address,
+                          iswatchonly=False,
+                          ismine=False,
+                          timestamp=None)
 
         # Importing existing watch only address with new timestamp should replace saved timestamp.
         assert_greater_than(timestamp, watchonly_timestamp)
         self.log.info("Should replace previously saved watch only timestamp.")
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": watchonly_address,
-            },
-            "timestamp": "now",
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(watchonly_address)
-        assert_equal(address_assert['iswatchonly'], True)
-        assert_equal(address_assert['ismine'], False)
-        assert_equal(address_assert['timestamp'], timestamp)
+        self.test_importmulti({"scriptPubKey": {"address": watchonly_address},
+                               "timestamp": "now"},
+                              True)
+        self.test_address(watchonly_address,
+                          iswatchonly=True,
+                          ismine=False,
+                          timestamp=timestamp)
         watchonly_timestamp = timestamp
 
-
         # restart nodes to check for proper serialization/deserialization of watch only address
         self.stop_nodes()
         self.start_nodes()
-        address_assert = self.nodes[1].getaddressinfo(watchonly_address)
-        assert_equal(address_assert['iswatchonly'], True)
-        assert_equal(address_assert['ismine'], False)
-        assert_equal(address_assert['timestamp'], watchonly_timestamp)
+        self.test_address(watchonly_address,
+                          iswatchonly=True,
+                          ismine=False,
+                          timestamp=watchonly_timestamp)
 
         # Bad or missing timestamps
         self.log.info("Should throw on invalid or missing timestamp values")
         assert_raises_rpc_error(-3, 'Missing required timestamp field for key',
-            self.nodes[1].importmulti, [{
-                "scriptPubKey": address['scriptPubKey'],
-            }])
+                                self.nodes[1].importmulti, [{"scriptPubKey": key.p2pkh_script}])
         assert_raises_rpc_error(-3, 'Expected number or "now" timestamp value for key. got type string',
-            self.nodes[1].importmulti, [{
-                "scriptPubKey": address['scriptPubKey'],
-                "timestamp": "",
-            }])
+                                self.nodes[1].importmulti, [{
+                                    "scriptPubKey": key.p2pkh_script,
+                                    "timestamp": ""
+                                }])
 
         # Import P2WPKH address as watch only
         self.log.info("Should import a P2WPKH address as watch only")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress(address_type="bech32"))
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": address['address']
-            },
-            "timestamp": "now",
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], True)
-        assert_equal(address_assert['solvable'], False)
+        key = self.get_key()
+        address = key.p2wpkh_addr
+        self.test_importmulti({"scriptPubKey": {"address": address},
+                               "timestamp": "now"},
+                              True)
+        self.test_address(address,
+                          iswatchonly=True,
+                          solvable=False)
 
         # Import P2WPKH address with public key but no private key
         self.log.info("Should import a P2WPKH address and public key as solvable but not spendable")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress(address_type="bech32"))
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": address['address']
-            },
-            "timestamp": "now",
-            "pubkeys": [ address['pubkey'] ]
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['ismine'], False)
-        assert_equal(address_assert['solvable'], True)
+        key = self.get_key()
+        address = key.p2wpkh_addr
+        self.test_importmulti({"scriptPubKey": {"address": address},
+                               "timestamp": "now",
+                               "pubkeys": [key.pubkey]},
+                              True)
+        self.test_address(address,
+                          ismine=False,
+                          solvable=True)
 
         # Import P2WPKH address with key and check it is spendable
         self.log.info("Should import a P2WPKH address with key")
-        address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress(address_type="bech32"))
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": address['address']
-            },
-            "timestamp": "now",
-            "keys": [self.nodes[0].dumpprivkey(address['address'])]
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(address['address'])
-        assert_equal(address_assert['iswatchonly'], False)
-        assert_equal(address_assert['ismine'], True)
+        key = self.get_key()
+        address = key.p2wpkh_addr
+        self.test_importmulti({"scriptPubKey": {"address": address},
+                               "timestamp": "now",
+                               "keys": [key.privkey]},
+                              True)
+        self.test_address(address,
+                          iswatchonly=False,
+                          ismine=True)
 
         # P2WSH multisig address without scripts or keys
-        sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        sig_address_2 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        multi_sig_script = self.nodes[0].addmultisigaddress(2, [sig_address_1['pubkey'], sig_address_2['pubkey']], "", "bech32")
+        multisig = self.get_multisig()
         self.log.info("Should import a p2wsh multisig as watch only without respective redeem script and private keys")
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": multi_sig_script['address']
-            },
-            "timestamp": "now"
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(multi_sig_script['address'])
-        assert_equal(address_assert['solvable'], False)
+        self.test_importmulti({"scriptPubKey": {"address": multisig.p2wsh_addr},
+                               "timestamp": "now"},
+                              True)
+        self.test_address(multisig.p2sh_addr,
+                          solvable=False)
 
         # Same P2WSH multisig address as above, but now with witnessscript + private keys
-        self.log.info("Should import a p2wsh with respective redeem script and private keys")
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": multi_sig_script['address']
-            },
-            "timestamp": "now",
-            "witnessscript": multi_sig_script['redeemScript'],
-            "keys": [ self.nodes[0].dumpprivkey(sig_address_1['address']), self.nodes[0].dumpprivkey(sig_address_2['address']) ]
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(multi_sig_script['address'])
-        assert_equal(address_assert['solvable'], True)
-        assert_equal(address_assert['ismine'], True)
-        assert_equal(address_assert['sigsrequired'], 2)
+        self.log.info("Should import a p2wsh with respective witness script and private keys")
+        self.test_importmulti({"scriptPubKey": {"address": multisig.p2wsh_addr},
+                               "timestamp": "now",
+                               "witnessscript": multisig.redeem_script,
+                               "keys": multisig.privkeys},
+                              True)
+        self.test_address(multisig.p2sh_addr,
+                          solvable=True,
+                          ismine=True,
+                          sigsrequired=2)
 
         # P2SH-P2WPKH address with no redeemscript or public or private key
-        sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress(address_type="p2sh-segwit"))
-        pubkeyhash = hash160(hex_str_to_bytes(sig_address_1['pubkey']))
-        pkscript = CScript([OP_0, pubkeyhash])
+        key = self.get_key()
+        address = key.p2sh_p2wpkh_addr
         self.log.info("Should import a p2sh-p2wpkh without redeem script or keys")
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": sig_address_1['address']
-            },
-            "timestamp": "now"
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(sig_address_1['address'])
-        assert_equal(address_assert['solvable'], False)
-        assert_equal(address_assert['ismine'], False)
+        self.test_importmulti({"scriptPubKey": {"address": address},
+                               "timestamp": "now"},
+                              True)
+        self.test_address(address,
+                          solvable=False,
+                          ismine=False)
 
         # P2SH-P2WPKH address + redeemscript + public key with no private key
         self.log.info("Should import a p2sh-p2wpkh with respective redeem script and pubkey as solvable")
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": sig_address_1['address']
-            },
-            "timestamp": "now",
-            "redeemscript": bytes_to_hex_str(pkscript),
-            "pubkeys": [ sig_address_1['pubkey'] ]
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(sig_address_1['address'])
-        assert_equal(address_assert['solvable'], True)
-        assert_equal(address_assert['ismine'], False)
+        self.test_importmulti({"scriptPubKey": {"address": address},
+                               "timestamp": "now",
+                               "redeemscript": key.p2sh_p2wpkh_redeem_script,
+                               "pubkeys": [key.pubkey]},
+                              True)
+        self.test_address(address,
+                          solvable=True,
+                          ismine=False)
 
         # P2SH-P2WPKH address + redeemscript + private key
-        sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress(address_type="p2sh-segwit"))
-        pubkeyhash = hash160(hex_str_to_bytes(sig_address_1['pubkey']))
-        pkscript = CScript([OP_0, pubkeyhash])
+        key = self.get_key()
+        address = key.p2sh_p2wpkh_addr
         self.log.info("Should import a p2sh-p2wpkh with respective redeem script and private keys")
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": sig_address_1['address']
-            },
-            "timestamp": "now",
-            "redeemscript": bytes_to_hex_str(pkscript),
-            "keys": [ self.nodes[0].dumpprivkey(sig_address_1['address'])]
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(sig_address_1['address'])
-        assert_equal(address_assert['solvable'], True)
-        assert_equal(address_assert['ismine'], True)
+        self.test_importmulti({"scriptPubKey": {"address": address},
+                               "timestamp": "now",
+                               "redeemscript": key.p2sh_p2wpkh_redeem_script,
+                               "keys": [key.privkey]},
+                              True)
+        self.test_address(address,
+                          solvable=True,
+                          ismine=True)
 
-        # P2SH-P2WSH 1-of-1 multisig + redeemscript with no private key
-        sig_address_1 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
-        multi_sig_script = self.nodes[0].addmultisigaddress(1, [sig_address_1['pubkey']], "", "p2sh-segwit")
-        scripthash = sha256(hex_str_to_bytes(multi_sig_script['redeemScript']))
-        redeem_script = CScript([OP_0, scripthash])
+        # P2SH-P2WSH multisig + redeemscript with no private key
+        multisig = self.get_multisig()
         self.log.info("Should import a p2sh-p2wsh with respective redeem script but no private key")
-        result = self.nodes[1].importmulti([{
-            "scriptPubKey": {
-                "address": multi_sig_script['address']
-            },
-            "timestamp": "now",
-            "redeemscript": bytes_to_hex_str(redeem_script),
-            "witnessscript": multi_sig_script['redeemScript']
-        }])
-        assert_equal(result[0]['success'], True)
-        address_assert = self.nodes[1].getaddressinfo(multi_sig_script['address'])
-        assert_equal(address_assert['solvable'], True)
+        self.test_importmulti({"scriptPubKey": {"address": multisig.p2sh_p2wsh_addr},
+                               "timestamp": "now",
+                               "redeemscript": multisig.p2wsh_script,
+                               "witnessscript": multisig.redeem_script},
+                              True)
+        self.test_address(address,
+                          solvable=True)
 
 if __name__ == '__main__':
-    ImportMultiTest ().main ()
+    ImportMultiTest().main()