@arbitrum/nitro-contracts 1.0.0-beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. package/.prettierrc +5 -0
  2. package/.solhint.json +18 -0
  3. package/deploy/BridgeStubCreator.js +10 -0
  4. package/deploy/HashProofHelper.js +13 -0
  5. package/deploy/InboxStubCreator.js +17 -0
  6. package/deploy/OneStepProofEntryCreator.js +19 -0
  7. package/deploy/OneStepProver0Creator.js +14 -0
  8. package/deploy/OneStepProverHostIoCreator.js +14 -0
  9. package/deploy/OneStepProverMathCreator.js +14 -0
  10. package/deploy/OneStepProverMemoryCreator.js +14 -0
  11. package/deploy/SequencerInboxStubCreator.js +13 -0
  12. package/deploy/ValueArrayTesterCreator.js +13 -0
  13. package/hardhat.config.ts +47 -0
  14. package/hardhat.prod-config.js +18 -0
  15. package/package.json +49 -0
  16. package/scripts/build.bash +5 -0
  17. package/src/bridge/Bridge.sol +168 -0
  18. package/src/bridge/IBridge.sol +68 -0
  19. package/src/bridge/IInbox.sol +80 -0
  20. package/src/bridge/IMessageProvider.sol +11 -0
  21. package/src/bridge/IOutbox.sol +52 -0
  22. package/src/bridge/ISequencerInbox.sol +85 -0
  23. package/src/bridge/Inbox.sol +414 -0
  24. package/src/bridge/Messages.sol +38 -0
  25. package/src/bridge/Outbox.sol +188 -0
  26. package/src/bridge/SequencerInbox.sol +274 -0
  27. package/src/challenge/ChallengeLib.sol +135 -0
  28. package/src/challenge/ChallengeManager.sol +367 -0
  29. package/src/challenge/IChallengeManager.sol +75 -0
  30. package/src/challenge/IChallengeResultReceiver.sol +13 -0
  31. package/src/libraries/AddressAliasHelper.sol +29 -0
  32. package/src/libraries/AdminFallbackProxy.sol +153 -0
  33. package/src/libraries/ArbitrumProxy.sol +20 -0
  34. package/src/libraries/Constants.sol +10 -0
  35. package/src/libraries/CryptographyPrimitives.sol +323 -0
  36. package/src/libraries/DelegateCallAware.sol +44 -0
  37. package/src/libraries/Error.sol +38 -0
  38. package/src/libraries/IGasRefunder.sol +35 -0
  39. package/src/libraries/MerkleLib.sol +46 -0
  40. package/src/libraries/MessageTypes.sol +14 -0
  41. package/src/libraries/SecondaryLogicUUPSUpgradeable.sol +58 -0
  42. package/src/libraries/UUPSNotUpgradeable.sol +56 -0
  43. package/src/mocks/BridgeStub.sol +115 -0
  44. package/src/mocks/Counter.sol +13 -0
  45. package/src/mocks/ExecutionManager.sol +41 -0
  46. package/src/mocks/InboxStub.sol +131 -0
  47. package/src/mocks/MockResultReceiver.sol +59 -0
  48. package/src/mocks/SequencerInboxStub.sol +42 -0
  49. package/src/mocks/SimpleProxy.sol +19 -0
  50. package/src/node-interface/NodeInterface.sol +50 -0
  51. package/src/osp/HashProofHelper.sol +154 -0
  52. package/src/osp/IOneStepProofEntry.sol +20 -0
  53. package/src/osp/IOneStepProver.sol +27 -0
  54. package/src/osp/OneStepProofEntry.sol +129 -0
  55. package/src/osp/OneStepProver0.sol +566 -0
  56. package/src/osp/OneStepProverHostIo.sol +357 -0
  57. package/src/osp/OneStepProverMath.sol +514 -0
  58. package/src/osp/OneStepProverMemory.sol +313 -0
  59. package/src/precompiles/ArbAddressTable.sol +60 -0
  60. package/src/precompiles/ArbAggregator.sol +62 -0
  61. package/src/precompiles/ArbBLS.sol +53 -0
  62. package/src/precompiles/ArbDebug.sol +39 -0
  63. package/src/precompiles/ArbFunctionTable.sol +29 -0
  64. package/src/precompiles/ArbGasInfo.sol +121 -0
  65. package/src/precompiles/ArbInfo.sol +15 -0
  66. package/src/precompiles/ArbOwner.sol +65 -0
  67. package/src/precompiles/ArbOwnerPublic.sol +18 -0
  68. package/src/precompiles/ArbRetryableTx.sol +89 -0
  69. package/src/precompiles/ArbStatistics.sol +29 -0
  70. package/src/precompiles/ArbSys.sol +134 -0
  71. package/src/precompiles/ArbosActs.sol +41 -0
  72. package/src/precompiles/ArbosTest.sol +14 -0
  73. package/src/rollup/BridgeCreator.sol +120 -0
  74. package/src/rollup/IRollupCore.sol +152 -0
  75. package/src/rollup/IRollupLogic.sol +183 -0
  76. package/src/rollup/Node.sol +99 -0
  77. package/src/rollup/RollupAdminLogic.sol +322 -0
  78. package/src/rollup/RollupCore.sol +627 -0
  79. package/src/rollup/RollupCreator.sol +133 -0
  80. package/src/rollup/RollupEventBridge.sol +46 -0
  81. package/src/rollup/RollupLib.sol +135 -0
  82. package/src/rollup/RollupUserLogic.sol +712 -0
  83. package/src/rollup/ValidatorUtils.sol +243 -0
  84. package/src/rollup/ValidatorWallet.sol +76 -0
  85. package/src/rollup/ValidatorWalletCreator.sol +43 -0
  86. package/src/state/Deserialize.sol +321 -0
  87. package/src/state/GlobalState.sol +44 -0
  88. package/src/state/Instructions.sol +159 -0
  89. package/src/state/Machine.sol +65 -0
  90. package/src/state/MerkleProof.sol +99 -0
  91. package/src/state/Module.sol +33 -0
  92. package/src/state/ModuleMemory.sol +42 -0
  93. package/src/state/PcArray.sol +45 -0
  94. package/src/state/PcStack.sol +32 -0
  95. package/src/state/StackFrame.sol +63 -0
  96. package/src/state/Value.sol +65 -0
  97. package/src/state/ValueArray.sol +47 -0
  98. package/src/state/ValueStack.sol +39 -0
  99. package/src/test-helpers/CryptographyPrimitivesTester.sol +27 -0
  100. package/src/test-helpers/MessageTester.sol +34 -0
  101. package/src/test-helpers/ValueArrayTester.sol +34 -0
  102. package/test/contract/arbRollup.spec.ts +869 -0
  103. package/test/contract/common/challengeLib.ts +43 -0
  104. package/test/contract/common/globalStateLib.ts +17 -0
  105. package/test/contract/common/rolluplib.ts +259 -0
  106. package/test/contract/cryptographyPrimitives.spec.ts +82 -0
  107. package/test/contract/sequencerInboxForceInclude.spec.ts +516 -0
  108. package/test/contract/utils.ts +40 -0
  109. package/test/prover/hash-proofs.ts +75 -0
  110. package/test/prover/one-step-proof.ts +93 -0
  111. package/test/prover/proofs/.gitkeep +0 -0
  112. package/test/prover/value-arrays.ts +11 -0
  113. package/tsconfig.json +13 -0
@@ -0,0 +1,43 @@
1
+ import { BigNumber } from '@ethersproject/bignumber'
2
+ import { solidityKeccak256 } from 'ethers/lib/utils'
3
+
4
+ export enum MachineStatus {
5
+ RUNNING = 0,
6
+ FINISHED = 1,
7
+ ERRORED = 2,
8
+ TOO_FAR = 3,
9
+ }
10
+
11
+ export function hashChallengeState(
12
+ segmentsStart: BigNumber,
13
+ segmentsLength: BigNumber,
14
+ segments: string[],
15
+ ) {
16
+ return solidityKeccak256(
17
+ ['uint256', 'uint256', 'bytes32[]'],
18
+ [segmentsStart, segmentsLength, segments],
19
+ )
20
+ }
21
+
22
+ export function blockStateHash(
23
+ machineStatus: BigNumber,
24
+ globalStateHash: string,
25
+ ) {
26
+ const machineStatusNum = machineStatus.toNumber()
27
+ if (machineStatusNum === MachineStatus.FINISHED) {
28
+ return solidityKeccak256(
29
+ ['string', 'bytes32'],
30
+ ['Block state:', globalStateHash],
31
+ )
32
+ } else if (machineStatusNum === MachineStatus.ERRORED) {
33
+ return solidityKeccak256(
34
+ ['string', 'bytes32'],
35
+ ['Block state, errored:', globalStateHash],
36
+ )
37
+ } else if (machineStatusNum === MachineStatus.TOO_FAR) {
38
+ return solidityKeccak256(['string', 'bytes32'], ['Block state, too far:'])
39
+ } else {
40
+ console.log(machineStatus.toNumber())
41
+ throw new Error('BAD_BLOCK_STATUS')
42
+ }
43
+ }
@@ -0,0 +1,17 @@
1
+ import {
2
+ GlobalStateStruct,
3
+ } from '../../../build/types/RollupUserLogic'
4
+ import { solidityKeccak256 } from 'ethers/lib/utils'
5
+
6
+ export function hash(state: GlobalStateStruct) {
7
+ return solidityKeccak256(
8
+ ['string', 'bytes32', 'bytes32', 'uint64', 'uint64'],
9
+ [
10
+ 'Global state:',
11
+ state.bytes32Vals[0],
12
+ state.bytes32Vals[1],
13
+ state.u64Vals[0],
14
+ state.u64Vals[1],
15
+ ],
16
+ )
17
+ }
@@ -0,0 +1,259 @@
1
+ import { ethers } from "hardhat";
2
+ import { Interface, LogDescription } from "@ethersproject/abi";
3
+ import { Signer } from "@ethersproject/abstract-signer";
4
+ import { BigNumberish, BigNumber } from "@ethersproject/bignumber";
5
+ import { BytesLike } from "@ethersproject/bytes";
6
+ import { ContractTransaction, PayableOverrides } from "@ethersproject/contracts";
7
+ import { Provider } from "@ethersproject/providers";
8
+ import { RollupUserLogic, RollupAdminLogic, SequencerInbox } from "../../../build/types";
9
+ import {
10
+ RollupLib,
11
+ NodeCreatedEvent,
12
+ } from "../../../build/types/RollupUserLogic";
13
+ type AssertionStruct = RollupLib.AssertionStruct;
14
+ type ExecutionStateStruct = RollupLib.ExecutionStateStruct;
15
+ import { blockStateHash, hashChallengeState } from "./challengeLib";
16
+ import * as globalStateLib from "./globalStateLib";
17
+ import { constants } from "ethers";
18
+ import { GlobalStateStruct } from "../../../build/types/ChallengeManager";
19
+
20
+ export interface Node {
21
+ nodeNum: number;
22
+ proposedBlock: number;
23
+ assertion: AssertionStruct;
24
+ inboxMaxCount: BigNumber;
25
+ nodeHash: BytesLike;
26
+ wasmModuleRoot: BytesLike;
27
+ }
28
+
29
+ export function nodeHash(
30
+ hasSibling: boolean,
31
+ lastHash: BytesLike,
32
+ assertionExecHash: BytesLike,
33
+ inboxAcc: BytesLike
34
+ ): BytesLike {
35
+ return ethers.utils.solidityKeccak256(
36
+ ["bool", "bytes32", "bytes32", "bytes32"],
37
+ [hasSibling, lastHash, assertionExecHash, inboxAcc]
38
+ );
39
+ }
40
+
41
+ const globalStateEquals = (globalState1: GlobalStateStruct, globalState2: GlobalStateStruct) => {
42
+ return (
43
+ globalState1.bytes32Vals[0] === globalState2.bytes32Vals[0] &&
44
+ globalState1.bytes32Vals[1] === globalState2.bytes32Vals[1] &&
45
+ BigNumber.from(globalState1.u64Vals[0]).eq(globalState2.u64Vals[0]) &&
46
+ BigNumber.from(globalState1.u64Vals[1]).eq(globalState2.u64Vals[1])
47
+ );
48
+ };
49
+
50
+ export const executionStateEquals = (
51
+ executionState1: ExecutionStateStruct,
52
+ executionState2: ExecutionStateStruct
53
+ ) => {
54
+ return (
55
+ globalStateEquals(executionState1.globalState, executionState2.globalState) &&
56
+ BigNumber.from(executionState1.machineStatus).eq(executionState2.machineStatus)
57
+ );
58
+ };
59
+
60
+ export const assertionEquals = (assertion1: AssertionStruct, assertion2: AssertionStruct) => {
61
+ return (
62
+ executionStateEquals(assertion1.beforeState, assertion2.beforeState) &&
63
+ executionStateEquals(assertion1.afterState, assertion2.afterState) &&
64
+ BigNumber.from(assertion1.numBlocks).eq(assertion2.numBlocks)
65
+ );
66
+ };
67
+
68
+ export function executionStateHash(e: ExecutionStateStruct, inboxMaxCount: BigNumberish) {
69
+ return ethers.utils.solidityKeccak256(
70
+ ["bytes32", "uint256", "uint8"],
71
+ [globalStateLib.hash(e.globalState), inboxMaxCount, e.machineStatus]
72
+ );
73
+ }
74
+
75
+ export function executionStructHash(e: ExecutionStateStruct) {
76
+ return ethers.utils.solidityKeccak256(
77
+ ["bytes32", "uint8"],
78
+ [globalStateLib.hash(e.globalState), e.machineStatus]
79
+ );
80
+ }
81
+
82
+ export function assertionExecutionHash(a: AssertionStruct): BytesLike {
83
+ const seg0 = blockStateHash(
84
+ BigNumber.from(a.beforeState.machineStatus),
85
+ globalStateLib.hash(a.beforeState.globalState)
86
+ );
87
+ const seg1 = blockStateHash(
88
+ BigNumber.from(a.afterState.machineStatus),
89
+ globalStateLib.hash(a.afterState.globalState)
90
+ );
91
+ return hashChallengeState(BigNumber.from(0), BigNumber.from(a.numBlocks), [seg0, seg1]);
92
+ }
93
+
94
+ async function nodeFromNodeCreatedLog(blockNumber: number, log: LogDescription): Promise<Node> {
95
+ if (log.name != "NodeCreated") {
96
+ throw Error("wrong event type");
97
+ }
98
+ const parsedEv = log.args as NodeCreatedEvent["args"];
99
+
100
+ const node: Node = {
101
+ assertion: parsedEv.assertion,
102
+ nodeHash: parsedEv.nodeHash,
103
+ wasmModuleRoot: parsedEv.wasmModuleRoot,
104
+ nodeNum: parsedEv.nodeNum.toNumber(),
105
+ proposedBlock: blockNumber,
106
+ inboxMaxCount: parsedEv.inboxMaxCount,
107
+ };
108
+ return node;
109
+ }
110
+
111
+ async function nodeFromTx(abi: Interface, tx: ContractTransaction): Promise<Node> {
112
+ const receipt = await tx.wait();
113
+ if (receipt.logs == undefined) {
114
+ throw Error("expected receipt to have logs");
115
+ }
116
+ const evs = receipt.logs
117
+ .map((log) => {
118
+ try {
119
+ return abi.parseLog(log);
120
+ } catch (e) {
121
+ return undefined;
122
+ }
123
+ })
124
+ .filter((ev) => ev && ev.name == "NodeCreated");
125
+ if (evs.length != 1) {
126
+ throw Error("unique event not found");
127
+ }
128
+
129
+ return nodeFromNodeCreatedLog(receipt.blockNumber, evs[0]!);
130
+ }
131
+
132
+ export class RollupContract {
133
+ constructor(public rollup: RollupUserLogic) {}
134
+
135
+ connect(signerOrProvider: Signer | Provider | string): RollupContract {
136
+ return new RollupContract(this.rollup.connect(signerOrProvider));
137
+ }
138
+
139
+ async stakeOnNewNode(
140
+ sequencerInbox: SequencerInbox,
141
+ parentNode: {
142
+ nodeHash: BytesLike;
143
+ inboxMaxCount: BigNumber;
144
+ },
145
+ assertion: AssertionStruct,
146
+ siblingNode?: Node,
147
+ stakeToAdd?: BigNumber
148
+ ): Promise<{
149
+ tx: ContractTransaction;
150
+ node: Node;
151
+ expectedNewNodeHash: BytesLike;
152
+ }> {
153
+ const inboxPosition = BigNumber.from(assertion.afterState.globalState.u64Vals[0]).toNumber();
154
+ const afterInboxAcc =
155
+ inboxPosition > 0 ? await sequencerInbox.inboxAccs(inboxPosition - 1) : constants.HashZero;
156
+ const newNodeHash = nodeHash(
157
+ !!siblingNode,
158
+ (siblingNode || parentNode).nodeHash,
159
+ assertionExecutionHash(assertion),
160
+ afterInboxAcc
161
+ );
162
+ const tx = stakeToAdd
163
+ ? await this.rollup.newStakeOnNewNode(assertion, newNodeHash, parentNode.inboxMaxCount, {
164
+ value: stakeToAdd,
165
+ })
166
+ : await this.rollup.stakeOnNewNode(assertion, newNodeHash, parentNode.inboxMaxCount);
167
+ const node = await nodeFromTx(this.rollup.interface, tx);
168
+ return { tx, node, expectedNewNodeHash: newNodeHash };
169
+ }
170
+
171
+ stakeOnExistingNode(nodeNum: BigNumberish, nodeHash: BytesLike): Promise<ContractTransaction> {
172
+ return this.rollup.stakeOnExistingNode(nodeNum, nodeHash);
173
+ }
174
+
175
+ confirmNextNode(
176
+ node: Node,
177
+ ): Promise<ContractTransaction> {
178
+ return this.rollup.confirmNextNode(
179
+ node.assertion.afterState.globalState.bytes32Vals[0],
180
+ node.assertion.afterState.globalState.bytes32Vals[1]
181
+ );
182
+ }
183
+
184
+ rejectNextNode(stakerAddress: string): Promise<ContractTransaction> {
185
+ return this.rollup.rejectNextNode(stakerAddress);
186
+ }
187
+
188
+ async createChallenge(
189
+ staker1Address: string,
190
+ staker2Address: string,
191
+ node1: Node,
192
+ node2: Node
193
+ ): Promise<ContractTransaction> {
194
+ return this.rollup.createChallenge(
195
+ [staker1Address, staker2Address],
196
+ [node1.nodeNum, node2.nodeNum],
197
+ [node1.assertion.beforeState.machineStatus, node1.assertion.afterState.machineStatus],
198
+ [node1.assertion.beforeState.globalState, node1.assertion.afterState.globalState],
199
+ node1.assertion.numBlocks,
200
+ assertionExecutionHash(node2.assertion),
201
+ [node1.proposedBlock, node2.proposedBlock],
202
+ [node1.wasmModuleRoot, node2.wasmModuleRoot]
203
+ );
204
+ }
205
+
206
+ addToDeposit(staker: string, overrides: PayableOverrides = {}): Promise<ContractTransaction> {
207
+ return this.rollup.addToDeposit(staker, overrides);
208
+ }
209
+
210
+ reduceDeposit(amount: BigNumberish): Promise<ContractTransaction> {
211
+ return this.rollup.reduceDeposit(amount);
212
+ }
213
+
214
+ returnOldDeposit(stakerAddress: string): Promise<ContractTransaction> {
215
+ return this.rollup.returnOldDeposit(stakerAddress);
216
+ }
217
+
218
+ latestConfirmed(): Promise<BigNumber> {
219
+ return this.rollup.latestConfirmed();
220
+ }
221
+
222
+ getNodeStateHash(index: BigNumberish): Promise<string> {
223
+ return this.rollup.getNode(index).then((n) => n.stateHash);
224
+ }
225
+
226
+ latestStakedNode(staker: string): Promise<BigNumber> {
227
+ return this.rollup.latestStakedNode(staker);
228
+ }
229
+
230
+ currentRequiredStake(): Promise<BigNumber> {
231
+ return this.rollup.currentRequiredStake();
232
+ }
233
+ }
234
+
235
+ export async function forceCreateNode(
236
+ rollupAdmin: RollupAdminLogic,
237
+ sequencerInbox: SequencerInbox,
238
+ parentNode: Node,
239
+ assertion: AssertionStruct,
240
+ siblingNode?: Node
241
+ ): Promise<{ tx: ContractTransaction; node: Node }> {
242
+ const inboxPosition = BigNumber.from(assertion.afterState.globalState.u64Vals[0]).toNumber();
243
+ const afterInboxAcc =
244
+ inboxPosition > 0 ? await sequencerInbox.inboxAccs(inboxPosition - 1) : constants.HashZero;
245
+ const newNodeHash = nodeHash(
246
+ !!siblingNode,
247
+ (siblingNode || parentNode).nodeHash,
248
+ assertionExecutionHash(assertion),
249
+ afterInboxAcc
250
+ );
251
+ const tx = await rollupAdmin.forceCreateNode(
252
+ parentNode.nodeNum,
253
+ parentNode.inboxMaxCount,
254
+ assertion,
255
+ newNodeHash
256
+ );
257
+ const node = await nodeFromTx(rollupAdmin.interface, tx);
258
+ return { tx, node };
259
+ }
@@ -0,0 +1,82 @@
1
+ /*
2
+ * Copyright 2020, Offchain Labs, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ /* eslint-env node, mocha */
18
+
19
+ import { ethers } from 'hardhat'
20
+ import { BytesLike } from '@ethersproject/bytes'
21
+ import { expect } from 'chai'
22
+ import { CryptographyPrimitivesTester } from '../../build/types'
23
+
24
+ let cryptographyPrimitivesTester: CryptographyPrimitivesTester
25
+
26
+ describe('CryptographyPrimitives', () => {
27
+ before(async () => {
28
+ const CryptographyPrimitivesTester = await ethers.getContractFactory(
29
+ 'CryptographyPrimitivesTester'
30
+ )
31
+ cryptographyPrimitivesTester = (await CryptographyPrimitivesTester.deploy()) as CryptographyPrimitivesTester
32
+ await cryptographyPrimitivesTester.deployed()
33
+ })
34
+
35
+ it('calculates sha256 compression function correctly', async () => {
36
+ // test vectors from https://homes.esat.kuleuven.be/~nsmart/MPC/sha-256-test.txt
37
+
38
+ const initialHashState =
39
+ '0x6a09e667bb67ae853c6ef372a54ff53a510e527f9b05688c1f83d9ab5be0cd19'
40
+
41
+ const input1: [BytesLike, BytesLike] = [
42
+ ethers.constants.HashZero,
43
+ ethers.constants.HashZero,
44
+ ]
45
+
46
+ const input2: [BytesLike, BytesLike] = [
47
+ '0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f',
48
+ '0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f',
49
+ ]
50
+
51
+ const input3: [BytesLike, BytesLike] = [
52
+ '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',
53
+ '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',
54
+ ]
55
+
56
+ const input4: [BytesLike, BytesLike] = [
57
+ '0x243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89',
58
+ '0x452821E638D01377BE5466CF34E90C6CC0AC29B7C97C50DD3f84D5B5b5470917',
59
+ ]
60
+
61
+ const output1 =
62
+ '0xda5698be17b9b46962335799779fbeca8ce5d491c0d26243bafef9ea1837a9d8'
63
+ const output2 =
64
+ '0xfc99a2df88f42a7a7bb9d18033cdc6a20256755f9d5b9a5044a9cc315abe84a7'
65
+ const output3 =
66
+ '0xef0c748df4da50a8d6c43c013edc3ce76c9d9fa9a1458ade56eb86c0a64492d2'
67
+ const output4 =
68
+ '0xcf0ae4eb67d38ffeb94068984b22abde4e92bc548d14585e48dca8882d7b09ce'
69
+ expect(
70
+ await cryptographyPrimitivesTester.sha256Block(input1, initialHashState)
71
+ ).to.equal(output1)
72
+ expect(
73
+ await cryptographyPrimitivesTester.sha256Block(input2, initialHashState)
74
+ ).to.equal(output2)
75
+ expect(
76
+ await cryptographyPrimitivesTester.sha256Block(input3, initialHashState)
77
+ ).to.equal(output3)
78
+ expect(
79
+ await cryptographyPrimitivesTester.sha256Block(input4, initialHashState)
80
+ ).to.equal(output4)
81
+ })
82
+ })