Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
2fa4d36b
Unverified
Commit
2fa4d36b
authored
Apr 19, 2023
by
OptimismBot
Committed by
GitHub
Apr 19, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5459 from ethereum-optimism/sc/prove-fix-test
sdk: fix withdrawal bug
parents
e66312f9
2e4c17c0
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
263 additions
and
27 deletions
+263
-27
config.yml
.circleci/config.yml
+53
-0
package.json
packages/sdk/package.json
+4
-1
cross-chain-messenger.ts
packages/sdk/src/cross-chain-messenger.ts
+29
-24
message-utils.ts
packages/sdk/src/utils/message-utils.ts
+17
-1
README.md
packages/sdk/test-next/README.md
+4
-0
proveMessage.spec.ts
packages/sdk/test-next/proveMessage.spec.ts
+108
-0
message-utils.spec.ts
packages/sdk/test/utils/message-utils.spec.ts
+48
-1
No files found.
.circleci/config.yml
View file @
2fa4d36b
...
...
@@ -535,6 +535,55 @@ jobs:
name
:
Upload coverage
command
:
codecov --verbose --clean --flags <<parameters.coverage_flag>>
sdk-next-tests
:
docker
:
-
image
:
ethereumoptimism/ci-builder:latest
resource_class
:
large
steps
:
-
checkout
-
attach_workspace
:
{
at
:
"
."
}
-
check-changed
:
patterns
:
sdk,contracts-bedrock,contracts
-
restore_cache
:
name
:
Restore Yarn Package Cache
keys
:
-
yarn-packages-v2-{{ checksum "yarn.lock" }}
-
run
:
name
:
anvil-l1
background
:
true
# atm this is goerli but we should use mainnet after bedrock is live
command
:
anvil --fork-url $ANVIL_L1_FORK_URL --fork-block-number
8847426
-
run
:
name
:
anvil-l2
background
:
true
# atm this is goerli but we should use mainnet after bedrock is live
command
:
anvil --fork-url $ANVIL_L2_FORK_URL --port 9545 --fork-block-number
8172732
-
run
:
name
:
build
command
:
yarn build
working_directory
:
packages/atst
-
run
:
name
:
lint
command
:
yarn lint:check
working_directory
:
packages/atst
-
run
:
name
:
make sure anvil l1 is up
command
:
npx wait-on tcp:8545 && cast block-number --rpc-url http://localhost:8545
-
run
:
name
:
make sure anvil l2 is up
command
:
npx wait-on tcp:9545 && cast block-number --rpc-url http://localhost:9545
-
run
:
name
:
test:next
command
:
yarn test:next
no_output_timeout
:
5m
working_directory
:
packages/sdk
environment
:
# anvil[0] test private key
VITE_E2E_PRIVATE_KEY
:
"
0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
VITE_E2E_RPC_URL_L1
:
http://localhost:8545
VITE_E2E_RPC_URL_L2
:
http://localhost:9545
bedrock-markdown
:
machine
:
image
:
ubuntu-2204:2022.07.1
...
...
@@ -1094,6 +1143,10 @@ workflows:
dependencies
:
"
(common-ts|core-utils)"
requires
:
-
yarn-monorepo
-
sdk-next-tests
:
name
:
sdk-next-tests
requires
:
-
yarn-monorepo
-
js-lint-test
:
name
:
sdk-tests
coverage_flag
:
sdk-tests
...
...
packages/sdk/package.json
View file @
2fa4d36b
...
...
@@ -17,6 +17,7 @@
"lint:fix"
:
"yarn lint:check --fix"
,
"pre-commit"
:
"lint-staged"
,
"test"
:
"hardhat test"
,
"test:next"
:
"vitest test-next/proveMessage.spec.ts"
,
"test:coverage"
:
"nyc hardhat test && nyc merge .nyc_output coverage.json"
,
"autogen:docs"
:
"typedoc --out docs src/index.ts"
},
...
...
@@ -45,7 +46,9 @@
"hardhat-deploy"
:
"^0.11.4"
,
"nyc"
:
"^15.1.0"
,
"typedoc"
:
"^0.22.13"
,
"mocha"
:
"^10.0.0"
"mocha"
:
"^10.0.0"
,
"vitest"
:
"^0.28.3"
,
"zod"
:
"^3.11.6"
},
"dependencies"
:
{
"@eth-optimism/contracts"
:
"0.5.40"
,
...
...
packages/sdk/src/cross-chain-messenger.ts
View file @
2fa4d36b
...
...
@@ -68,6 +68,7 @@ import {
migratedWithdrawalGasLimit
,
DEPOSIT_CONFIRMATION_BLOCKS
,
CHAIN_BLOCK_TIMES
,
hashMessageHash
,
}
from
'
./utils
'
export
class
CrossChainMessenger
{
...
...
@@ -351,14 +352,12 @@ export class CrossChainMessenger {
}
}
const
minGasLimit
=
migratedWithdrawalGasLimit
(
resolved
.
message
)
return
{
...
resolved
,
value
,
minGasLimit
,
minGasLimit
:
BigNumber
.
from
(
0
)
,
messageNonce
:
encodeVersionedNonce
(
BigNumber
.
from
(
1
),
BigNumber
.
from
(
0
),
resolved
.
messageNonce
),
}
...
...
@@ -388,13 +387,23 @@ export class CrossChainMessenger {
updated
=
resolved
}
// Encode the updated message, we need this for legacy messages.
const
encoded
=
encodeCrossDomainMessageV1
(
updated
.
messageNonce
,
updated
.
sender
,
updated
.
target
,
updated
.
value
,
updated
.
minGasLimit
,
updated
.
message
)
// We need to figure out the final withdrawal data that was used to compute the withdrawal hash
// inside the L2ToL1Message passer contract. Exact mechanism here depends on whether or not
// this is a legacy message or a new Bedrock message.
let
gasLimit
:
BigNumber
let
messageNonce
:
BigNumber
if
(
version
.
eq
(
0
))
{
gasLimit
=
BigNumber
.
from
(
0
)
gasLimit
=
migratedWithdrawalGasLimit
(
encoded
)
messageNonce
=
resolved
.
messageNonce
}
else
{
const
receipt
=
await
this
.
l2Provider
.
getTransactionReceipt
(
...
...
@@ -433,14 +442,7 @@ export class CrossChainMessenger {
target
:
this
.
contracts
.
l1
.
L1CrossDomainMessenger
.
address
,
value
:
updated
.
value
,
minGasLimit
:
gasLimit
,
message
:
encodeCrossDomainMessageV1
(
updated
.
messageNonce
,
updated
.
sender
,
updated
.
target
,
updated
.
value
,
updated
.
minGasLimit
,
updated
.
message
),
message
:
encoded
,
}
}
...
...
@@ -572,6 +574,9 @@ export class CrossChainMessenger {
public
async
toCrossChainMessage
(
message
:
MessageLike
):
Promise
<
CrossChainMessage
>
{
if
(
!
message
)
{
throw
new
Error
(
'
message is undefined
'
)
}
// TODO: Convert these checks into proper type checks.
if
((
message
as
CrossChainMessage
).
message
)
{
return
message
as
CrossChainMessage
...
...
@@ -1357,12 +1362,8 @@ export class CrossChainMessenger {
}
const
withdrawal
=
await
this
.
toLowLevelMessage
(
resolved
)
const
messageSlot
=
ethers
.
utils
.
keccak256
(
ethers
.
utils
.
defaultAbiCoder
.
encode
(
[
'
bytes32
'
,
'
uint256
'
],
[
hashLowLevelMessage
(
withdrawal
),
ethers
.
constants
.
HashZero
]
)
)
const
hash
=
hashLowLevelMessage
(
withdrawal
)
const
messageSlot
=
hashMessageHash
(
hash
)
const
stateTrieProof
=
await
makeStateTrieProof
(
this
.
l2Provider
as
ethers
.
providers
.
JsonRpcProvider
,
...
...
@@ -1462,9 +1463,8 @@ export class CrossChainMessenger {
overrides
?:
Overrides
}
):
Promise
<
TransactionResponse
>
{
return
(
opts
?.
signer
||
this
.
l1Signer
).
sendTransaction
(
await
this
.
populateTransaction
.
proveMessage
(
message
,
opts
)
)
const
tx
=
await
this
.
populateTransaction
.
proveMessage
(
message
,
opts
)
return
(
opts
?.
signer
||
this
.
l1Signer
).
sendTransaction
(
tx
)
}
/**
...
...
@@ -1768,7 +1768,8 @@ export class CrossChainMessenger {
const
withdrawal
=
await
this
.
toLowLevelMessage
(
resolved
)
const
proof
=
await
this
.
getBedrockMessageProof
(
resolved
)
return
this
.
contracts
.
l1
.
OptimismPortal
.
populateTransaction
.
proveWithdrawalTransaction
(
const
args
=
[
[
withdrawal
.
messageNonce
,
withdrawal
.
sender
,
...
...
@@ -1785,7 +1786,11 @@ export class CrossChainMessenger {
proof
.
outputRootProof
.
latestBlockhash
,
],
proof
.
withdrawalProof
,
opts
?.
overrides
||
{}
opts
?.
overrides
||
{},
]
as
const
return
this
.
contracts
.
l1
.
OptimismPortal
.
populateTransaction
.
proveWithdrawalTransaction
(
...
args
)
},
...
...
packages/sdk/src/utils/message-utils.ts
View file @
2fa4d36b
import
{
hashWithdrawal
}
from
'
@eth-optimism/core-utils
'
import
{
BigNumber
,
utils
}
from
'
ethers
'
import
{
BigNumber
,
utils
,
ethers
}
from
'
ethers
'
import
{
LowLevelMessage
}
from
'
../interfaces
'
...
...
@@ -22,6 +22,22 @@ export const hashLowLevelMessage = (message: LowLevelMessage): string => {
)
}
/**
* Utility for hashing a message hash. This computes the storage slot
* where the message hash will be stored in state. HashZero is used
* because the first mapping in the contract is used.
*
* @param messageHash Message hash to hash.
* @returns Hash of the given message hash.
*/
export
const
hashMessageHash
=
(
messageHash
:
string
):
string
=>
{
const
data
=
ethers
.
utils
.
defaultAbiCoder
.
encode
(
[
'
bytes32
'
,
'
uint256
'
],
[
messageHash
,
ethers
.
constants
.
HashZero
]
)
return
ethers
.
utils
.
keccak256
(
data
)
}
/**
* Compute the min gas limit for a migrated withdrawal.
*/
...
...
packages/sdk/test-next/README.md
0 → 100644
View file @
2fa4d36b
# test-next
-
The new tests for the next version of sdk will use vitest
-
The vitest tests are kept here seperated from mocha tests for now
packages/sdk/test-next/proveMessage.spec.ts
0 → 100644
View file @
2fa4d36b
import
ethers
from
'
ethers
'
import
{
describe
,
expect
,
it
}
from
'
vitest
'
import
{
z
}
from
'
zod
'
import
{
CrossChainMessenger
}
from
'
../src
'
/**
* This test repros the bug where legacy withdrawals are not provable
*/
/*******
Cast results from runnning cast tx and cast receipt on the l2 tx hash
cast tx 0xd66fda632b51a8b25a9d260d70da8be57b9930c4616370861526335c3e8eef81 --rpc-url https://goerli.optimism.io
blockHash 0x67956cee3de38d49206d34b77f560c4c371d77b36584047ade8bf7b67bf210c0
blockNumber 2337599
from 0x1d86C2F5cc7fBEc35FEDbd3293b5004A841EA3F0
gas 118190
gasPrice 1
hash 0xd66fda632b51a8b25a9d260d70da8be57b9930c4616370861526335c3e8eef81
input 0x32b7006d000000000000000000000000deaddeaddeaddeaddeaddeaddeaddeaddead000000000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000
nonce 10
r 0x7e58c5dbb37f57303d936562d89a75a20be2a45f54c5d44dc73119453adf2e08
s 0x1bc952bd048dd38668a0c3b4bac202945c5a150465b551dd2a768e54a746e2c4
to 0x4200000000000000000000000000000000000010
transactionIndex 0
v 875
value 0
index 2337598
l1BlockNumber 7850866
l1Timestamp 1666982083
queueOrigin sequencer
rawTransaction 0xf901070a018301cdae94420000000000000000000000000000000000001080b8a432b7006d000000000000000000000000deaddeaddeaddeaddeaddeaddeaddeaddead000000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000082036ba07e58c5dbb37f57303d936562d89a75a20be2a45f54c5d44dc73119453adf2e08a01bc952bd048dd38668a0c3b4bac202945c5a150465b551dd2a768e54a746e2c4
cast tx 0xd66fda632b51a8b25a9d260d70da8be57b9930c4616370861526335c3e8eef81 --rpc-url https://goerli.optimism.io
blockHash 0x67956cee3de38d49206d34b77f560c4c371d77b36584047ade8bf7b67bf210c0
blockNumber 2337599
contractAddress
cumulativeGasUsed 115390
effectiveGasPrice
gasUsed 115390
logs [{"address":"0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000001d86c2f5cc7fbec35fedbd3293b5004a841ea3f0","0x0000000000000000000000000000000000000000000000000000000000000000"],"data":"0x00000000000000000000000000000000000000000000000000005af3107a4000","blockHash":"0x67956cee3de38d49206d34b77f560c4c371d77b36584047ade8bf7b67bf210c0","blockNumber":"0x23ab3f","transactionHash":"0xd66fda632b51a8b25a9d260d70da8be57b9930c4616370861526335c3e8eef81","transactionIndex":"0x0","logIndex":"0x0","removed":false},{"address":"0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000","topics":["0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5","0x0000000000000000000000001d86c2f5cc7fbec35fedbd3293b5004a841ea3f0"],"data":"0x00000000000000000000000000000000000000000000000000005af3107a4000","blockHash":"0x67956cee3de38d49206d34b77f560c4c371d77b36584047ade8bf7b67bf210c0","blockNumber":"0x23ab3f","transactionHash":"0xd66fda632b51a8b25a9d260d70da8be57b9930c4616370861526335c3e8eef81","transactionIndex":"0x0","logIndex":"0x1","removed":false},{"address":"0x4200000000000000000000000000000000000007","topics":["0xcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a","0x000000000000000000000000636af16bf2f682dd3109e60102b8e1a089fedaa8"],"data":"0x00000000000000000000000042000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000001a048000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a41532ec340000000000000000000000001d86c2f5cc7fbec35fedbd3293b5004a841ea3f00000000000000000000000001d86c2f5cc7fbec35fedbd3293b5004a841ea3f000000000000000000000000000000000000000000000000000005af3107a40000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","blockHash":"0x67956cee3de38d49206d34b77f560c4c371d77b36584047ade8bf7b67bf210c0","blockNumber":"0x23ab3f","transactionHash":"0xd66fda632b51a8b25a9d260d70da8be57b9930c4616370861526335c3e8eef81","transactionIndex":"0x0","logIndex":"0x2","removed":false},{"address":"0x4200000000000000000000000000000000000010","topics":["0x73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000deaddeaddeaddeaddeaddeaddeaddeaddead0000","0x0000000000000000000000001d86c2f5cc7fbec35fedbd3293b5004a841ea3f0"],"data":"0x0000000000000000000000001d86c2f5cc7fbec35fedbd3293b5004a841ea3f000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000","blockHash":"0x67956cee3de38d49206d34b77f560c4c371d77b36584047ade8bf7b67bf210c0","blockNumber":"0x23ab3f","transactionHash":"0xd66fda632b51a8b25a9d260d70da8be57b9930c4616370861526335c3e8eef81","transactionIndex":"0x0","logIndex":"0x3","removed":false}]
logsBloom 0x00000000000000000010000000000000000000000000001000100000001000000000000000000080000000000000008000000800000000000000000000000240000000002000400040000008000000000000000000000000000000000000000100000000020000000000000000000800080000000040000000000010000000000000000000000000000000000000000000800000000000000020000000200000000000000000000001000000000000000000200000000000000000000000000000000002000000200000000400000000000002100000000000000000000020001000000000000000000000000000000000000000000000000000010000008000
root
status 1
transactionHash 0xd66fda632b51a8b25a9d260d70da8be57b9930c4616370861526335c3e8eef81
transactionIndex 0
type
*/
const
E2E_RPC_URL_L1
=
z
.
string
()
.
url
()
.
describe
(
'
L1 ethereum rpc Url
'
)
.
parse
(
import
.
meta
.
env
.
VITE_E2E_RPC_URL_L1
)
const
E2E_RPC_URL_L2
=
z
.
string
()
.
url
()
.
describe
(
'
L1 ethereum rpc Url
'
)
.
parse
(
import
.
meta
.
env
.
VITE_E2E_RPC_URL_L2
)
const
E2E_PRIVATE_KEY
=
z
.
string
()
.
describe
(
'
Private key
'
)
.
parse
(
import
.
meta
.
env
.
VITE_E2E_PRIVATE_KEY
)
const
jsonRpcHeaders
=
{
'
User-Agent
'
:
'
eth-optimism/@gateway/backend
'
}
/**
* Initialize the signer, prover, and cross chain messenger
*/
const
l1Provider
=
new
ethers
.
providers
.
JsonRpcProvider
({
url
:
E2E_RPC_URL_L1
,
headers
:
jsonRpcHeaders
,
})
const
l2Provider
=
new
ethers
.
providers
.
JsonRpcProvider
({
url
:
E2E_RPC_URL_L2
,
headers
:
jsonRpcHeaders
,
})
const
l1Wallet
=
new
ethers
.
Wallet
(
E2E_PRIVATE_KEY
,
l1Provider
)
const
crossChainMessenger
=
new
CrossChainMessenger
({
l1SignerOrProvider
:
l1Wallet
,
l2SignerOrProvider
:
l2Provider
,
l1ChainId
:
5
,
l2ChainId
:
420
,
bedrock
:
true
,
})
describe
(
'
prove message
'
,
()
=>
{
it
(
`should prove a legacy tx
`
,
async
()
=>
{
/**
* Tx hash of legacy withdrawal
*
* @see https://goerli-optimism.etherscan.io/tx/0xd66fda632b51a8b25a9d260d70da8be57b9930c4616370861526335c3e8eef81
*/
const
txWithdrawalHash
=
'
0xd66fda632b51a8b25a9d260d70da8be57b9930c4616370861526335c3e8eef81
'
const
txReceipt
=
await
l2Provider
.
getTransactionReceipt
(
txWithdrawalHash
)
expect
(
txReceipt
).
toBeDefined
()
const
tx
=
await
crossChainMessenger
.
proveMessage
(
txWithdrawalHash
)
const
receipt
=
await
tx
.
wait
()
// A 1 means the transaction was successful
expect
(
receipt
.
status
).
toBe
(
1
)
},
20
_000
)
})
packages/sdk/test/utils/message-utils.spec.ts
View file @
2fa4d36b
import
{
BigNumber
}
from
'
ethers
'
import
{
expect
}
from
'
../setup
'
import
{
migratedWithdrawalGasLimit
}
from
'
../../src/utils/message-utils
'
import
{
migratedWithdrawalGasLimit
,
hashLowLevelMessage
,
hashMessageHash
,
}
from
'
../../src/utils/message-utils
'
describe
(
'
Message Utils
'
,
()
=>
{
describe
(
'
migratedWithdrawalGasLimit
'
,
()
=>
{
...
...
@@ -26,4 +30,47 @@ describe('Message Utils', () => {
}
})
})
/**
* Test that storage slot computation is correct. The test vectors are
* from actual migrated withdrawals on goerli.
*/
describe
(
'
Withdrawal Hashing
'
,
()
=>
{
it
(
'
should work
'
,
()
=>
{
const
tests
=
[
{
input
:
{
messageNonce
:
BigNumber
.
from
(
100000
),
sender
:
'
0x4200000000000000000000000000000000000007
'
,
target
:
'
0x5086d1eEF304eb5284A0f6720f79403b4e9bE294
'
,
value
:
BigNumber
.
from
(
0
),
minGasLimit
:
BigNumber
.
from
(
207744
),
message
:
'
0xd764ad0b00000000000000000000000000000000000000000000000000000000000186a00000000000000000000000004200000000000000000000000000000000000010000000000000000000000000636af16bf2f682dd3109e60102b8e1a089fedaa80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e4a9f9e67500000000000000000000000007865c6e87b9f70255377e024ace6630c1eaa37f0000000000000000000000003b8e53b3ab8e01fb57d0c9e893bc4d655aa67d84000000000000000000000000b91882244f7f82540f2941a759724523c7b9a166000000000000000000000000b91882244f7f82540f2941a759724523c7b9a166000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
'
,
},
result
:
'
0x7c83d39edf60c0ab61bc7cfd2e5f741efdf02fd6e2da0f12318f0d1858d3773b
'
,
},
{
input
:
{
messageNonce
:
BigNumber
.
from
(
100001
),
sender
:
'
0x4200000000000000000000000000000000000007
'
,
target
:
'
0x5086d1eEF304eb5284A0f6720f79403b4e9bE294
'
,
value
:
BigNumber
.
from
(
0
),
minGasLimit
:
BigNumber
.
from
(
207744
),
message
:
'
0xd764ad0b00000000000000000000000000000000000000000000000000000000000186a10000000000000000000000004200000000000000000000000000000000000010000000000000000000000000636af16bf2f682dd3109e60102b8e1a089fedaa80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e4a9f9e67500000000000000000000000007865c6e87b9f70255377e024ace6630c1eaa37f0000000000000000000000004e62882864fb8ce54affcaf8d899a286762b011b000000000000000000000000b91882244f7f82540f2941a759724523c7b9a166000000000000000000000000b91882244f7f82540f2941a759724523c7b9a166000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
'
,
},
result
:
'
0x17c90d87508a23d806962f4c5f366ef505e8d80e5cc2a5c87242560c21d7c588
'
,
},
]
for
(
const
test
of
tests
)
{
const
hash
=
hashLowLevelMessage
(
test
.
input
)
const
messageSlot
=
hashMessageHash
(
hash
)
expect
(
messageSlot
).
to
.
eq
(
test
.
result
)
}
})
})
})
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment