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

test: subscribe to a dapp with a token #4696

Merged
merged 11 commits into from
Feb 24, 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
1 change: 1 addition & 0 deletions boxes/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@aztec/accounts": "portal:../yarn-project/accounts",
"@aztec/aztec.js": "portal:../yarn-project/aztec.js",
"@aztec/circuits.js": "portal:../yarn-project/circuits.js",
"@aztec/entrypoints": "portal:../yarn-project/entrypoints",
"@aztec/foundation": "portal:../yarn-project/foundation",
"@aztec/bb.js": "portal:../barretenberg/ts",
"@aztec/circuit-types": "portal:../yarn-project/circuit-types",
Expand Down
55 changes: 34 additions & 21 deletions boxes/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,24 @@ __metadata:
languageName: node
linkType: hard

"@aztec/accounts@portal:../yarn-project/accounts::locator=create-aztec%40workspace%3A.":
"@aztec/accounts@portal:../yarn-project/accounts::locator=create-aztec-app%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/accounts@portal:../yarn-project/accounts::locator=create-aztec%40workspace%3A."
resolution: "@aztec/accounts@portal:../yarn-project/accounts::locator=create-aztec-app%40workspace%3A."
dependencies:
"@aztec/aztec.js": "workspace:^"
"@aztec/circuit-types": "workspace:^"
"@aztec/circuits.js": "workspace:^"
"@aztec/entrypoints": "workspace:^"
"@aztec/ethereum": "workspace:^"
"@aztec/foundation": "workspace:^"
"@aztec/types": "workspace:^"
tslib: "npm:^2.4.0"
languageName: node
linkType: soft

"@aztec/aztec.js@portal:../yarn-project/aztec.js::locator=create-aztec%40workspace%3A.":
"@aztec/aztec.js@portal:../yarn-project/aztec.js::locator=create-aztec-app%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/aztec.js@portal:../yarn-project/aztec.js::locator=create-aztec%40workspace%3A."
resolution: "@aztec/aztec.js@portal:../yarn-project/aztec.js::locator=create-aztec-app%40workspace%3A."
dependencies:
"@aztec/circuit-types": "workspace:^"
"@aztec/circuits.js": "workspace:^"
Expand All @@ -57,9 +58,9 @@ __metadata:
languageName: node
linkType: soft

"@aztec/bb.js@portal:../barretenberg/ts::locator=create-aztec%40workspace%3A.":
"@aztec/bb.js@portal:../barretenberg/ts::locator=create-aztec-app%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/bb.js@portal:../barretenberg/ts::locator=create-aztec%40workspace%3A."
resolution: "@aztec/bb.js@portal:../barretenberg/ts::locator=create-aztec-app%40workspace%3A."
dependencies:
comlink: "npm:^4.4.1"
commander: "npm:^10.0.1"
Expand Down Expand Up @@ -141,9 +142,9 @@ __metadata:
languageName: unknown
linkType: soft

"@aztec/circuit-types@portal:../yarn-project/circuit-types::locator=create-aztec%40workspace%3A.":
"@aztec/circuit-types@portal:../yarn-project/circuit-types::locator=create-aztec-app%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/circuit-types@portal:../yarn-project/circuit-types::locator=create-aztec%40workspace%3A."
resolution: "@aztec/circuit-types@portal:../yarn-project/circuit-types::locator=create-aztec-app%40workspace%3A."
dependencies:
"@aztec/circuits.js": "workspace:^"
"@aztec/ethereum": "workspace:^"
Expand All @@ -157,9 +158,9 @@ __metadata:
languageName: node
linkType: soft

"@aztec/circuits.js@portal:../yarn-project/circuits.js::locator=create-aztec%40workspace%3A.":
"@aztec/circuits.js@portal:../yarn-project/circuits.js::locator=create-aztec-app%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/circuits.js@portal:../yarn-project/circuits.js::locator=create-aztec%40workspace%3A."
resolution: "@aztec/circuits.js@portal:../yarn-project/circuits.js::locator=create-aztec-app%40workspace%3A."
dependencies:
"@aztec/bb.js": "portal:../../barretenberg/ts"
"@aztec/foundation": "workspace:^"
Expand All @@ -170,9 +171,21 @@ __metadata:
languageName: node
linkType: soft

"@aztec/ethereum@portal:../yarn-project/ethereum::locator=create-aztec%40workspace%3A.":
"@aztec/entrypoints@portal:../yarn-project/entrypoints::locator=create-aztec-app%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/ethereum@portal:../yarn-project/ethereum::locator=create-aztec%40workspace%3A."
resolution: "@aztec/entrypoints@portal:../yarn-project/entrypoints::locator=create-aztec-app%40workspace%3A."
dependencies:
"@aztec/aztec.js": "workspace:^"
"@aztec/circuit-types": "workspace:^"
"@aztec/circuits.js": "workspace:^"
"@aztec/foundation": "workspace:^"
tslib: "npm:^2.4.0"
languageName: node
linkType: soft

"@aztec/ethereum@portal:../yarn-project/ethereum::locator=create-aztec-app%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/ethereum@portal:../yarn-project/ethereum::locator=create-aztec-app%40workspace%3A."
dependencies:
"@aztec/foundation": "workspace:^"
dotenv: "npm:^16.0.3"
Expand All @@ -181,9 +194,9 @@ __metadata:
languageName: node
linkType: soft

"@aztec/foundation@portal:../yarn-project/foundation::locator=create-aztec%40workspace%3A.":
"@aztec/foundation@portal:../yarn-project/foundation::locator=create-aztec-app%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/foundation@portal:../yarn-project/foundation::locator=create-aztec%40workspace%3A."
resolution: "@aztec/foundation@portal:../yarn-project/foundation::locator=create-aztec-app%40workspace%3A."
dependencies:
"@aztec/bb.js": "portal:../../barretenberg/ts"
"@koa/cors": "npm:^4.0.0"
Expand All @@ -208,9 +221,9 @@ __metadata:
languageName: node
linkType: soft

"@aztec/protocol-contracts@portal:../yarn-project/protocol-contracts::locator=create-aztec%40workspace%3A.":
"@aztec/protocol-contracts@portal:../yarn-project/protocol-contracts::locator=create-aztec-app%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/protocol-contracts@portal:../yarn-project/protocol-contracts::locator=create-aztec%40workspace%3A."
resolution: "@aztec/protocol-contracts@portal:../yarn-project/protocol-contracts::locator=create-aztec-app%40workspace%3A."
dependencies:
"@aztec/circuits.js": "workspace:^"
"@aztec/foundation": "workspace:^"
Expand All @@ -220,9 +233,9 @@ __metadata:
languageName: node
linkType: soft

"@aztec/types@portal:../yarn-project/types::locator=create-aztec%40workspace%3A.":
"@aztec/types@portal:../yarn-project/types::locator=create-aztec-app%40workspace%3A.":
version: 0.0.0-use.local
resolution: "@aztec/types@portal:../yarn-project/types::locator=create-aztec%40workspace%3A."
resolution: "@aztec/types@portal:../yarn-project/types::locator=create-aztec-app%40workspace%3A."
dependencies:
"@aztec/ethereum": "workspace:^"
"@aztec/foundation": "workspace:^"
Expand Down Expand Up @@ -3538,9 +3551,9 @@ __metadata:
languageName: node
linkType: hard

"create-aztec@workspace:.":
"create-aztec-app@workspace:.":
version: 0.0.0-use.local
resolution: "create-aztec@workspace:."
resolution: "create-aztec-app@workspace:."
dependencies:
"@iarna/toml": "npm:^2.2.5"
"@inquirer/confirm": "npm:^3.0.0"
Expand All @@ -3552,7 +3565,7 @@ __metadata:
node-pty: "npm:^1.0.0"
tiged: "npm:^2.12.6"
bin:
create-aztec: npx.js
create-aztec-app: npx.js
languageName: unknown
linkType: soft

Expand Down
98 changes: 98 additions & 0 deletions l1-contracts/test/portals/GasPortal.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
pragma solidity >=0.8.18;

import {IERC20} from "@oz/token/ERC20/IERC20.sol";
import {SafeERC20} from "@oz/token/ERC20/utils/SafeERC20.sol";

// Messaging
import {IRegistry} from "../../src/core/interfaces/messagebridge/IRegistry.sol";
import {IInbox} from "../../src/core/interfaces/messagebridge/IInbox.sol";
import {DataStructures} from "../../src/core/libraries/DataStructures.sol";
// docs:start:content_hash_sol_import
import {Hash} from "../../src/core/libraries/Hash.sol";
// docs:end:content_hash_sol_import

// docs:start:init
contract GasPortal {
using SafeERC20 for IERC20;

IRegistry public registry;
IERC20 public underlying;
bytes32 public l2TokenAddress;

function initialize(address _registry, address _underlying, bytes32 _l2TokenAddress) external {
registry = IRegistry(_registry);
underlying = IERC20(_underlying);
l2TokenAddress = _l2TokenAddress;
}
// docs:end:init

// docs:start:deposit_public
/**
* @notice Deposit funds into the portal and adds an L2 message which can only be consumed publicly on Aztec
* @param _to - The aztec address of the recipient
* @param _amount - The amount to deposit
* @param _canceller - The address that can cancel the L1 to L2 message
* @param _deadline - The timestamp after which the entry can be cancelled
* @param _secretHash - The hash of the secret consumable message. The hash should be 254 bits (so it can fit in a Field element)
* @return - The key of the entry in the Inbox
*/
function depositToAztecPublic(
bytes32 _to,
uint256 _amount,
address _canceller,
uint32 _deadline,
bytes32 _secretHash
) external payable returns (bytes32) {
// Preamble
IInbox inbox = registry.getInbox();
DataStructures.L2Actor memory actor = DataStructures.L2Actor(l2TokenAddress, 1);

// Hash the message content to be reconstructed in the receiving contract
bytes32 contentHash = Hash.sha256ToField(
abi.encodeWithSignature("mint_public(bytes32,uint256,address)", _to, _amount, _canceller)
);

// Hold the tokens in the portal
underlying.safeTransferFrom(msg.sender, address(this), _amount);

// Send message to rollup
return inbox.sendL2Message{value: msg.value}(actor, _deadline, contentHash, _secretHash);
}

/**
* @notice Cancel a public depositToAztec L1 to L2 message
* @dev only callable by the `canceller` of the message
* @param _to - The aztec address of the recipient in the original message
* @param _amount - The amount to deposit per the original message
* @param _deadline - The timestamp after which the entry can be cancelled
* @param _secretHash - The hash of the secret consumable message in the original message
* @param _fee - The fee paid to the sequencer
* @return The key of the entry in the Inbox
*/
function cancelL1ToAztecMessagePublic(
bytes32 _to,
uint256 _amount,
uint32 _deadline,
bytes32 _secretHash,
uint64 _fee
) external returns (bytes32) {
IInbox inbox = registry.getInbox();
DataStructures.L1Actor memory l1Actor = DataStructures.L1Actor(address(this), block.chainid);
DataStructures.L2Actor memory l2Actor = DataStructures.L2Actor(l2TokenAddress, 1);
DataStructures.L1ToL2Msg memory message = DataStructures.L1ToL2Msg({
sender: l1Actor,
recipient: l2Actor,
content: Hash.sha256ToField(
abi.encodeWithSignature("mint_public(bytes32,uint256,address)", _to, _amount, msg.sender)
),
secretHash: _secretHash,
deadline: _deadline,
fee: _fee
});
bytes32 entryKey = inbox.cancelL2Message(message, address(this));
// release the funds to msg.sender (since the content hash (& message key) is derived by hashing the caller,
// we confirm that msg.sender is same as `_canceller` supplied when creating the message)
underlying.transfer(msg.sender, _amount);
return entryKey;
}
}
5 changes: 2 additions & 3 deletions noir-projects/aztec-nr/aztec/src/context/private_context.nr
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use dep::protocol_types::{
},
contrakt::{storage_read::StorageRead, storage_update_request::StorageUpdateRequest},
grumpkin_private_key::GrumpkinPrivateKey, hash::hash_args, header::Header,
messaging::l2_to_l1_message::L2ToL1Message, utils::reader::Reader
messaging::l2_to_l1_message::L2ToL1Message, utils::reader::Reader, traits::is_empty
};
use dep::std::option::Option;

Expand Down Expand Up @@ -71,8 +71,7 @@ impl PrivateContext {
pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext {
let side_effect_counter = inputs.call_context.start_side_effect_counter;
let mut min_revertible_side_effect_counter = 0;
// Note. The side effect counter is 2 when this is the initial call
if (side_effect_counter == 2) {
if is_empty(inputs.call_context.msg_sender) {
min_revertible_side_effect_counter = side_effect_counter;
}
PrivateContext {
Expand Down
4 changes: 2 additions & 2 deletions noir-projects/aztec-nr/aztec/src/state_vars/singleton.nr
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ impl<Note> Singleton<Note> {
// When this initialization nullifier is emitted, an observer could do a dictionary or rainbow attack to learn the preimage of this nullifier to deduce the storage slot and contract address.
// For some applications, leaking the details that a particular state variable of a particular contract has been initialized will be unacceptable.
// Under such circumstances, such application developers might wish to _not_ use this state variable type.
// This is especially dangerous for initial assignment to elements of a `Map<AztecAddress, Singleton>` type (for example), because the storage slot often also identifies an actor. e.g.
// This is especially dangerous for initial assignment to elements of a `Map<AztecAddress, Singleton>` type (for example), because the storage slot often also identifies an actor. e.g.
// the initial assignment to `my_map.at(msg.sender)` will leak: `msg.sender`, the fact that an element of `my_map` was assigned-to for the first time, and the contract_address.
// Note: subsequent nullification of this state variable, via the `replace` method will not be leaky, if the `compute_nullifier()` method of the underlying note is designed to ensure privacy.
// Note: subsequent nullification of this state variable, via the `replace` method will not be leaky, if the `compute_nullifier()` method of the underlying note is designed to ensure privacy.
// For example, if the `compute_nullifier()` method injects the secret key of a note owner into the computed nullifier's preimage.
pub fn compute_initialization_nullifier(self) -> Field {
pedersen_hash(
Expand Down
2 changes: 2 additions & 0 deletions noir-projects/noir-contracts/Nargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
[workspace]
members = [
"contracts/app_subscription_contract",
"contracts/avm_test_contract",
"contracts/fpc_contract",
"contracts/benchmarking_contract",
"contracts/card_game_contract",
"contracts/child_contract",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "app_subscription_contract"
authors = [""]
compiler_version = ">=0.18.0"
type = "contract"

[dependencies]
aztec = { path = "../../../aztec-nr/aztec" }
authwit = { path = "../../../aztec-nr/authwit" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use dep::aztec::context::PrivateContext;
use dep::aztec::protocol_types::{
constants::GENERATOR_INDEX__SIGNATURE_PAYLOAD, hash::pedersen_hash, traits::{Hash, Serialize},
address::AztecAddress
};

use dep::authwit::entrypoint::function_call::{FunctionCall, FUNCTION_CALL_SIZE_IN_BYTES};

// FUNCTION_CALL_SIZE * DAPP_MAX_CALLS + 1
global DAPP_PAYLOAD_SIZE: Field = 5;
// FUNCTION_CALL_SIZE_IN_BYTES * DAPP_MAX_CALLS + 32
global DAPP_PAYLOAD_SIZE_IN_BYTES: Field = 129;

global DAPP_MAX_CALLS: Field = 1;

// Note: If you change the following struct you have to update default_entrypoint.ts
// docs:start:app-payload-struct
struct DAppPayload {
function_calls: [FunctionCall; DAPP_MAX_CALLS],
nonce: Field,
}
// docs:end:app-payload-struct

impl Serialize<DAPP_PAYLOAD_SIZE> for DAppPayload {
// Serializes the entrypoint struct
fn serialize(self) -> [Field; DAPP_PAYLOAD_SIZE] {
let mut fields: BoundedVec<Field, DAPP_PAYLOAD_SIZE> = BoundedVec::new(0);
for call in self.function_calls {
fields.extend_from_array(call.serialize());
}
fields.push(self.nonce);
fields.storage
}
}

impl Hash for DAppPayload {
fn hash(self) -> Field {
pedersen_hash(
self.serialize(),
GENERATOR_INDEX__SIGNATURE_PAYLOAD
)
}
}

impl DAppPayload {
// Serializes the payload as an array of bytes. Useful for hashing with sha256.
fn to_be_bytes(self) -> [u8; DAPP_PAYLOAD_SIZE_IN_BYTES] {
let mut bytes: BoundedVec<u8, DAPP_PAYLOAD_SIZE_IN_BYTES> = BoundedVec::new(0);

for i in 0..DAPP_MAX_CALLS {
bytes.extend_from_array(self.function_calls[i].to_be_bytes());
}
bytes.extend_from_array(self.nonce.to_be_bytes(32));

bytes.storage
}

// Executes all private and public calls
// docs:start:entrypoint-execute-calls
fn execute_calls(self, context: &mut PrivateContext, target_address: AztecAddress) {
for call in self.function_calls {
// whitelist the calls that the user can do only go to the expected Dapp contract
assert(call.target_address == target_address);
if call.is_public {
context.call_public_function_with_packed_args(
call.target_address,
call.function_selector,
call.args_hash,
false,
false
);
} else {
let _result = context.call_private_function_with_packed_args(
call.target_address,
call.function_selector,
call.args_hash,
false,
false
);
}
}
}
// docs:end:entrypoint-execute-calls
}
Loading
Loading