This repository has been archived by the owner on Oct 14, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Starknetv0.11 Ready for review #21
Merged
Merged
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
a8c077a
poseidon test
FawadHa1der 9a6ec46
initial migration to use the new commitment scheme
FawadHa1der 812f5db
update the abis and move to new deployed l1resolver/verifier contract
FawadHa1der fdc9ece
unit test updates
FawadHa1der c1eca9c
deploying poseidon only for local deployment
FawadHa1der 5a98fb6
update core contract root used for testing
FawadHa1der 75a7139
move the gateway abi interface to l1resolver filde
FawadHa1der f39e618
remove docker compose file
FawadHa1der 21a40b0
update the test work area
FawadHa1der e2b70e9
update the abis
FawadHa1der 79157f6
readme update
FawadHa1der 6a29cf1
upgrading l2resolver from cairo0 to cairo1
FawadHa1der 68c55e6
readme update
FawadHa1der 2ed31fd
move StarknetCoreContractStub.sol to mocks folder
FawadHa1der 772fa14
move StarknetCoreContractStub.sol to mocks folder
FawadHa1der 48e462d
performance improvment for poseidon array, calldata to memory functio…
FawadHa1der e68f642
Add more comments to make explicit the puprose of the starknetcoercon…
FawadHa1der 1135443
adding more poseidon array tests
FawadHa1der 855a361
adding goerli deployment constants
FawadHa1der 2a66654
readme updates with links to etherscan and voyager
FawadHa1der 4502104
updated deployment address for new verifier/resolver on goerli
FawadHa1der d2bf5f0
updated deployment address for new verifier/resolver on goerli
FawadHa1der f58aa9f
update the new abis
FawadHa1der File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,16 +42,17 @@ struct StarknetProof { | |
// includes contract proof and state/storage proof for a partciular starknet block | ||
struct StarknetCompositeStateProof { | ||
int256 blockNumber; | ||
uint256 classCommitment; | ||
ContractData contractData; | ||
StarknetProof[] contractProofArray; | ||
StarknetProof[] storageProofArray; | ||
} | ||
|
||
interface IStarknetResolverService { | ||
function addr(bytes32 node) | ||
external | ||
view | ||
returns (StarknetCompositeStateProof memory proof); | ||
interface PoseidonHash3 { | ||
// this is the hades permutation function. TODO update the name when goerli eth is not so expensive | ||
function poseidon( | ||
uint256[3] memory input | ||
) external view returns (uint256[3] memory); | ||
} | ||
|
||
// Starknet Core Contract Minimal Interface | ||
|
@@ -76,7 +77,10 @@ contract SNStateProofVerifier is | |
{ | ||
uint256 private constant BIG_PRIME = | ||
3618502788666131213697322783095070105623107215331596699973092056135872020481; | ||
uint256 private constant FELT_FOR_STARKNET_STATE_V0 = | ||
28355430774503553497671514844211693180464; // short_str_to_felt for "STARKNET_STATE_V0" | ||
PedersenHash public pedersen; | ||
PoseidonHash3 public poseidon; | ||
StarknetCoreContract public starknetCoreContract; | ||
|
||
/// @custom:oz-upgrades-unsafe-allow constructor | ||
|
@@ -86,28 +90,25 @@ contract SNStateProofVerifier is | |
|
||
function initialize( | ||
address pedersenAddress, | ||
address poseidonAddress, | ||
address _starknetCoreContractAddress | ||
) public initializer { | ||
pedersen = PedersenHash(pedersenAddress); | ||
poseidon = PoseidonHash3(poseidonAddress); | ||
starknetCoreContract = StarknetCoreContract( | ||
_starknetCoreContractAddress | ||
); | ||
__Ownable_init(); | ||
__UUPSUpgradeable_init(); | ||
} | ||
|
||
function _authorizeUpgrade(address newImplementation) | ||
internal | ||
virtual | ||
override | ||
onlyOwner | ||
{} | ||
|
||
function hashForSingleProofNode(StarknetProof memory proof) | ||
private | ||
view | ||
returns (uint256) | ||
{ | ||
function _authorizeUpgrade( | ||
address newImplementation | ||
) internal virtual override onlyOwner {} | ||
|
||
function hashForSingleProofNode( | ||
StarknetProof memory proof | ||
) private view returns (uint256) { | ||
uint256 hashvalue = 0; | ||
if (proof.nodeType == NodeType.BINARY) { | ||
hashvalue = hash( | ||
|
@@ -123,6 +124,27 @@ contract SNStateProofVerifier is | |
return hashvalue; | ||
} | ||
|
||
// based on https://docs.starknet.io/documentation/architecture_and_concepts/Hashing/hash-functions/ | ||
function poseidonHashMany( | ||
uint256[] memory elems | ||
) public view returns (uint256) { | ||
uint256[3] memory state = [uint256(0), uint256(0), uint256(0)]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe I'm missing something, but I feel that the code here never updates There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh, it's probably updated by the function There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes that is correct |
||
|
||
for (uint256 i = 0; i < (elems.length - 1); i += 2) { | ||
state[0] = (state[0] + elems[i]) % BIG_PRIME; | ||
state[1] = (state[1] + elems[i + 1]) % BIG_PRIME; | ||
state = poseidon.poseidon(state); | ||
} | ||
|
||
uint256 rem = elems.length % 2; | ||
if (rem == 1) { | ||
state[0] = (state[0] + elems[elems.length - 1]) % BIG_PRIME; | ||
} | ||
state[rem] = (state[rem] + (1)) % BIG_PRIME; | ||
|
||
return poseidon.poseidon(state)[0]; | ||
} | ||
|
||
// this functions connects the contract state root with value of leaf node in the contract proof. | ||
// state_hash = H(H(H(class_hash, contract_root), contract_nonce), RESERVED) | ||
function stateHash( | ||
|
@@ -147,11 +169,10 @@ contract SNStateProofVerifier is | |
return hashes[0]; | ||
} | ||
|
||
function convertToBytes(uint256 x, uint256 y) | ||
private | ||
pure | ||
returns (bytes memory) | ||
{ | ||
function convertToBytes( | ||
uint256 x, | ||
uint256 y | ||
) private pure returns (bytes memory) { | ||
bytes memory b = new bytes(64); | ||
assembly { | ||
mstore(add(b, 32), x) | ||
|
@@ -168,6 +189,7 @@ contract SNStateProofVerifier is | |
// Only supports verifiying a proof for a single storage variable value. | ||
function verifiedStorageValue( | ||
int256 blockNumber, | ||
uint256 classCommitment, | ||
ContractData calldata contractData, | ||
StarknetProof[] calldata contractProofArray, | ||
StarknetProof[] calldata storageProofArray | ||
|
@@ -208,24 +230,23 @@ contract SNStateProofVerifier is | |
contractData.hashVersion | ||
); | ||
|
||
uint256 storageVarValue = verifyProof( | ||
uint256 storageVarValue = verifyStorageProof( | ||
contractData.contractStateRoot, | ||
contractData.storageVarAddress, | ||
storageProofArray | ||
); | ||
|
||
// the contract proof has to be verified against the state root committed on L1 in the Starknet Core Contract | ||
uint256 stateRootCoreHash = starknetCoreContract.stateRoot(); | ||
|
||
require( | ||
_stateHash != 0, | ||
"stateroot hash is not fetched properly! revert" | ||
); | ||
|
||
// the contract proof has to be verified against the state root committed on L1 in the Starknet Core Contract | ||
uint256 expectedStateHash = verifyProof( | ||
stateRootCoreHash, | ||
starknetCoreContract.stateRoot(), | ||
contractData.contractAddress, | ||
contractProofArray | ||
contractProofArray, | ||
classCommitment | ||
); | ||
|
||
require( | ||
|
@@ -248,19 +269,47 @@ contract SNStateProofVerifier is | |
return aExtracted == b; | ||
} | ||
|
||
// A generic method to verify a proof against a root hash and a path. | ||
function verifyProof( | ||
// overloaded/wrapper function around verifyProof, used to verify storage proof array where the class commitment does not apply | ||
function verifyStorageProof( | ||
uint256 rootHash, | ||
uint256 path, | ||
StarknetProof[] calldata proofArray | ||
) public view returns (uint256 value) { | ||
uint256 expectedHash = rootHash; | ||
int256 pathBitIndex = 250; // start from the MSB bit index | ||
// classCommitment is 0 means we are verifying storage proof array | ||
return verifyProof(rootHash, path, proofArray, 0); | ||
} | ||
|
||
// A generic method to verify a proof against a root hash and a path. | ||
function verifyProof( | ||
uint256 rootHash, | ||
uint256 path, | ||
StarknetProof[] calldata proofArray, | ||
uint256 classCommitment // 0 means no class commitment | ||
) public view returns (uint256 value) { | ||
require( | ||
proofArray.length > 0, | ||
"proof array must have atleast one element." | ||
); | ||
uint256 expectedHash = rootHash; | ||
int256 pathBitIndex = 250; // start from the MSB bit index | ||
if (classCommitment > 0) { | ||
// https://docs.starknet.io/documentation/architecture_and_concepts/State/starknet-state/ | ||
uint256 calculatedContractStateRoot = hashForSingleProofNode( | ||
proofArray[0] | ||
); // the hash of first element in the proof array is the contract state root | ||
uint256[] memory poseidonInput = new uint256[](3); | ||
poseidonInput[0] = FELT_FOR_STARKNET_STATE_V0; | ||
poseidonInput[1] = calculatedContractStateRoot; | ||
poseidonInput[2] = classCommitment; | ||
|
||
uint256 calculateStateCommitment = poseidonHashMany(poseidonInput); | ||
require( | ||
calculateStateCommitment == expectedHash, | ||
"calculated state commitment doesn't match with the expected state commitment!" | ||
); | ||
// since we have already verified the first element in the proof array correctly hashes up to the state commitment, we can assume the hash of first element in the proof array is correct. | ||
expectedHash = calculatedContractStateRoot; | ||
} | ||
|
||
bool isRight = true; | ||
for (uint256 i = 0; i < proofArray.length; i++) { | ||
|
@@ -296,7 +345,6 @@ contract SNStateProofVerifier is | |
expectedHash = proof.edgeProof.childHash; | ||
int256 edgePathLength = int256(proof.edgeProof.length); | ||
pathBitIndex -= edgePathLength; | ||
console.log("pathBitIndex", uint256(pathBitIndex)); | ||
} | ||
} | ||
} | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this file as this is not required.