@ethernity-cloud/sdk-js 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +185 -0
  3. package/build.js +22 -0
  4. package/init.js +301 -0
  5. package/nodenithy/build/las/Dockerfile +5 -0
  6. package/nodenithy/build/securelock/Dockerfile.tmpl +65 -0
  7. package/nodenithy/build/securelock/scripts/binary-fs-build.sh +28 -0
  8. package/nodenithy/build/securelock/src/.env +3 -0
  9. package/nodenithy/build/securelock/src/etny_crypto.js +201 -0
  10. package/nodenithy/build/securelock/src/etny_exec.js +65 -0
  11. package/nodenithy/build/securelock/src/image_registry_abi.js +808 -0
  12. package/nodenithy/build/securelock/src/models.js +261 -0
  13. package/nodenithy/build/securelock/src/package.json +40 -0
  14. package/nodenithy/build/securelock/src/pox_abi.js +1491 -0
  15. package/nodenithy/build/securelock/src/securelock.js.tmpl +421 -0
  16. package/nodenithy/build/securelock/src/swift_stream_service.js +147 -0
  17. package/nodenithy/build/securelock/src/task_status.js +15 -0
  18. package/nodenithy/build/securelock/src/wallet.js +29 -0
  19. package/nodenithy/build/squash/Dockerfile +7 -0
  20. package/nodenithy/build/trustedzone/Dockerfile.tmpl +57 -0
  21. package/nodenithy/build/trustedzone/scripts/binary-fs-build.sh +22 -0
  22. package/nodenithy/build/trustedzone/src/.env +3 -0
  23. package/nodenithy/build/trustedzone/src/etny_crypto.js +202 -0
  24. package/nodenithy/build/trustedzone/src/etny_exec.js +54 -0
  25. package/nodenithy/build/trustedzone/src/image_registry_abi.js +808 -0
  26. package/nodenithy/build/trustedzone/src/models.js +261 -0
  27. package/nodenithy/build/trustedzone/src/package.json +40 -0
  28. package/nodenithy/build/trustedzone/src/pox_abi.js +1491 -0
  29. package/nodenithy/build/trustedzone/src/swift_stream_service.js +147 -0
  30. package/nodenithy/build/trustedzone/src/task_status.js +15 -0
  31. package/nodenithy/build/trustedzone/src/test.js +44 -0
  32. package/nodenithy/build/trustedzone/src/trustedzone.js.tmpl +508 -0
  33. package/nodenithy/build/trustedzone/src/wallet.js +28 -0
  34. package/nodenithy/build/validator/Dockerfile +58 -0
  35. package/nodenithy/build/validator/package-lock.json +6 -0
  36. package/nodenithy/build/validator/scripts/binary-fs-build.sh +19 -0
  37. package/nodenithy/build/validator/src/.env +3 -0
  38. package/nodenithy/build/validator/src/cert.pem +5 -0
  39. package/nodenithy/build/validator/src/etny_crypto.js +204 -0
  40. package/nodenithy/build/validator/src/etny_exec.js +52 -0
  41. package/nodenithy/build/validator/src/image_registry_abi.js +808 -0
  42. package/nodenithy/build/validator/src/key.pem +6 -0
  43. package/nodenithy/build/validator/src/models.js +261 -0
  44. package/nodenithy/build/validator/src/package-lock.json +2498 -0
  45. package/nodenithy/build/validator/src/package.json +40 -0
  46. package/nodenithy/build/validator/src/pox_abi.js +1491 -0
  47. package/nodenithy/build/validator/src/swift_stream_service.js +147 -0
  48. package/nodenithy/build/validator/src/task_status.js +15 -0
  49. package/nodenithy/build/validator/src/test.js +44 -0
  50. package/nodenithy/build/validator/src/trustedzone.js +613 -0
  51. package/nodenithy/build/validator/src/validator_abi.js +834 -0
  52. package/nodenithy/build/validator/src/wallet.js +28 -0
  53. package/nodenithy/build.js +184 -0
  54. package/nodenithy/build.mjs +179 -0
  55. package/nodenithy/build.sh +161 -0
  56. package/nodenithy/ipfs.js +135 -0
  57. package/nodenithy/ipfs.mjs +551 -0
  58. package/nodenithy/public/favicon.ico +0 -0
  59. package/nodenithy/public/index.html +43 -0
  60. package/nodenithy/public/logo192.png +0 -0
  61. package/nodenithy/public/logo512.png +0 -0
  62. package/nodenithy/public/manifest.json +25 -0
  63. package/nodenithy/public/robots.txt +3 -0
  64. package/nodenithy/run/__pycache__/swift_stream_service.cpython-312.pyc +0 -0
  65. package/nodenithy/run/app/input.txt +4 -0
  66. package/nodenithy/run/app/payload.js +4 -0
  67. package/nodenithy/run/docker-compose-final.yml.tmpl +65 -0
  68. package/nodenithy/run/docker-compose-swift-stream.yml +17 -0
  69. package/nodenithy/run/docker-compose.yml.tmpl +76 -0
  70. package/nodenithy/run/etny-securelock-test.yaml.tpl +46 -0
  71. package/nodenithy/run/etny-trustedzone-test.yaml.tpl +45 -0
  72. package/nodenithy/run/git.sh +22 -0
  73. package/nodenithy/run/image_registry.abi +1 -0
  74. package/nodenithy/run/image_registry.js +372 -0
  75. package/nodenithy/run/image_registry.py +327 -0
  76. package/nodenithy/run/image_registry_runner.py +71 -0
  77. package/nodenithy/run/ipfs.sh +58 -0
  78. package/nodenithy/run/ipfs_pre.sh +75 -0
  79. package/nodenithy/run/public_key_service.js +90 -0
  80. package/nodenithy/run/public_key_service.py +107 -0
  81. package/nodenithy/run/swift_stream_service.py +212 -0
  82. package/nodenithy/run/swiftstream.py +37 -0
  83. package/nodenithy/run/swiftstream1.py +27 -0
  84. package/nodenithy/run.js +538 -0
  85. package/nodenithy/run.sh +277 -0
  86. package/nodenithy/scripts/build-ipfs-upload.sh +23 -0
  87. package/nodenithy/scripts/build.sh +40 -0
  88. package/nodenithy/scripts/ipfs-daemon.sh +7 -0
  89. package/nodenithy/scripts/run.sh +50 -0
  90. package/nodenithy/src/App.css +57 -0
  91. package/nodenithy/src/ec_helloworld_example.js +64 -0
  92. package/nodenithy/src/index.css +13 -0
  93. package/nodenithy/src/index.js +17 -0
  94. package/nodenithy/src/preStart.js +45 -0
  95. package/nodenithy/src/preStart.mjs +57 -0
  96. package/nodenithy/src/reportWebVitals.js +13 -0
  97. package/nodenithy/src/serverless/backend.js +5 -0
  98. package/package.json +48 -0
  99. package/postinstall.js +34 -0
  100. package/publish.js +126 -0
  101. package/pynithy/build/docker-compose.yml +68 -0
  102. package/pynithy/build/las/Dockerfile +11 -0
  103. package/pynithy/build/las/src/etny_entrypoint.sh +6 -0
  104. package/pynithy/build/las/src/las_entrypoint.sh +26 -0
  105. package/pynithy/build/scripts/binary-fs-build.sh +28 -0
  106. package/pynithy/build/securelock/Dockerfile.tmpl +78 -0
  107. package/pynithy/build/securelock/scripts/binary-fs-build.sh +41 -0
  108. package/pynithy/build/securelock/src/app/.env +5 -0
  109. package/pynithy/build/securelock/src/app/cert1-ca1-clean.crt +10 -0
  110. package/pynithy/build/securelock/src/app/cert1-ca1-clean.key +6 -0
  111. package/pynithy/build/securelock/src/app/enclave_pub_cert.pem +10 -0
  112. package/pynithy/build/securelock/src/app/input.txt +1 -0
  113. package/pynithy/build/securelock/src/app/payload.py +25 -0
  114. package/pynithy/build/securelock/src/app/public-cert-clean.pem +10 -0
  115. package/pynithy/build/securelock/src/app/result.txt +1 -0
  116. package/pynithy/build/securelock/src/app/transaction.txt +1 -0
  117. package/pynithy/build/securelock/src/etny_crypto.py +167 -0
  118. package/pynithy/build/securelock/src/etny_exec.py +79 -0
  119. package/pynithy/build/securelock/src/image_registry.abi +1 -0
  120. package/pynithy/build/securelock/src/key_generation.py +17 -0
  121. package/pynithy/build/securelock/src/models.py +176 -0
  122. package/pynithy/build/securelock/src/pox.abi +1489 -0
  123. package/pynithy/build/securelock/src/securelock.py.tmpl +411 -0
  124. package/pynithy/build/securelock/src/swift_stream_service.py +186 -0
  125. package/pynithy/build/trustedzone/Dockerfile.tmpl +56 -0
  126. package/pynithy/build/trustedzone/scripts/binary-fs-build.sh +32 -0
  127. package/pynithy/build/trustedzone/src/app/.env +5 -0
  128. package/pynithy/build/trustedzone/src/app/cert1-ca1-clean.crt +10 -0
  129. package/pynithy/build/trustedzone/src/app/cert1-ca1-clean.key +6 -0
  130. package/pynithy/build/trustedzone/src/app/enclave_pub_cert.pem +10 -0
  131. package/pynithy/build/trustedzone/src/app/input.txt +1 -0
  132. package/pynithy/build/trustedzone/src/app/payload.py +25 -0
  133. package/pynithy/build/trustedzone/src/app/public-cert-clean.pem +10 -0
  134. package/pynithy/build/trustedzone/src/app/result.txt +1 -0
  135. package/pynithy/build/trustedzone/src/app/securelock.crt +10 -0
  136. package/pynithy/build/trustedzone/src/app/transaction.txt +1 -0
  137. package/pynithy/build/trustedzone/src/app/trustedzone.crt +10 -0
  138. package/pynithy/build/trustedzone/src/etny_crypto.py +188 -0
  139. package/pynithy/build/trustedzone/src/etny_exec.py +56 -0
  140. package/pynithy/build/trustedzone/src/formatter.py +42 -0
  141. package/pynithy/build/trustedzone/src/image_registry.abi +1 -0
  142. package/pynithy/build/trustedzone/src/key_generation.py +17 -0
  143. package/pynithy/build/trustedzone/src/models.py +176 -0
  144. package/pynithy/build/trustedzone/src/pox.abi +1489 -0
  145. package/pynithy/build/trustedzone/src/swift_stream_service.py +186 -0
  146. package/pynithy/build/trustedzone/src/trustedzone.py.tmpl +460 -0
  147. package/pynithy/build.mjs +179 -0
  148. package/pynithy/docker-compose.yml +0 -0
  149. package/pynithy/ipfs.mjs +244 -0
  150. package/pynithy/public/favicon.ico +0 -0
  151. package/pynithy/public/index.html +43 -0
  152. package/pynithy/public/logo192.png +0 -0
  153. package/pynithy/public/logo512.png +0 -0
  154. package/pynithy/public/manifest.json +25 -0
  155. package/pynithy/public/robots.txt +3 -0
  156. package/pynithy/run/certs/cert.pem +31 -0
  157. package/pynithy/run/certs/challenge.crt +10 -0
  158. package/pynithy/run/certs/key.pem +52 -0
  159. package/pynithy/run/docker-compose-final.yml +59 -0
  160. package/pynithy/run/docker-compose-final.yml.tmpl +59 -0
  161. package/pynithy/run/docker-compose-swift-stream.yml +27 -0
  162. package/pynithy/run/docker-compose-swift-stream.yml.tmpl +27 -0
  163. package/pynithy/run/docker-compose.yml +55 -0
  164. package/pynithy/run/docker-compose.yml.tmpl +55 -0
  165. package/pynithy/run/etny-pynity-test.yaml.tpl +46 -0
  166. package/pynithy/run/etny-securelock-test.yaml.tpl +46 -0
  167. package/pynithy/run/etny-trustedzone-test.yaml.tpl +46 -0
  168. package/pynithy/run/git.sh +22 -0
  169. package/pynithy/run/image_registry.abi +1 -0
  170. package/pynithy/run/image_registry.js +372 -0
  171. package/pynithy/run/image_registry.py +139 -0
  172. package/pynithy/run/image_registry_runner.py +45 -0
  173. package/pynithy/run/ipfs.sh +89 -0
  174. package/pynithy/run/public_key_service.js +90 -0
  175. package/pynithy/run/swiftstream.py +28 -0
  176. package/pynithy/run.js +538 -0
  177. package/pynithy/src/App.css +57 -0
  178. package/pynithy/src/ec_helloworld_example.js +64 -0
  179. package/pynithy/src/index.css +13 -0
  180. package/pynithy/src/index.js +17 -0
  181. package/pynithy/src/preStart.mjs +57 -0
  182. package/pynithy/src/reportWebVitals.js +13 -0
  183. package/pynithy/src/serverless/__init__.py +0 -0
  184. package/pynithy/src/serverless/backend.py +2 -0
@@ -0,0 +1,186 @@
1
+ import os
2
+
3
+ from minio import Minio
4
+ from minio.error import S3Error
5
+
6
+
7
+ class SwiftStreamService:
8
+
9
+ def __init__(self, endpoint: str, access_key: str, secret_key: str):
10
+ self.client = Minio(endpoint=endpoint,
11
+ access_key=access_key,
12
+ secret_key=secret_key,
13
+ secure=False)
14
+
15
+ def create_bucket(self, bucket_name: str) -> (bool, str):
16
+ try:
17
+ if not self.client.bucket_exists(bucket_name):
18
+ self.client.make_bucket(bucket_name)
19
+ else:
20
+ return False, f"Bucket, {bucket_name} already exists!"
21
+ except S3Error as err:
22
+ return False, err
23
+
24
+ return True, f"Bucket, {bucket_name} successfully created!"
25
+
26
+ def delete_bucket(self, bucket_name: str) -> (bool, str):
27
+ try:
28
+ if self.client.bucket_exists(bucket_name):
29
+ file_objects = self.client.list_objects(bucket_name)
30
+ if file_objects.size() == 0:
31
+ self.client.remove_bucket(bucket_name)
32
+ else:
33
+ for file_object in file_objects:
34
+ self.delete_file(bucket_name, file_object)
35
+ self.client.remove_bucket(bucket_name)
36
+ else:
37
+ return False, f"Bucket, {bucket_name} does not exists!"
38
+ except S3Error as err:
39
+ return False, err
40
+
41
+ return True, f"Bucket, {bucket_name} successfully deleted!"
42
+
43
+ def delete_file(self, bucket_name: str, file_name: str) -> (bool, str):
44
+ try:
45
+ self.client.remove_object(bucket_name, file_name)
46
+ except S3Error as err:
47
+ return False, err
48
+
49
+ return True, f"File, {file_name} successfully deleted!"
50
+
51
+ def delete_files(self, bucket_name: str, list_of_files: list[str]) -> (bool, str):
52
+ try:
53
+ errors = self.client.remove_objects(bucket_name, list_of_files)
54
+ for error in errors:
55
+ print(f"[Error] Error occurred when deleting file: {error}!")
56
+ except S3Error as err:
57
+ return False, err
58
+
59
+ return True, f"Files, {list_of_files} successfully deleted!"
60
+
61
+ def upload_file(self, bucket_name: str, file_name: str, file_path: str) -> (bool, str):
62
+ try:
63
+ if self.client.bucket_exists(bucket_name):
64
+ self.client.fput_object(bucket_name, file_name, file_path)
65
+ else:
66
+ self.create_bucket(bucket_name)
67
+ self.client.fput_object(bucket_name, file_name, file_path)
68
+ except S3Error as err:
69
+ return False, err
70
+
71
+ return True, f"{file_path} is successfully uploaded to bucket {bucket_name}."
72
+
73
+ def upload_files(self, bucket_name: str, list_of_files: list[str],
74
+ upload_file_paths: list[str]) -> (bool, str):
75
+ try:
76
+ if self.client.bucket_exists(bucket_name):
77
+ for file_idx in range(len(upload_file_paths)):
78
+ self.client.fput_object(bucket_name,
79
+ list_of_files[file_idx],
80
+ upload_file_paths[file_idx])
81
+ else:
82
+ self.create_bucket(bucket_name)
83
+ for file_idx in range(len(upload_file_paths)):
84
+ self.client.fput_object(bucket_name,
85
+ list_of_files[file_idx],
86
+ upload_file_paths[file_idx])
87
+ except S3Error as err:
88
+ return False, err
89
+
90
+ return True, f"{upload_file_paths} are successfully uploaded to bucket {bucket_name}."
91
+
92
+ def download_file(self, bucket_name: str, file_name: str, file_path: str) -> (bool, str):
93
+ try:
94
+ if self.client.bucket_exists(bucket_name):
95
+ self.client.fget_object(bucket_name, file_name, file_path)
96
+ else:
97
+ return False, f"Bucket, {bucket_name} does not exists!"
98
+ except S3Error as err:
99
+ return False, err
100
+
101
+ return True, f"File, {file_name} from bucket {bucket_name} was downloaded in {file_path}."
102
+
103
+ def download_files(self, bucket_name: str, list_of_files: list[str],
104
+ download_file_paths: list[str]) -> (bool, str):
105
+ try:
106
+ if self.client.bucket_exists(bucket_name):
107
+ for file_idx in range(len(list_of_files)):
108
+ self.client.fget_object(bucket_name,
109
+ list_of_files[file_idx],
110
+ download_file_paths[file_idx])
111
+ else:
112
+ return False, f"Bucket, {bucket_name} does not exists!"
113
+ except S3Error as err:
114
+ return False, err
115
+
116
+ return True, f"{download_file_paths} are successfully uploaded to bucket {bucket_name}."
117
+
118
+ def get_file_content_bytes(self, bucket_name: str, file_name: str) -> (bool, bytes):
119
+ response = None
120
+ try:
121
+ response = self.client.get_object(bucket_name, file_name)
122
+ _d = b''
123
+ for data in response.stream(amt=1024 * 1024):
124
+ _d = _d + data
125
+
126
+ except S3Error as err:
127
+ return False, err
128
+ finally:
129
+ if response is not None:
130
+ response.close()
131
+ response.release_conn()
132
+ return True, _d
133
+
134
+ def get_file_content(self, bucket_name: str, file_name: str) -> (bool, str):
135
+ status, content = self.get_file_content_bytes(bucket_name, file_name)
136
+ if status:
137
+ return True, content.decode('utf-8')
138
+ return status, content
139
+
140
+ def put_file_content(self, bucket_name: str, object_name: str, object_path: str,
141
+ object_data: object = None) -> (bool, str):
142
+ try:
143
+ if object_data is not None:
144
+ self.client.put_object(bucket_name,
145
+ object_name,
146
+ object_data,
147
+ len(object_data.getbuffer()))
148
+ else:
149
+ object_stat = os.stat(object_path)
150
+ with open(object_path, 'rb') as file_data:
151
+ self.client.put_object(bucket_name,
152
+ object_name,
153
+ file_data,
154
+ object_stat.st_size)
155
+ file_data.close()
156
+ except S3Error as err:
157
+ return False, err
158
+
159
+ return True, f"{object_name} is successfully uploaded to bucket {bucket_name}."
160
+
161
+ def is_object_in_bucket(self, bucket_name: str, object_name: str) -> (bool, str):
162
+ found = False
163
+ try:
164
+ result = self.client.stat_object(bucket_name, object_name)
165
+ if result:
166
+ found = True
167
+ except S3Error as err:
168
+ return False, err
169
+
170
+ if found:
171
+ return found, f"{object_name} exists inside {bucket_name}."
172
+ else:
173
+ return found, f"{object_name} doesn't exists inside {bucket_name}."
174
+
175
+ def _list_buckets(self) -> None:
176
+ buckets = self.client.list_buckets()
177
+ for bucket in buckets:
178
+ print(bucket.name, bucket.creation_date)
179
+
180
+ def _list_objects(self, bucket_name: str) -> None:
181
+ objects = self.client.list_objects(bucket_name)
182
+ for obj in objects:
183
+ print("-> ", obj.object_name, obj.owner_name)
184
+
185
+ def _is_bucket(self, bucket_name: str) -> bool:
186
+ return self.client.bucket_exists(bucket_name)
@@ -0,0 +1,460 @@
1
+ #!/usr/bin/python
2
+
3
+ # update 29.12.2022
4
+ import binascii
5
+ import hashlib
6
+ import os
7
+ import re
8
+ import string
9
+ import random
10
+ import io
11
+ import time
12
+
13
+ from etny_crypto import etny_crypto as crypto
14
+ from web3 import Web3
15
+ from eth_account import Account
16
+ from web3.middleware import geth_poa_middleware
17
+ from key_generation import get_wallet_address
18
+ from etny_exec import execute_task, TaskStatus
19
+ from models import *
20
+ from swift_stream_service import SwiftStreamService
21
+ from eth_account.messages import defunct_hash_message
22
+
23
+
24
+ # todo: remove EtnyTrustedZone.debug
25
+ class EtnyTrustedZone:
26
+ debug = False
27
+ bucket_name = 'etny-pynithy-testnet-v3'
28
+ integration_bucket_name = 'etny-bucket-integration'
29
+
30
+ def __init__(self, swiftStreamClient):
31
+ self.swift_stream_service = swiftStreamClient
32
+ self.version = 'v3'
33
+ print(f'ETNY Pynithy [{self.version}]')
34
+ self.__set_initializers()
35
+ self.save_pub_cert()
36
+ self.__load_env()
37
+ self.read_contract_abi()
38
+ self.init_web3()
39
+ if self.run_integration_test == 1:
40
+ self.run_integration_tests()
41
+ print('Integration tests finished. exiting...')
42
+ exit(0)
43
+ self.read_client_challenge()
44
+ self.generate_challenge()
45
+ self.generate_eth_compatible_wallet()
46
+ #print('wallet = ', self.publickey)
47
+ # print('private = ', self.privatekey)
48
+
49
+ self.print_env()
50
+ # if not EtnyTrustedZone.debug:
51
+ # self.reset_cert_file()
52
+
53
+ @staticmethod
54
+ def read_env(env_file):
55
+ with open(env_file, 'r') as f:
56
+ # Read each line of the file
57
+ for line in f:
58
+ # Split the line at the first '=' character
59
+ key, value = line.split('=', 1)
60
+ # Set the environment variable
61
+ os.environ[key] = value
62
+
63
+ @staticmethod
64
+ def read_env_str(env_str):
65
+ with io.StringIO(env_str) as f:
66
+ # Read each line of the string
67
+ for line in f:
68
+ # Split the line at the first '=' character
69
+ key, value = line.split('=', 1)
70
+ # Set the environment variable and remove new line
71
+ os.environ[key] = re.sub(r'\n', '', value)
72
+
73
+ def __set_initializers(self):
74
+ self.is_valid_client_data = True
75
+ self.key_file = "/private/__ENCLAVE_NAME_TRUSTEDZONE__/key.pem"
76
+ self.cert_file = "/app/__ENCLAVE_NAME_TRUSTEDZONE__/cert.pem"
77
+ self.pub_cert_file = "/app/__ENCLAVE_NAME_TRUSTEDZONE__/app.pem"
78
+ self.payload = 'payload.etny'
79
+ self.input = 'input.txt'
80
+ self.result_file = '/app/result.txt'
81
+ self.transaction_file = '/app/transaction.txt'
82
+ self.smart_contract_address = '0x02882F03097fE8cD31afbdFbB5D72a498B41112c'
83
+ self.image_registry_address = '0x15D73a742529C3fb11f3FA32EF7f0CC3870ACA31'
84
+ self.chain_id = 8995
85
+ self.web3_provider = 'https://bloxberg.ethernity.cloud'
86
+ self.etny_bucket = EtnyTrustedZone.bucket_name
87
+ self.secure_lock_public_key = ''
88
+ if EtnyTrustedZone.debug:
89
+ self.key_file = "./app/cert1-ca1-clean.key"
90
+ self.cert_file = "./app/cert1-ca1-clean.crt"
91
+ self.payload = 'payload.py'
92
+ self.input = 'input.txt'
93
+ self.result_file = './app/result.txt'
94
+ self.transaction_file = './app/transaction.txt'
95
+ self.pub_cert_file = "./app/enclave_pub_cert.pem"
96
+ self.secure_lock_public_key = "./app/enclave_pub_cert.pem"
97
+
98
+ def __extract_signer(self, checksum, signature):
99
+ signer = self.w3.eth.account.recoverHash(defunct_hash_message(text=checksum), signature=signature)
100
+ return signer
101
+
102
+ def validate_client_payload(self, payload_data, input_data):
103
+ if self._metadata.payload_metadata_obj.checksum is not None:
104
+ #print('Computing payload checksum: ')
105
+ payload_checksum = self.compute_sha256_checksum(payload_data)
106
+ #print('payload checksum: ', payload_checksum)
107
+ # check the wallet address that signed payload checksum is the one from order metadata
108
+ payload_signer = self.__extract_signer(payload_checksum, self._metadata.payload_metadata_obj.checksum)
109
+ if payload_signer.lower() != self.order_metadata.do_owner.lower():
110
+ self.task_code = TaskStatus.PAYLOAD_CHECKSUM_ERROR
111
+ self.task_result = 'PAYLOAD CHECKSUM DOESN\'T MATCH'
112
+ self.is_valid_client_data = False
113
+ return
114
+
115
+ if self._metadata.input_metadata_obj.checksum is not None:
116
+ input_checksum = self.compute_sha256_checksum(input_data)
117
+ #print('input checksum: ', input_checksum)
118
+ # check the wallet address that signed input checksum is the one from order metadata
119
+ input_signer = self.__extract_signer(input_checksum, self._metadata.input_metadata_obj.checksum)
120
+ if input_signer.lower() != self.order_metadata.do_owner.lower():
121
+ self.task_code = TaskStatus.INPUT_CHECKSUM_ERROR
122
+ self.task_result = 'INPUT CHECKSUM DOESN\'T MATCH'
123
+ self.is_valid_client_data = False
124
+ return
125
+
126
+ def get_do_request_metadata(self):
127
+ order = Order(self.etny.caller()._getOrder(self.order_id), self.order_id)
128
+ #print('order', order)
129
+ self._metadata = DOReqMetadata(self.etny.caller()._getDORequestMetadata(order.do_req), order.do_req)
130
+ self.order_metadata = order
131
+ #print('metadata', self._metadata)
132
+
133
+ def compute_sha256_checksum(self, file_data):
134
+ if type(file_data) is str:
135
+ file_data = file_data.encode('utf-8')
136
+
137
+ return hashlib.sha256(file_data).hexdigest()
138
+
139
+ # h = hashlib.sha256()
140
+ # file = io.BytesIO(file_data)
141
+ # while True:
142
+ # Reading is buffered, so we can read smaller chunks.
143
+ # chunk = file.read(h.block_size)
144
+ # if not chunk:
145
+ # break
146
+ # h.update(chunk)
147
+ # return h.hexdigest()
148
+
149
+ def reset_cert_file(self):
150
+ #print('Resetting the cert file')
151
+ try:
152
+ with open(self.key_file, 'r+') as f:
153
+ f.truncate(0)
154
+ except Exception as e:
155
+ print('Error while removing the private key file content', e)
156
+
157
+ #with open(self.key_file, 'r') as f:
158
+ # print('cert file content', f.read(), '##################')
159
+
160
+ def generate_eth_compatible_wallet(self):
161
+ decrypted_string = crypto.decrypt(
162
+ private_key_file=self.key_file,
163
+ encrypted_msg=self.encrypted_tuple
164
+ )
165
+ #print('decrypted_string = ', decrypted_string)
166
+ (public, private) = get_wallet_address(decrypted_string.decode(), self.enclave_challenge)
167
+ self.publickey = public
168
+ self.privatekey = private
169
+ self.acct = Account.privateKeyToAccount(self.privatekey)
170
+
171
+ def print_env(self):
172
+ print('chain id:', self.chain_id)
173
+ print('smart contract address:', self.smart_contract_address)
174
+ print('web3 provider:', self.web3_provider)
175
+ print('encrypted challenge:', self.client_challenge)
176
+ print('order id:', self.order_id)
177
+
178
+ def init_web3(self):
179
+ self.w3 = Web3(Web3.HTTPProvider(self.web3_provider))
180
+ self.w3.middleware_onion.inject(geth_poa_middleware, layer=0)
181
+ self.etny = self.w3.eth.contract(address=self.w3.toChecksumAddress(self.smart_contract_address),
182
+ abi=self.contract_abi)
183
+ self.image_registry = self.w3.eth.contract(address=self.w3.toChecksumAddress(self.image_registry_address),
184
+ abi=self.image_registry_abi)
185
+
186
+ def read_contract_abi(self):
187
+ self.contract_abi = self.__read_contract_abi('pox.abi')
188
+ self.image_registry_abi = self.__read_contract_abi('image_registry.abi')
189
+
190
+ def __read_contract_abi(self, contract_name):
191
+ f = open(os.path.dirname(os.path.realpath(__file__)) + f'/{contract_name}')
192
+ contract_abi = f.read()
193
+ f.close()
194
+ return contract_abi
195
+
196
+ def __load_env(self):
197
+ if os.getenv('ETNY_CHAIN_ID') is not None:
198
+ self.chain_id = int(os.getenv('ETNY_CHAIN_ID'))
199
+
200
+ if os.getenv('ETNY_SMART_CONTRACT_ADDRESS') is not None:
201
+ self.smart_contract_address = os.getenv('ETNY_SMART_CONTRACT_ADDRESS').rstrip()
202
+
203
+ if os.getenv('ETNY_WEB3_PROVIDER') is not None:
204
+ self.web3_provider = os.getenv('ETNY_WEB3_PROVIDER').rstrip()
205
+
206
+ #print('ETNY_RUN_INTEGRATION_TEST', os.getenv('ETNY_RUN_INTEGRATION_TEST'));
207
+ if os.getenv('ETNY_RUN_INTEGRATION_TEST') is not None:
208
+ self.run_integration_test = int(os.getenv('ETNY_RUN_INTEGRATION_TEST'))
209
+ else:
210
+ self.run_integration_test = 0
211
+
212
+
213
+ self.client_challenge = os.getenv('ETNY_CLIENT_CHALLENGE')
214
+ self.order_id = int(os.getenv('ETNY_ORDER_ID'))
215
+
216
+ def read_client_challenge(self):
217
+ self.encrypted_tuple = crypto.encrypted_data_from_base64_json(self.client_challenge)
218
+
219
+ def generate_challenge(self, length=20):
220
+ lowercase_only = ''.join(
221
+ random.choice(string.ascii_lowercase) for _ in range(length)
222
+ )
223
+ #print('random challenge:', lowercase_only)
224
+ self.enclave_challenge = lowercase_only
225
+ return self.enclave_challenge
226
+
227
+ def build_result(self):
228
+ self.result = (f'{self.version}:{self.task_code}:{self.task_result_checksum}:{self.enclave_challenge}:')
229
+
230
+ def addResult(self):
231
+ self.build_result()
232
+ print(f'adding result to order {self.order_id}')
233
+ nonce = self.w3.eth.getTransactionCount(self.publickey)
234
+ unicorn_txn = self.etny.functions._addResultToOrder(
235
+ self.order_id, self.result
236
+ ).buildTransaction({
237
+ 'gas': 1000000,
238
+ 'chainId': self.chain_id,
239
+ 'nonce': nonce,
240
+ 'gasPrice': self.w3.toWei("1", "mwei"),
241
+ })
242
+
243
+ signed_txn = self.w3.eth.account.sign_transaction(unicorn_txn, private_key=self.acct.key)
244
+ self.w3.eth.sendRawTransaction(signed_txn.rawTransaction)
245
+ # self.transaction = unicorn_tx signed
246
+ hash = self.w3.toHex(self.w3.sha3(signed_txn.rawTransaction))
247
+
248
+ try:
249
+ receipt = self.w3.eth.waitForTransactionReceipt(hash)
250
+ except Exception as e:
251
+ print(f'An error occurred while sending transaction result {self.order_id}: ', e)
252
+ raise
253
+
254
+ #print('transaction status: ', receipt.status)
255
+ #print('transaction receipt: ', receipt)
256
+ if receipt.status == 1:
257
+ print("Result transaction was successful!")
258
+ else:
259
+ print("Result transaction was UNSUCCESSFUL!")
260
+
261
+ #print("Result payload: %s" % self.result)
262
+ #print("TX Raw: %s" % signed_txn.rawTransaction)
263
+ #print("TX Hash: %s" % hash)
264
+
265
+ def build_transaction(self):
266
+ self.build_result()
267
+ print(f'adding result to order {self.order_id}')
268
+ nonce = self.w3.eth.getTransactionCount(self.publickey)
269
+ unicorn_txn = self.etny.functions._addResultToOrder(
270
+ self.order_id, self.result
271
+ ).buildTransaction({
272
+ 'gas': 1000000,
273
+ 'chainId': self.chain_id,
274
+ 'nonce': nonce,
275
+ 'gasPrice': self.w3.toWei("1", "mwei"),
276
+ })
277
+
278
+ signed_txn = self.w3.eth.account.sign_transaction(unicorn_txn, private_key=self.acct.key)
279
+ signed_tx_as_bytes = binascii.hexlify(signed_txn.rawTransaction)
280
+ self.signed_tx_as_bytes = signed_tx_as_bytes
281
+
282
+ def get_result_checksum(self):
283
+ self.task_result_checksum = hashlib.sha256(self.task_result.encode("utf-8")).hexdigest()
284
+
285
+ def save_result(self):
286
+ self.swift_stream_service.create_bucket(self.etny_bucket)
287
+ print("Encrypting result with public key: %s" % self._metadata.public_key)
288
+ encrypted_result = crypto.encrypt_nacl(self._metadata.public_key, self.task_result.encode('utf-8'))
289
+ print("Result successfully encrypted!", encrypted_result)
290
+ data = io.BytesIO(encrypted_result.encode("utf-8"))
291
+ status, _ = self.swift_stream_service.put_file_content(self.etny_bucket,
292
+ "result.txt",
293
+ self.result_file,
294
+ data)
295
+ if status:
296
+ print('result saved to swift stream successfully')
297
+
298
+ def save_pub_cert(self):
299
+ self.swift_stream_service.create_bucket(self.etny_bucket)
300
+ self.swift_stream_service.put_file_content(self.etny_bucket,
301
+ "cert.pem",
302
+ self.cert_file)
303
+
304
+ def save_transaction(self):
305
+ self.swift_stream_service.create_bucket(self.etny_bucket)
306
+ transaction = io.BytesIO(self.signed_tx_as_bytes)
307
+ self.swift_stream_service.put_file_content(self.etny_bucket,
308
+ "transaction.txt",
309
+ self.transaction_file,
310
+ transaction)
311
+
312
+ def execute(self):
313
+ self.get_do_request_metadata()
314
+ self.prepare_context_for_secure_lock()
315
+ self.wait_for_task()
316
+ print('TASK RESULT (code, data):', self.task_code, self.task_result)
317
+
318
+ def encrypt_file_and_push_to_swifstream(self, payload_data, file_name):
319
+ # todo use the actual public key of the secure lock enclave
320
+ encrypted_input = crypto.encrypt_with_pub_key(self.secure_lock_public_key, payload_data.encode('utf-8'))
321
+ encrypted_input_base64 = crypto.encrypted_data_to_base64_json(encrypted_input)
322
+
323
+ # file name should end with secure lock '.securelock' extension
324
+ file_name = file_name + '.securelock'
325
+ self.swift_stream_service.create_bucket(self.etny_bucket)
326
+ data = io.BytesIO(encrypted_input_base64)
327
+ status, _ = self.swift_stream_service.put_file_content(self.etny_bucket,
328
+ file_name,
329
+ "",
330
+ data)
331
+ if status:
332
+ print(f'File {file_name} encrypted and saved to swift stream successfully')
333
+
334
+ def __check_is_empty_input(self):
335
+ empty_input_checksum = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
336
+ input_signer = self.__extract_signer(empty_input_checksum, self._metadata.input_metadata_obj.checksum)
337
+
338
+ if input_signer.lower() == self.order_metadata.do_owner.lower():
339
+ print('Input is empty')
340
+ return True
341
+ return False
342
+
343
+ def prepare_context_for_secure_lock(self):
344
+ self.__get_secure_lock_public_key()
345
+ payload_data = self.__get_file_content_and_decrypt('payload.etny')
346
+
347
+ is_empty_input = self.__check_is_empty_input()
348
+ input_data = self.__get_file_content_and_decrypt('input.txt', is_empty_input)
349
+
350
+ #print('Validate client payload and input')
351
+ self.validate_client_payload(payload_data, input_data)
352
+ if app.is_valid_client_data:
353
+ print('Client payload and input are valid')
354
+ else:
355
+ print('Client payload and input are NOT valid')
356
+ return
357
+
358
+ self.encrypt_file_and_push_to_swifstream(payload_data, self.payload)
359
+ self.encrypt_file_and_push_to_swifstream(input_data, self.input)
360
+
361
+ def wait_for_secure_lock(self, bucket_name, object_name, timeout=3600):
362
+ i = 0
363
+ print(f'Checking if object {object_name} exists in bucket {bucket_name}')
364
+ while True:
365
+ time.sleep(1)
366
+ i = i + 1
367
+ if i > timeout:
368
+ break
369
+ (status, result) = self.swift_stream_service.is_object_in_bucket(bucket_name, object_name)
370
+ if status:
371
+ break
372
+
373
+ print('secure lock finished the execution')
374
+
375
+ def __get_file_content_and_decrypt(self, object_name, is_empty=False):
376
+ status, encrypted_base64 = self.swift_stream_service.get_file_content(self.etny_bucket, object_name)
377
+ print(f'File {object_name} downloaded from swift stream successfully')
378
+ print(status, encrypted_base64)
379
+ #print('Decrypting the file with private key:')
380
+ if is_empty:
381
+ return encrypted_base64
382
+ encrypted_tuple = crypto.encrypted_data_from_base64_json(encrypted_base64.encode('utf-8'))
383
+ decrypted_result = crypto.decrypt(self.key_file, encrypted_tuple)
384
+ return decrypted_result.decode('utf-8')
385
+
386
+ def wait_for_task(self):
387
+ self.wait_for_secure_lock(self.etny_bucket, "result.txt.securelock")
388
+ self.task_result = self.__get_file_content_and_decrypt("result.txt.securelock")
389
+ self.task_code = self.__get_file_content_and_decrypt("result_code.txt.securelock")
390
+
391
+ def __get_secure_lock_public_key(self):
392
+ #print('getting the public key of the trusted zone enclave')
393
+ image_hash = self._metadata.image_hash
394
+ if EtnyTrustedZone.debug:
395
+ image_hash = 'v3-hash-1'
396
+ self.secure_lock_public_key = self.image_registry.caller().getImageCertPublicKey(
397
+ image_hash)
398
+ #print('public key of the securelock enclave:', self.secure_lock_public_key)
399
+
400
+ def run_integration_tests(self):
401
+ print('Running integration test')
402
+ file_name = "context_test" + '.etny'
403
+ self.swift_stream_service.create_bucket(self.etny_bucket)
404
+ block = self.w3.eth.block_number
405
+ data = io.BytesIO(b"Trusted zone status:success. Block number:" + str(block).encode('utf-8'))
406
+ status, _ = self.swift_stream_service.put_file_content(EtnyTrustedZone.integration_bucket_name,
407
+ file_name,
408
+ "",
409
+ data)
410
+ if status:
411
+ print(f'File {file_name} saved to swift stream successfully')
412
+
413
+ print('Running integration test finished successfully')
414
+
415
+
416
+ if __name__ == '__main__':
417
+ print('[TrustedZone]Loading env variables..')
418
+ try:
419
+ if EtnyTrustedZone.debug:
420
+ swiftStreamClient = SwiftStreamService("localhost:9000",
421
+ "swiftstreamadmin",
422
+ "swiftstreamadmin")
423
+ else:
424
+ swiftStreamClient = SwiftStreamService("etny-swift-stream:9000",
425
+ "swiftstreamadmin",
426
+ "swiftstreamadmin")
427
+
428
+ status, env_content_integration_test = swiftStreamClient.get_file_content(
429
+ EtnyTrustedZone.integration_bucket_name, ".env")
430
+ if status:
431
+ EtnyTrustedZone.read_env_str(env_content_integration_test)
432
+ print("Integration test env loaded")
433
+ else:
434
+ status, env_content = swiftStreamClient.get_file_content(EtnyTrustedZone.bucket_name, ".env")
435
+ if not status:
436
+ print("Failed to get .env file")
437
+ raise Exception("Failed to get .env file")
438
+ EtnyTrustedZone.read_env_str(env_content)
439
+ except Exception as e:
440
+ cert_file = "/app/__ENCLAVE_NAME_TRUSTEDZONE__/cert.pem"
441
+ with open(cert_file, 'r') as f:
442
+ print("PUBLIC_CERT:", f.read())
443
+ exit(1)
444
+
445
+ if not EtnyTrustedZone.debug:
446
+ with open("/app/__ENCLAVE_NAME_TRUSTEDZONE__/cert.pem", 'r') as f:
447
+ print("PUBLIC_CERT:", f.read())
448
+
449
+ print('Initializing..')
450
+ app = EtnyTrustedZone(swiftStreamClient)
451
+ app.execute()
452
+ print('Generating task result checksum..')
453
+ app.get_result_checksum()
454
+ print('Building transaction..')
455
+ app.build_transaction()
456
+ print('Saving transaction...')
457
+ app.save_transaction()
458
+ print('Saving the result..')
459
+ app.save_result()
460
+ print('Finished the execution')