Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move PrecomputeAddress function to 'contract' package #574

Merged
merged 6 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 10 additions & 23 deletions account/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

"github.com/NethermindEth/juno/core/crypto"
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/starknet.go/curve"
"github.com/NethermindEth/starknet.go/contracts"
"github.com/NethermindEth/starknet.go/hash"
"github.com/NethermindEth/starknet.go/rpc"
"github.com/NethermindEth/starknet.go/utils"
Expand All @@ -21,10 +21,9 @@ var (
)

var (
PREFIX_TRANSACTION = new(felt.Felt).SetBytes([]byte("invoke"))
PREFIX_DECLARE = new(felt.Felt).SetBytes([]byte("declare"))
PREFIX_CONTRACT_ADDRESS = new(felt.Felt).SetBytes([]byte("STARKNET_CONTRACT_ADDRESS"))
PREFIX_DEPLOY_ACCOUNT = new(felt.Felt).SetBytes([]byte("deploy_account"))
PREFIX_TRANSACTION = new(felt.Felt).SetBytes([]byte("invoke"))
PREFIX_DECLARE = new(felt.Felt).SetBytes([]byte("declare"))
PREFIX_DEPLOY_ACCOUNT = new(felt.Felt).SetBytes([]byte("deploy_account"))
)

//go:generate mockgen -destination=../mocks/mock_account.go -package=mocks -source=account.go AccountInterface
Expand All @@ -36,7 +35,7 @@ type AccountInterface interface {
SignInvokeTransaction(ctx context.Context, tx *rpc.InvokeTxnV1) error
SignDeployAccountTransaction(ctx context.Context, tx *rpc.DeployAccountTxn, precomputeAddress *felt.Felt) error
SignDeclareTransaction(ctx context.Context, tx *rpc.DeclareTxnV2) error
PrecomputeAddress(deployerAddress *felt.Felt, salt *felt.Felt, classHash *felt.Felt, constructorCalldata []*felt.Felt) (*felt.Felt, error)
PrecomputeAccountAddress(salt *felt.Felt, classHash *felt.Felt, constructorCalldata []*felt.Felt) (*felt.Felt, error)
WaitForTransactionReceipt(ctx context.Context, transactionHash *felt.Felt, pollInterval time.Duration) (*rpc.TransactionReceiptWithBlockInfo, error)
}

Expand Down Expand Up @@ -484,8 +483,8 @@ func (account *Account) TransactionHashDeclare(tx rpc.DeclareTxnType) (*felt.Fel
return nil, ErrTxnTypeUnSupported
}

// PrecomputeAddress calculates the precomputed address for an account.
// ref: https://github.com/starkware-libs/cairo-lang/blob/master/src/starkware/starknet/core/os/contract_address/contract_address.py
// PrecomputeAccountAddress calculates the precomputed address for an account.
// ref: https://docs.starknet.io/architecture-and-concepts/smart-contracts/contract-address/
//
// Parameters:
// - deployerAddress: the deployer address
Expand All @@ -495,25 +494,13 @@ func (account *Account) TransactionHashDeclare(tx rpc.DeclareTxnType) (*felt.Fel
// Returns:
// - *felt.Felt: the precomputed address as a *felt.Felt
// - error: an error if any
func (account *Account) PrecomputeAddress(deployerAddress *felt.Felt, salt *felt.Felt, classHash *felt.Felt, constructorCalldata []*felt.Felt) (*felt.Felt, error) {

bigIntArr := utils.FeltArrToBigIntArr([]*felt.Felt{
PREFIX_CONTRACT_ADDRESS,
deployerAddress,
salt,
classHash,
})

constructorCalldataBigIntArr := utils.FeltArrToBigIntArr(constructorCalldata)
constructorCallDataHashInt, _ := curve.Curve.ComputeHashOnElements(constructorCalldataBigIntArr)
bigIntArr = append(bigIntArr, constructorCallDataHashInt)

preBigInt, err := curve.Curve.ComputeHashOnElements(bigIntArr)
func (account *Account) PrecomputeAccountAddress(salt *felt.Felt, classHash *felt.Felt, constructorCalldata []*felt.Felt) (*felt.Felt, error) {
result, err := contracts.PrecomputeAddress(&felt.Zero, salt, classHash, constructorCalldata)
if err != nil {
return nil, err
}
return utils.BigIntToFelt(preBigInt), nil

return result, nil
}

// WaitForTransactionReceipt waits for the transaction receipt of the given transaction hash to succeed or fail.
Expand Down
2 changes: 1 addition & 1 deletion account/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ func TestAddDeployAccountDevnet(t *testing.T) {
ConstructorCalldata: []*felt.Felt{fakeUserPub},
}

precomputedAddress, err := acnt.PrecomputeAddress(&felt.Zero, fakeUserPub, classHash, tx.ConstructorCalldata)
precomputedAddress, err := acnt.PrecomputeAccountAddress(fakeUserPub, classHash, tx.ConstructorCalldata)
require.Nil(t, err)
require.NoError(t, acnt.SignDeployAccountTransaction(context.Background(), &tx, precomputedAddress))

Expand Down
35 changes: 35 additions & 0 deletions contracts/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import (
"os"

"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/starknet.go/curve"
"github.com/NethermindEth/starknet.go/utils"
)

var PREFIX_CONTRACT_ADDRESS = new(felt.Felt).SetBytes([]byte("STARKNET_CONTRACT_ADDRESS"))

type CasmClass struct {
Prime string `json:"prime"`
Version string `json:"compiler_version"`
Expand Down Expand Up @@ -46,3 +50,34 @@ func UnmarshalCasmClass(filePath string) (*CasmClass, error) {

return &casmClass, nil
}

// PrecomputeAddress calculates the precomputed address for a contract instance.
// ref: https://github.com/starkware-libs/cairo-lang/blob/master/src/starkware/starknet/core/os/contract_address/contract_address.py
//
// Parameters:
// - deployerAddress: the deployer address
// - salt: the salt
// - classHash: the class hash
// - constructorCalldata: the constructor calldata
// Returns:
// - *felt.Felt: the precomputed address as a *felt.Felt
// - error: an error if any
func PrecomputeAddress(deployerAddress *felt.Felt, salt *felt.Felt, classHash *felt.Felt, constructorCalldata []*felt.Felt) (*felt.Felt, error) {

bigIntArr := utils.FeltArrToBigIntArr([]*felt.Felt{
PREFIX_CONTRACT_ADDRESS,
deployerAddress,
salt,
classHash,
})

constructorCalldataBigIntArr := utils.FeltArrToBigIntArr(constructorCalldata)
constructorCallDataHashInt, _ := curve.Curve.ComputeHashOnElements(constructorCalldataBigIntArr)
bigIntArr = append(bigIntArr, constructorCallDataHashInt)

preBigInt, err := curve.Curve.ComputeHashOnElements(bigIntArr)
if err != nil {
return nil, err
}
return utils.BigIntToFelt(preBigInt), nil
}
70 changes: 68 additions & 2 deletions contracts/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import (
"os"
"testing"

"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/starknet.go/contracts"
"github.com/NethermindEth/starknet.go/rpc"
"github.com/NethermindEth/starknet.go/utils"
"github.com/test-go/testify/assert"
"github.com/test-go/testify/require"
)
Expand All @@ -19,7 +21,8 @@ import (
// Parameters:
// - t: The testing.T instance for running the test
// Returns:
// none
//
// none
func TestUnmarshalContractClass(t *testing.T) {
content, err := os.ReadFile("./tests/hello_starknet_compiled.sierra.json")
require.NoError(t, err)
Expand All @@ -40,7 +43,8 @@ func TestUnmarshalContractClass(t *testing.T) {
// Parameters:
// - t: The testing.T instance for running the test
// Returns:
// none
//
// none
func TestUnmarshalCasmClass(t *testing.T) {
casmClass, err := contracts.UnmarshalCasmClass("./tests/hello_starknet_compiled.casm.json")
require.NoError(t, err)
Expand All @@ -50,3 +54,65 @@ func TestUnmarshalCasmClass(t *testing.T) {
assert.Equal(t, casmClass.EntryPointByType.External[1].Offset, 130)
assert.Equal(t, casmClass.EntryPointByType.External[1].Builtins[0], "range_check")
}

// TestPrecomputeAddress tests the PrecomputeAddress function.
//
// It calls the PrecomputeAddress with predefined parameter values and compares the result with predefined expected results.
// The function uses the 'require' .NoError and .Equal functions from the github.com/stretchr/testify/assert package to perform the assertions.
// It is a test function and is meant to be used with the Go testing framework.
//
// Parameters:
// - t: The testing.T instance for running the test
// Returns:
//
// none
func TestPrecomputeAddress(t *testing.T) {
type testSetType struct {
DeployerAddress string
Salt string
ClassHash string
ConstructorCalldata []*felt.Felt
ExpectedPrecomputedAddress string
}

testSet := []testSetType{
{ //https://sepolia.voyager.online/tx/0x3789fe05652c9b18b98750b840e64cd3cc737592012c40d3233170d099db507
DeployerAddress: "0",
Salt: "0x0702e82f1ec15656ad4502268dad530197141f3b59f5529835af9318ef399da5",
ClassHash: "0x064728e0c0713811c751930f8d3292d683c23f107c89b0a101425d9e80adb1c0",
ConstructorCalldata: []*felt.Felt{
utils.TestHexToFelt(t, "0x022f3e55b61d86c2ac5239fa3b3b8761f26b9a5c0b5f61ddbd5d756ced498b46"),
},
ExpectedPrecomputedAddress: "0x31463b5263a6631be4d1fe92d64d13e3a8498c440bf789e69ccb951eb8ad5da",
},
{ //https://sepolia.voyager.online/tx/0x7a4458b402a172e730c947b293a499d310a7ae6cfb18b5d9774fc10625927e5
DeployerAddress: "0",
Salt: "0x023a851e8aeba201772098e1a1db3448f6238b20f928527242eb383905d91a87",
ClassHash: "0x061dac032f228abef9c6626f995015233097ae253a7f72d68552db02f2971b8f",
ConstructorCalldata: []*felt.Felt{
utils.TestHexToFelt(t, "0x023a851e8aeba201772098e1a1db3448f6238b20f928527242eb383905d91a87"),
},
ExpectedPrecomputedAddress: "0x28771beb7a2522a07d2ae6fc1fa5af942e8e863f70e6d7d74f9600ea3d5c242",
},
{ //https://sepolia.voyager.online/tx/0x2419a80d80045dd08cdb2606850c4eaf0ed8e705ee07bb1837d8daf12263bc0
DeployerAddress: "0",
Salt: "0x0702e82f1ec15656ad4502268dad530197141f3b59f5529835af9318ef399da5",
ClassHash: "0xf6f44afb3cacbcc01a371aff62c86ca9a45feba065424c99f7cd8637514d8f",
ConstructorCalldata: []*felt.Felt{
utils.TestHexToFelt(t, "0x022f3e55b61d86c2ac5239fa3b3b8761f26b9a5c0b5f61ddbd5d756ced498b46"),
},
ExpectedPrecomputedAddress: "0x50cb9257feb7e960c8ab7d1cf48f33cfbe21de138409be476f63203383ece63",
},
}

for _, test := range testSet {
precomputedAddress, err := contracts.PrecomputeAddress(
utils.TestHexToFelt(t, test.DeployerAddress),
utils.TestHexToFelt(t, test.Salt),
utils.TestHexToFelt(t, test.ClassHash),
test.ConstructorCalldata,
)
require.NoError(t, err)
require.Equal(t, test.ExpectedPrecomputedAddress, precomputedAddress.String())
}
}
2 changes: 1 addition & 1 deletion examples/deployAccount/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func main() {
},
}

precomputedAddress, err := accnt.PrecomputeAddress(&felt.Zero, pub, classHash, tx.ConstructorCalldata)
precomputedAddress, err := accnt.PrecomputeAccountAddress(pub, classHash, tx.ConstructorCalldata)
if err != nil {
panic(err)
}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249
github.com/pkg/errors v0.9.1
github.com/test-go/testify v1.1.4
go.uber.org/mock v0.4.0
golang.org/x/crypto v0.17.0
golang.org/x/net v0.18.0
)
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
Expand Down
19 changes: 10 additions & 9 deletions mocks/mock_account.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading