Skip to content

Commit

Permalink
Creating new RPCv2 example
Browse files Browse the repository at this point in the history
  • Loading branch information
rianhughes committed Jul 24, 2023
1 parent 90e0706 commit 6b83153
Show file tree
Hide file tree
Showing 8 changed files with 727 additions and 1 deletion.
3 changes: 2 additions & 1 deletion examples/deploy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
starknetgo "github.com/NethermindEth/starknet.go"
"github.com/NethermindEth/starknet.go/artifacts"
"github.com/NethermindEth/starknet.go/gateway"
"github.com/NethermindEth/starknet.go/rpcv02"
"github.com/NethermindEth/starknet.go/types"
)

Expand All @@ -35,7 +36,7 @@ func main() {
os.Exit(1)
}

contractClass := types.ContractClass{}
contractClass := rpcv02.ContractClass{}
err = json.Unmarshal(artifacts.AccountCompiled, &contractClass)
if err != nil {
fmt.Println("could not log file", err)
Expand Down
57 changes: 57 additions & 0 deletions examples/deployAccount/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# DeployAccount example

# todo (update)

This directory provides a full example on how to use the gateway API to :

- Deploy an OpenZeppelin account
- Deploy an ERC20 contract
- Mint the ERC20 contract
- Transfer tokens from the deployed account to a third-party account

## Run the program

In a terminal in this directory, enter : `go run main.go`

You can choose to run the program with an instance of the devnet (local Starknet instance) or with the testnet by setting the `env` variable to `dev` for devnet or `testnet` for testnet.

Note: The private key of the deployed account will be saved in hex format in the `private_key.txt` file. This allows you, in case of failure, to not rerun the program entirely.

## Contracts

All used contracts can be found in `./contracts`

- The account is in `./contracts/account/`
- The erc20 is in `./contracts/erc20/`

You will find for each contract : the Cairo version, the compiled version and the abi.

If you want to compile contracts yourself, input this command in a terminal :
`starknet-compile <my_contract.cairo> --output <my_contract_compiled.json> --abi <my_contract_abi.json>`

For the transfer operation, an account is already deployed on testnet at this address : `0x0024e9f35c5d6a14dcbb3f08be5fb7703e76611767266068c521fe8cba27983c`

Note:

If you run the program with a devnet instance, you have to deploy an account manually and set the `predeployedContract` value with the deployed account address.

## Providing ethereum to the deployed account

When running the program, you will be prompted to add ethereum to the account.

This step has to be done with the testnet [faucet](https://faucet.goerli.starknet.io/)

Copy to the clipboard the address of the contract printed in the terminal and past it in the faucet. The transaction can take several minutes.

Once the transaction is accepted, go to [voyager](https://goerli.voyager.online/) to search for your contract. You should see that it has a little amount of ethereum.

Those ETHs are used to pay transaction fees.

NOTE: this operation has to be done too for devnet. See the devnet documentation to see the process.

## Useful links

- [voyager](https://goerli.voyager.online/): to explore deployed contracts and transactions
- [starknet faucet](https://faucet.goerli.starknet.io/): to provide ETH to accounts
- [devnet](https://github.com/Shard-Labs/starknet-devnet) : local starknet instance
- [cairo-lang](https://github.com/starkware-libs/cairo-lang) : Cairo and CLI installing
115 changes: 115 additions & 0 deletions examples/deployAccount/contracts/account/OZAccount.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# SPDX-License-Identifier: MIT
# OpenZeppelin Contracts for Cairo v0.3.1 (account/presets/Account.cairo)

%lang starknet

from starkware.cairo.common.cairo_builtins import HashBuiltin, SignatureBuiltin, BitwiseBuiltin

from openzeppelin.account.library import Account, AccountCallArray

from openzeppelin.introspection.erc165.library import ERC165

#
# Constructor
#

@constructor
func constructor{
syscall_ptr : felt*,
pedersen_ptr : HashBuiltin*,
range_check_ptr
}(public_key: felt):
Account.initializer(public_key)
return ()
end

#
# Getters
#

@view
func get_public_key{
syscall_ptr : felt*,
pedersen_ptr : HashBuiltin*,
range_check_ptr
}() -> (res: felt):
let (res) = Account.get_public_key()
return (res=res)
end

@view
func get_nonce{
syscall_ptr : felt*,
pedersen_ptr : HashBuiltin*,
range_check_ptr
}() -> (res: felt):
let (res) = Account.get_nonce()
return (res=res)
end

@view
func supportsInterface{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
} (interfaceId: felt) -> (success: felt):
let (success) = ERC165.supports_interface(interfaceId)
return (success)
end

#
# Setters
#

@external
func set_public_key{
syscall_ptr : felt*,
pedersen_ptr : HashBuiltin*,
range_check_ptr
}(new_public_key: felt):
Account.set_public_key(new_public_key)
return ()
end

#
# Business logic
#

@view
func is_valid_signature{
syscall_ptr : felt*,
pedersen_ptr : HashBuiltin*,
range_check_ptr,
ecdsa_ptr: SignatureBuiltin*
}(
hash: felt,
signature_len: felt,
signature: felt*
) -> (is_valid: felt):
let (is_valid) = Account.is_valid_signature(hash, signature_len, signature)
return (is_valid=is_valid)
end

@external
func __execute__{
syscall_ptr : felt*,
pedersen_ptr : HashBuiltin*,
range_check_ptr,
ecdsa_ptr: SignatureBuiltin*,
bitwise_ptr: BitwiseBuiltin*
}(
call_array_len: felt,
call_array: AccountCallArray*,
calldata_len: felt,
calldata: felt*,
nonce: felt
) -> (response_len: felt, response: felt*):
let (response_len, response) = Account.execute(
call_array_len,
call_array,
calldata_len,
calldata,
nonce
)
return (response_len=response_len, response=response)
end
179 changes: 179 additions & 0 deletions examples/deployAccount/contracts/erc20/erc20.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# SPDX-License-Identifier: MIT

%lang starknet

from starkware.cairo.common.cairo_builtins import HashBuiltin
from starkware.cairo.common.uint256 import Uint256
from starkware.cairo.common.bool import TRUE

from openzeppelin.token.erc20.library import ERC20
from openzeppelin.access.ownable.library import Ownable

@constructor
func constructor{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}(owner: felt):
ERC20.initializer('MyToken', 'MTK', 18)
Ownable.initializer(owner)
return ()
end

#
# Getters
#

@view
func name{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}() -> (name: felt):
let (name) = ERC20.name()
return (name)
end

@view
func get_owner{
syscall_ptr : felt*,
pedersen_ptr : HashBuiltin*,
range_check_ptr,
}() -> (address : felt):
let (address) = Ownable.owner()
return (address)
end

@view
func symbol{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}() -> (symbol: felt):
let (symbol) = ERC20.symbol()
return (symbol)
end

@view
func totalSupply{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}() -> (totalSupply: Uint256):
let (totalSupply) = ERC20.total_supply()
return (totalSupply)
end

@view
func decimals{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}() -> (decimals: felt):
let (decimals) = ERC20.decimals()
return (decimals)
end

@view
func balanceOf{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}(account: felt) -> (balance: Uint256):
let (balance) = ERC20.balance_of(account)
return (balance)
end

@view
func allowance{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}(owner: felt, spender: felt) -> (remaining: Uint256):
let (remaining) = ERC20.allowance(owner, spender)
return (remaining)
end

#
# Externals
#

@external
func transfer{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}(recipient: felt, amount: Uint256) -> (success: felt):
ERC20.transfer(recipient, amount)
return (TRUE)
end

@external
func transferFrom{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}(sender: felt, recipient: felt, amount: Uint256) -> (success: felt):
ERC20.transfer_from(sender, recipient, amount)
return (TRUE)
end

@external
func approve{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}(spender: felt, amount: Uint256) -> (success: felt):
ERC20.approve(spender, amount)
return (TRUE)
end

@external
func increaseAllowance{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}(spender: felt, added_value: Uint256) -> (success: felt):
ERC20.increase_allowance(spender, added_value)
return (TRUE)
end

@external
func decreaseAllowance{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}(spender: felt, subtracted_value: Uint256) -> (success: felt):
ERC20.decrease_allowance(spender, subtracted_value)
return (TRUE)
end

@external
func transferOwnership{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}(newOwner: felt):
Ownable.transfer_ownership(newOwner)
return ()
end

@external
func renounceOwnership{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}():
Ownable.renounce_ownership()
return ()
end

@external
func mint{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr
}(to: felt, amount: Uint256):
ERC20._mint(to, amount)
return ()
end
Loading

0 comments on commit 6b83153

Please sign in to comment.