diff --git a/nucypher/blockchain/eth/aragon.py b/nucypher/blockchain/eth/aragon.py
new file mode 100644
index 000000000..ede19407a
--- /dev/null
+++ b/nucypher/blockchain/eth/aragon.py
@@ -0,0 +1,38 @@
+"""
+ This file is part of nucypher.
+
+ nucypher is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ nucypher is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with nucypher. If not, see .
+"""
+from typing import Iterable, Tuple
+
+from eth_utils import to_canonical_address
+from web3 import Web3
+
+
+class CallScriptCodec:
+
+ CALLSCRIPT_ID = Web3.toBytes(hexstr='0x00000001')
+
+ @classmethod
+ def encode(cls, actions: Iterable[Tuple[str, bytes]]):
+ callscript = [cls.CALLSCRIPT_ID]
+
+ for target, action_data in actions:
+ encoded_action = (to_canonical_address(target),
+ len(action_data).to_bytes(4, 'big'),
+ action_data)
+ callscript.extend(encoded_action)
+
+ callscript_data = b''.join(callscript)
+ return callscript_data
diff --git a/tests/unit/test_aragon.py b/tests/unit/test_aragon.py
new file mode 100644
index 000000000..11f2377b7
--- /dev/null
+++ b/tests/unit/test_aragon.py
@@ -0,0 +1,49 @@
+"""
+ This file is part of nucypher.
+
+ nucypher is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ nucypher is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with nucypher. If not, see .
+"""
+
+import os
+
+import pytest
+from eth_utils import to_canonical_address
+
+from nucypher.blockchain.eth.aragon import CallScriptCodec
+
+
+def test_callscriptcodec():
+ assert CallScriptCodec.CALLSCRIPT_ID == bytes.fromhex("00000001")
+
+
+def test_callscript_encoding_empty():
+ actions = tuple()
+
+ callscript_data = CallScriptCodec.encode(actions)
+ expected_callscript = CallScriptCodec.CALLSCRIPT_ID
+ assert expected_callscript == callscript_data
+
+
+@pytest.mark.parametrize('data_length', range(0, 100, 5))
+def test_callscript_encoding_one_action(get_random_checksum_address, data_length):
+ target = get_random_checksum_address()
+ data = os.urandom(data_length)
+ actions = [(target, data)]
+
+ callscript_data = CallScriptCodec.encode(actions)
+ expected_callscript = b''.join((CallScriptCodec.CALLSCRIPT_ID,
+ to_canonical_address(target),
+ data_length.to_bytes(4, 'big'),
+ data))
+ assert expected_callscript == callscript_data